/* ============================================================
   TEA BUCKS - 04-tea-bucks
   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 every place this file deliberately out-specifies
   booking.css is marked OVERRIDE and explained.

   THE READ. A tea-leaf shop in Ebisu-nishi with a counter. Retail,
   not a cafe: 茶葉販売店 is what the listing says and the booking is
   a visit to a counter, not a table for dinner. Paper and ink, and
   a typographic page rather than a photographic one, because of
   what is actually on disk: g1 is a genuinely good dusk shopfront
   with the signage legible, g2 is a wall chart with no prices on
   it at all, g3 is a seamed three-panel collage and g4 shows two
   identifiable customers. Two usable frames do not carry a page,
   so type carries it and the two good photographs are shown large.

   THE SIGNATURE, used by no other site in the set: a centred PAPER
   SHEET with wide margins, and one section laid out on a CROSS,
   content in quadrants instead of rows. The cross is taken off the
   two-axis chart on the shop's wall in g2. It is a LAYOUT motif and
   nothing else: the cultivars, the growing regions and the taste
   words in that photograph are not in data/businesses.json, so they
   are never written into this page. The photograph is shown big and
   the guest reads the real thing in the frame.

   THE RULE THAT MATTERS ON THIS SITE. TEA BUCKS publishes no
   telephone number, so the failure path cannot offer a call. Three
   consequences live in this file and in the markup:
     1. SHOP.tel is "" and not null (site.js line 44 calls
        SHOP.tel.replace and a null throws before submit is bound).
     2. No [data-tel] element exists anywhere in the markup.
     3. site.js line 259 appends <a href="tel:"></a> to every
        failure message regardless, so .form-error hides it below.
   See the OVERRIDE block near the form.

   PALETTE, measured against WCAG 2.1 (ratios computed, not guessed):
     --text        #1F2420 on --bg #F4F1EA .... 13.98:1
                   on --bg-2 #FBF9F4 .......... 14.99:1
     --muted       #5A6058 on --bg ............  5.73:1  (6.14:1 on --bg-2)
     --accent      #3E6B4A on --bg ............  5.46:1
     --accent-dark #2F5A3C on --bg ............  7.03:1  (small text, links)
     --accent-ink  #FBF9F4 on --accent ........  5.86:1  (.book-ref chip)
     --warm        #8C4526 on --bg ............  6.22:1  (rules, small type)
     --error       #9B2C1A on --bg ............  6.72:1
     --success     #2F5A3C on --bg ............  7.03:1
   The literal terracotta of the counter wall in g1, #B5643C, is
   3.84:1 and is therefore a photographic colour only. It is not a
   token and it never carries a word.
   Lowest chroma of the eight on purpose: everything colourful on
   this page is inside a photograph.
   ============================================================ */

:root {
  /* Ground. Unbleached paper, and tea. */
  --bg: #F4F1EA;
  --bg-2: #FBF9F4;          /* the sheet */
  --bg-3: #ECE8DE;          /* input wells */

  --text: #1F2420;
  --muted: #5A6058;
  --line: #DCD7CB;

  --accent: #3E6B4A;        /* tea green: fills, the reference chip */
  --accent-dark: #2F5A3C;   /* the same green, darkened for small text */
  --accent-ink: #FBF9F4;

  --warm: #8C4526;          /* terracotta off the interior wall. Rules and
                               small type only, never a large field. */

  --error: #9B2C1A;
  --success: #2F5A3C;

  /* One radius system. Paper is cut, not rounded, so the steps are
     small on purpose. */
  --radius: 4px;
  --radius-sm: 3px;

  --font-latin: "Cormorant Garamond", "Hoefler Text", Georgia, serif;
  --font-jp-display: "Hina Mincho", "Hiragino Mincho ProN", "Yu Mincho", YuMincho, serif;
  --font-jp-body: "Noto Sans JP", "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo, sans-serif;

  --font-display: var(--font-jp-display);
  --font-body: var(--font-jp-body);

  --ease: cubic-bezier(0.22, 0.75, 0.3, 1);
  --nav-h: 58px;

  /* Per-site motion dials, matching the data-ds-* attributes on <html>.
     The least motion of the eight: this is the only site where the form
     is the sole route to the business. */
  --ds-lift: 2px;
  --ds-dur: 0.24s;
}

/* Latin display on the English page. Hina Mincho is a Japanese face and
   has no business setting an English heading. */
html[lang="en"] { --font-display: var(--font-latin); }

/* zh-Hant and ko REPLACE the families rather than appending to them. A
   Japanese mincho left at the head of a Chinese stack renders Chinese in
   Japanese glyph forms, which is the tell that nobody wrote the page. */
html[lang="zh-Hant"] {
  --font-display: "Noto Serif TC", "Songti TC", "PMingLiU", serif;
  --font-body: "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", sans-serif;
}
html[lang="ko"] {
  --font-display: "Nanum Myeongjo", Batang, serif;
  --font-body: "Noto Sans KR", "Apple SD Gothic Neo", Pretendard, "Malgun Gothic", sans-serif;
}

/* The address is Japanese on every page, because it is the string a guest
   shows a taxi driver. It keeps a Japanese face on the Chinese and Korean
   pages instead of being rendered with TC or KR glyph shapes. */
[lang="ja"] { font-family: var(--font-jp-body); }

*, *::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-size: 16px;
  font-weight: 400;
  line-height: 1.9;
  letter-spacing: 0.01em;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; }

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

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

/* ------------------------------------------------------------
   THE SHEET.
   One centred sheet of paper with wide margins, running the whole
   page. Sections are divided by a hairline rather than by a change
   of ground: the page is one theme throughout and nothing flips to
   an inverted mode mid-scroll.
   ------------------------------------------------------------ */
.sheet {
  max-width: 68rem;
  margin: 0 auto;
  background: var(--bg-2);
  border-inline: 1px solid var(--line);
}

/* The measure. Everything typographic is set inside it; only the
   photographs are allowed the full width of the sheet. 16px of side
   gutter survives at 390px because the padding is set once, here. */
.measure {
  max-width: 42rem;
  margin-inline: auto;
  padding-inline: clamp(1rem, 5vw, 3rem);
}

.band { padding-block: clamp(2.75rem, 7vw, 5.5rem); }
.band + .band { border-block-start: 1px solid var(--line); }

/* ------------------------------------------------------------
   Masthead
   ------------------------------------------------------------ */
.mast {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--bg-2) 92%, transparent);
  border-block-end: 1px solid var(--line);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
@supports not (background: color-mix(in srgb, red 50%, white)) {
  .mast { background: var(--bg-2); }
}
.mast-in {
  max-width: 68rem;
  margin-inline: auto;
  min-height: var(--nav-h);
  padding-inline: clamp(1rem, 5vw, 3rem);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.mast-name {
  font-family: var(--font-latin);
  font-weight: 600;
  font-size: 1.15rem;
  letter-spacing: 0.22em;
  line-height: 1;
  color: var(--text);
  text-decoration: none;
  padding-block: 0.9rem;
}
.mast-name:hover { color: var(--warm); }

/* Language switcher. Four links, not a dropdown: with four options a
   dropdown costs a tap and gains nothing. */
.langsw { display: flex; flex-wrap: wrap; gap: 0.1rem; align-items: center; }
.langsw a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 0.55rem;
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1;
  color: var(--muted);
  text-decoration: none;
  border-block-end: 2px solid transparent;
}
.langsw a:hover { color: var(--text); }
.langsw a[aria-current="true"] {
  color: var(--warm);
  border-block-end-color: var(--warm);
}

/* At 390px the name and four language links cannot share a row, so the bar
   wraps to two. The switcher keeps its 44px tap targets; the name gives up
   the padding instead, so the sticky header costs 84px rather than 104px of
   a phone screen. --nav-h is raised to match, because ds.css offsets every
   in-page anchor by it and a focused field must not land under the bar. */
@media (max-width: 560px) {
  :root { --nav-h: 84px; }
  .mast-name { padding-block: 0.45rem; font-size: 1.05rem; letter-spacing: 0.18em; }
  .mast-in { row-gap: 0; }
}

/* ------------------------------------------------------------
   Family 1 - the shopfront.
   Type first, plate second. The name is set on paper the way a
   title page is, and the photograph follows at the full width of
   the sheet. Putting the copy first is also what keeps the booking
   link above the fold at 390px, where a 4:3 photograph on top would
   push it a screen and a half down.
   ------------------------------------------------------------ */
.shopfront { padding-block-start: clamp(2.5rem, 7vw, 5rem); }

.kicker {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: var(--warm);
  margin-block-end: 1.25rem;
}
html[lang="en"] .kicker { text-transform: uppercase; }

/* The wordmark. Cormorant Garamond echoes the spurred, high-contrast
   capitals cut into the concrete lintel in g1. */
.wordmark {
  display: block;
  font-family: var(--font-latin);
  font-weight: 500;
  font-size: clamp(2.9rem, 1.9rem + 4.6vw, 5.4rem);
  line-height: 1.04;
  letter-spacing: 0.1em;
  text-indent: 0.1em;       /* balances the tracking on the last letter */
  margin-block-end: 1.5rem;
}

.lede {
  font-size: 1.06rem;
  line-height: 1.95;
  color: var(--text);
  max-width: 34rem;
  margin-inline: auto;
}

.cta-row { margin-block-start: 2rem; }

.shopfront .measure { text-align: center; }

.shopfront-photo { margin-block-start: clamp(2.5rem, 6vw, 4rem); }
.shopfront-photo img {
  display: block;
  width: 100%;
  height: auto;
}

/* Captions sit under the plate in small warm type, the way a printed
   plate is captioned. */
.cap {
  font-size: 0.82rem;
  line-height: 1.75;
  color: var(--warm);
  padding-block-start: 0.7rem;
  border-block-start: 1px solid var(--line);
  margin-block-start: 0.9rem;
  max-width: 42rem;
  margin-inline: auto;
}
/* The shopfront plate runs the full width of the sheet, so its caption
   carries the side gutter itself. The plate inside a .measure does not. */
.shopfront-photo .cap { padding-inline: clamp(1rem, 5vw, 3rem); }

/* ------------------------------------------------------------
   Family 2 - the paper measure.
   No photograph at all: a ruled typographic column. This is the
   section that says plainly what the shop is and what this page
   does and does not know.
   ------------------------------------------------------------ */
h2 {
  font-family: var(--font-display);
  font-weight: 400;
  /* Hina Mincho is too fine below roughly 28px, so the floor of this
     clamp is 1.75rem = 28px and the face is never used smaller. */
  font-size: clamp(1.75rem, 1.4rem + 1.7vw, 2.5rem);
  line-height: 1.5;
  letter-spacing: 0.04em;
  margin-block-end: 1.5rem;
}
html[lang="zh-Hant"] h2 { font-weight: 500; }
html[lang="ko"] h2 { font-weight: 700; }
html[lang="en"] h2 { font-weight: 600; letter-spacing: 0.01em; }

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

/* A single ruled fact, set the way a colophon line is. */
.colophon {
  margin-block-start: 2.5rem;
  padding-block-start: 1.1rem;
  border-block-start: 1px solid var(--warm);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.4rem;
  align-items: baseline;
  font-size: 0.9rem;
}
.colophon dt {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--warm);
}
html[lang="en"] .colophon dt { text-transform: uppercase; }
.colophon dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

/* ------------------------------------------------------------
   Family 3 - the cross-axis section. THE SIGNATURE.
   Four quadrants around a cross, rather than four rows in a list.
   The device comes off the two-axis chart on the shop's wall; the
   axes here carry no labels and no words from that chart, because
   none of its content is in data/businesses.json.
   ------------------------------------------------------------ */
.cross { position: relative; }
.taste-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin-block-start: 2.25rem;
}
.taste-grid > * { padding: clamp(1.15rem, 3vw, 2.1rem); min-width: 0; }

/* The cross itself: one vertical rule and one horizontal rule meeting
   at the centre. Drawn as borders on the quadrants so it can never
   drift out of alignment with them. */
.taste-grid > :nth-child(1),
.taste-grid > :nth-child(2) { border-block-end: 1px solid var(--warm); }
.taste-grid > :nth-child(1),
.taste-grid > :nth-child(3) { border-inline-end: 1px solid var(--warm); }

.taste-grid > :nth-child(1) { padding-inline-start: 0; padding-block-start: 0; }
.taste-grid > :nth-child(2) { padding-inline-end: 0; padding-block-start: 0; }
.taste-grid > :nth-child(3) { padding-inline-start: 0; padding-block-end: 0; }
.taste-grid > :nth-child(4) { padding-inline-end: 0; padding-block-end: 0; }

.q-label {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  line-height: 1.6;
  color: var(--warm);
  margin-block-end: 0.7rem;
}
html[lang="en"] .q-label { text-transform: uppercase; }

.q-value {
  font-size: 1.32rem;
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.q-note {
  margin-block-start: 0.55rem;
  font-size: 0.9rem;
  line-height: 1.8;
  color: var(--muted);
}

/* The address is load-bearing type on this site, because it is the only
   physical way to reach the shop. Body size or larger, never muted grey,
   and tabular figures so the block reads as an address and not as a
   sentence. */
.addr {
  font-size: 1.12rem;
  line-height: 1.75;
  font-weight: 400;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
/* CJK breaks between any two ideographs, which at narrow widths split the
   building number across two lines as "…２丁目１ / ２−１４". The address is
   the only physical route to this shop, so the segments that must stay
   whole are held together and the break is allowed only between them. */
.addr .nb { white-space: nowrap; }

.maps-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  margin-block-start: 0.4rem;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--accent-dark);
  text-decoration: underline;
}
.maps-link:hover { color: var(--warm); }
.maps-link svg { width: 1.05em; height: 1.05em; flex: none; }

.q-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--accent-dark);
  text-decoration: underline;
}
.q-link:hover { color: var(--warm); }

@media (max-width: 660px) {
  /* One column. The vertical arm of the cross has nothing to divide at
     this width, so it goes; the horizontal rules stay and keep the four
     quadrants legible as four separate things. */
  .taste-grid { grid-template-columns: 1fr; }
  .taste-grid > * {
    padding-inline: 0;
    padding-block: 1.4rem;
    border-inline-end: 0 !important;
    border-block-end: 1px solid var(--warm);
  }
  .taste-grid > :nth-child(1) { padding-block-start: 0; }
  .taste-grid > :nth-child(4) { padding-block-end: 0; border-block-end: 0; }
}

/* ------------------------------------------------------------
   Family 4 - the standalone plate.
   g2 at the largest size the measure allows. It is the only menu
   board photograph in the whole project that carries no prices at
   all, which is exactly why it can be shown big: there is nothing
   on it that could be read as a price list. Nothing written on it
   is repeated in text anywhere on this page.
   ------------------------------------------------------------ */
.plate { margin-block-start: 2rem; }
.plate img {
  display: block;
  width: 100%;
  max-width: 38rem;
  height: auto;
  margin-inline: auto;
  border: 1px solid var(--line);
  background: var(--bg-3);
}
.plate .cap { max-width: 38rem; }

/* ------------------------------------------------------------
   Buttons
   ------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0.75rem 1.6rem;
  font-family: var(--font-body);
  font-size: 0.98rem;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.04em;
  border-radius: var(--radius);
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
}
.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.btn-primary:hover {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
  color: var(--accent-ink);
}
.btn-primary:disabled { opacity: 0.7; cursor: default; }
.btn-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--text);
}
.btn-ghost:hover { background: var(--bg-3); color: var(--text); }

/* ------------------------------------------------------------
   The booking block
   ------------------------------------------------------------ */
.form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.1rem 1.2rem;
  margin-block-start: 2rem;
}
.field { display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.field.full { grid-column: 1 / -1; }
.field label {
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--text);
}
.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);
  font-variant-numeric: tabular-nums;
}
.field select {
  /* The UA arrow is kept: a hand-rolled one is a decorative SVG and the
     brief rules those out. */
  appearance: auto;
}
.field .hint {
  font-size: 0.85rem;
  line-height: 1.75;
  color: var(--muted);
}
.form textarea { background: var(--bg-3); border-radius: var(--radius-sm); }
.form-error, .form-ok {
  grid-column: 1 / -1;
  display: none;
  margin: 0;
  padding: 0.85rem 1rem;
  font-size: 0.95rem;
  line-height: 1.8;
  border-radius: var(--radius-sm);
}
.form-error.show, .form-ok.show { display: block; }
.form-error {
  color: var(--error);
  background: #F7EBE7;
  border: 1px solid var(--error);
  font-weight: 700;
}
.form-ok {
  color: var(--success);
  background: #E9F0EA;
  border: 1px solid var(--success);
  font-weight: 700;
}

/* ---- OVERRIDE 1 of 3, and the one that matters most ----------------
   booking.css ships .field .field-msg { color:#f0a08c } and
   .field.bad input { border-color:#f0a08c }. On this ground #f0a08c
   measures 1.84:1, which is invisible. On the ONE site in the set where
   the form is the only way to reach the shop, an invisible field-level
   error means a guest who cannot see which box is wrong has no second
   route at all. booking.css loads after this file, so the restatement
   has to out-specify it rather than merely repeat it; #reserve-form
   does that without touching the shared file. */
#reserve-form .field .field-msg {
  color: var(--error);
  font-weight: 700;
  font-size: 0.85rem;
  line-height: 1.7;
}
#reserve-form .field.bad input,
#reserve-form .field.bad select,
#reserve-form .field.bad textarea {
  border-color: var(--error);
  border-width: 2px;
}

/* ---- OVERRIDE 2 of 3 ----------------------------------------------
   site.js line 259 appends <a href="tel:">…</a> to every failure
   message whether or not the shop has a telephone. SHOP.tel is "" here
   (it cannot be null: line 44 calls SHOP.tel.replace before the submit
   handler is ever bound), so that anchor arrives empty and would sit at
   the end of the error as a dangling link to nowhere. site.js is shared
   and is not ours to edit, so it is hidden here instead. */
.form-error a[href="tel:"],
.form-error a:empty { display: none; }
.form-error a { color: var(--error); text-decoration: underline; }

/* ---- OVERRIDE 3 of 3 ----------------------------------------------
   booking.css sets .book-result h3 in the inherited family. Hina Mincho
   ships one weight and would render the confirmation heading at 400 in
   a face that is too fine at this size, so the confirmation panel is
   held in the body face, where 700 exists. */
.book-result h3 { font-family: var(--font-body); font-size: 1.15rem; }

/* The permanent contact block. It sits under the form, is visible before
   anything has failed, and is the honest answer to a failure path that
   cannot offer a telephone call. It never says an email was sent,
   because none is. */
.no-tel {
  margin-block-start: 1.75rem;
  padding: 1.35rem 1.4rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--warm);
  border-radius: var(--radius-sm);
}
.no-tel h3 {
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--warm);
  margin-block-end: 0.85rem;
}
html[lang="en"] .no-tel h3 { text-transform: uppercase; }
.no-tel p { font-size: 0.95rem; line-height: 1.85; color: var(--text); }
.no-tel p + p { margin-block-start: 0.8rem; }
.no-tel .addr { margin-block-end: 0.2rem; }

.ref-note {
  margin-block-start: 1.25rem;
  font-size: 0.88rem;
  line-height: 1.85;
  color: var(--muted);
}

@media (max-width: 660px) {
  .form { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------------------
   Footer
   ------------------------------------------------------------ */
footer {
  border-block-start: 1px solid var(--line);
  background: var(--bg);
  padding-block: clamp(2.25rem, 5vw, 3.5rem);
}
.foot-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 2.5rem;
  justify-content: space-between;
  align-items: flex-start;
}
.foot-brand {
  font-family: var(--font-latin);
  font-weight: 600;
  font-size: 1.1rem;
  letter-spacing: 0.2em;
  margin-block-end: 0.5rem;
}
.foot-links { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; }
.foot-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--accent-dark);
  text-decoration: none;
}
.foot-links a:hover { color: var(--warm); text-decoration: underline; }
.demo-note {
  margin-block-start: 1.1rem;
  font-size: 0.8rem;
  line-height: 1.85;
  color: var(--muted);
  max-width: 46rem;
}

/* Skip link. Visible the moment it is focused, never before. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--accent-ink);
  padding: 0.75rem 1.1rem;
  font-weight: 700;
  z-index: 50;
}
.skip:focus { left: 0; }

/* ------------------------------------------------------------
   Reveal.
   .rv is not defined by any shared stylesheet that this page loads,
   so it is defined here. motion.js takes ownership when it runs
   (ds.css switches the transition off under html.ds-motion); media.js
   adds .in after four seconds regardless, which is the failsafe for a
   background tab. Under reduced motion nothing moves at all.
   ------------------------------------------------------------ */
.rv { opacity: 0; transform: translateY(10px); }
@media (prefers-reduced-motion: no-preference) {
  .rv { transition: opacity 0.45s var(--ease), transform 0.45s var(--ease); }
}
.rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; transition: none; }
}

/* The shopfront photograph is deliberately outside every motion system.
   It carries no .rv class, and it is not inside .hero, .hero-band,
   .hero-media or .m-hero-media, which are the selectors media.css and
   motion.js use to drift and parallax a hero image. Nothing on this page
   is scroll-linked. */

/* ------------------------------------------------------------
   Print. A tea shop with no telephone is a shop somebody writes the
   address down for.
   ------------------------------------------------------------ */
@media print {
  .mast, .langsw, .cta-row, .form, .btn { display: none; }
  .sheet { border: 0; }
  body { background: #fff; }
}
