/* 狀態玩家 public pages, v4 (2026-10-21): 首屏, 三站, 導師, 預約表單, one 「照片來源」 link. Colours and fonts come from
   tokens.css (unchanged). Hard rules, checked in WebKit and Chromium at 320/390/1440 (scripts/layout-v4.mjs):
   html.scrollWidth <= innerWidth, visualViewport.scale === 1, form fields >= 16px, no phrase-level nowrap. */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
/* v4.2 (Bevis): no double-tap zoom; the viewport also sets maximum-scale=1, user-scalable=no. */
html, body { touch-action: manipulation; }
/* No overflow-x: hidden here: it hid overflow from the checks while iOS Safari still zoomed the page out. */
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  color: var(--ink);
  background: var(--seg-1);
}
img, svg, picture { display: block; max-width: 100%; }
/* CJK text breaks at punctuation and spaces only (never inside a word); anywhere is the safety net at 320. */
p, li, h1, h2, h3, h4, label, legend, summary { word-break: keep-all; line-break: strict; overflow-wrap: anywhere; }
h1, h2, h3, .brand {
  font-family: var(--font-heading);
  font-weight: 500;
  font-feature-settings: "palt";
  margin: 0;
}
h1 { font-size: var(--fs-display); line-height: var(--lh-display); letter-spacing: var(--ls-display); }
h2 { font-size: var(--fs-h2); line-height: var(--lh-h2); letter-spacing: var(--ls-display); }
h3 { font-size: var(--fs-h3); line-height: 1.5; letter-spacing: var(--ls-h3); }
p { margin: 0 0 var(--space-4); }
.num { font-family: var(--font-num); font-weight: 500; font-variant-numeric: lining-nums tabular-nums; letter-spacing: var(--ls-time); }
a { color: var(--clay-dk); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip { position: absolute; left: var(--space-4); top: -100px; background: var(--paper); color: var(--ink); padding: var(--space-3) var(--space-4); border-radius: var(--r-1); z-index: 10; }
.skip:focus { top: var(--space-4); }

/* ---- Buttons: one primary colour on the page (挑一天, 下一步／送出 share it) ---- */
.button {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: 48px; padding: 0 var(--space-6);
  border-radius: var(--r-1); border: 1px solid transparent;
  font: 500 var(--fs-body)/1 var(--font-sans); letter-spacing: var(--ls-button);
  text-decoration: none; cursor: pointer;
}
.button.primary { background: var(--clay); color: var(--button-ink); }
.button.primary:not([disabled]):not([aria-disabled="true"]):hover { background: var(--clay-dk); }
.button.primary.is-sending, .button.primary.is-sending:hover { background: var(--clay); color: var(--button-ink); cursor: progress; }
.button.secondary { background: transparent; color: var(--night-ink); border-color: var(--night-ink); }
.button.lamp { background: var(--lamp); color: var(--seg-5); }
.button .icon { width: 20px; height: 20px; }
.link-button {
  background: none; border: 0; padding: 0 var(--space-2); min-height: 44px; min-width: 44px;
  font: inherit; color: var(--ink); text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 1px; cursor: pointer;
}
.link-button[disabled] { color: var(--disabled-ink); text-decoration-color: transparent; cursor: default; }

/* ---- Blocks: 64px above and below on phones, 120px from 960px; text column at most 612px ---- */
:root { --gutter: 20px; }
.block { padding: 64px var(--gutter); }
.column, .stop-list, .booking > .invite, .success { max-width: var(--content); margin-inline: auto; }
.night { background: var(--seg-4); color: var(--night-ink); }
.deep { background: var(--seg-5); color: var(--night-ink); }
.night a, .deep a { color: var(--lamp); }
.night :focus-visible, .deep :focus-visible { outline-color: var(--lamp); }

/* ---- 首屏: phone = photo 70svh with the text over its lower edge; desktop = text left, photo right (58vw) ---- */
.hero { position: relative; background: var(--seg-1); }
.hero-photo { height: 70svh; min-height: 420px; width: 100%; margin: 0; background: var(--placeholder-1); }
/* 01 (設計總監): phones crop at center 70%; the text overlaps the photo by 96px only, so the cup sits whole above the fade. */
.hero-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center 70%; }
.hero-text { position: relative; z-index: 1; margin-top: -96px; padding: 0 var(--gutter); display: flex; flex-direction: column; gap: var(--space-3); }
/* A paper fade under the text, so the photo never decides the contrast (ink on paper ≥ 12:1). */
.hero-text::before { content: ""; position: absolute; inset: -40px 0 0; z-index: -1;
  background: linear-gradient(180deg, rgba(247, 241, 232, 0) 0, rgba(247, 241, 232, .9) 40px, var(--seg-1) 72px); pointer-events: none; }
.hero .brand { font-size: 1.125rem; letter-spacing: .3em; color: var(--ink); }
.hero h1 { font-size: clamp(1.75rem, 8vw, 2rem); }
.hero .lead { font-size: 1rem; line-height: 1.8; margin: 0; max-width: 34em; }
.hero .button { width: 100%; margin-top: var(--space-2); }

/* ---- 三站 (v4.2): one 4:5 photo per stop. Phones: the photo runs edge to edge above the text, 48px between stops.
   ≥960px: photo column (40vw, max 480px) and text side by side, alternating sides (Azumi Setoda), text centred. ---- */
@media (max-width: 959px) { .block.stops { padding-top: 40px; } }
.stop-list { list-style: none; margin-block: 0; padding: 0; display: grid; gap: var(--space-7); }
.stop-list li { margin: 0; }
.stop-photo { display: block; aspect-ratio: 4 / 5; max-width: none; margin: 0 calc(-1 * var(--gutter)); background: var(--placeholder-1); overflow: hidden; }
.stop-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.stop-list .caption { padding-top: var(--space-4); }
.stop-list h2 { font-size: 1.25rem; line-height: 1.5; letter-spacing: .08em; margin: 0 0 var(--space-1); }
.stop-list p { margin: 0; }

/* ---- 導師: one paragraph, 16px / 1.8; 64px above (02→03, a hard cut) ---- */
.block.guide { padding-top: 64px; }
.guide h2 { font-size: 1.25rem; margin: 0 0 var(--space-3); }
.guide p { font-size: 1rem; line-height: 1.8; margin: 0; color: var(--night-ink); }

/* ---- Booking card and success ---- */
.booking { padding-inline: var(--gutter); }
.invite { background: var(--paper); color: var(--ink); border-radius: var(--r-0); position: relative; }
.invite p, .invite li, .invite legend, .invite label { color: var(--ink); }
.invite a { color: var(--clay-dk); }
.invite :focus-visible { outline-color: var(--focus); }
.invite-photo { aspect-ratio: 3 / 1; width: 100%; margin: 0; }
.invite-photo img { width: 100%; height: 100%; object-fit: cover; }
.invite-body { padding: var(--space-5) var(--space-5) 0; }
.invite-body > h2 { font-size: 1.5rem; margin: 0; }
@media (max-width: 359px) { .booking { padding-inline: 12px; } .invite-body { padding-inline: var(--space-4); } }
.success-card .invite-body { padding-bottom: var(--space-6); }
.success-card:focus { outline: none; }
.success-card h3 { font-size: 1.5rem; margin: 0 0 var(--space-3); }
.success-ref { font-size: var(--fs-body); margin: 0 0 var(--space-3); }
.success-ref .num { font-family: var(--font-num); font-weight: 500; font-size: inherit; letter-spacing: .06em; }
.success-mail { margin: 0; }
.success-email { display: block; overflow-wrap: anywhere; word-break: normal; }
/* 10: two equal buttons, 12px apart, 48px high; the paper card meets the dark ground with a hard cut and 64px of air. */
.success-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 64px 0 0; }
.success-actions .button { min-height: 48px; height: 48px; padding-inline: var(--space-3); letter-spacing: 0; }

/* ---- Footer: the 導師 colour, a 1px rule on top, one 13px line; only the author's name is underlined ---- */
.site-footer { padding: var(--space-5) var(--gutter) calc(32px + env(safe-area-inset-bottom)); font-size: .8125rem; line-height: 1.7;
  border-top: 1px solid rgba(255, 255, 255, .12); }
.credits { max-width: var(--content); margin: 0 auto; color: var(--night-muted) !important; }
.credits a { color: var(--night-muted); }

/* ---- /privacy (v4.2): 個人資料 and 圖片出處 on the cream ground, the home page's type ---- */
.privacy-main { max-width: var(--content); margin: 0 auto; padding: var(--space-6) var(--gutter) calc(48px + env(safe-area-inset-bottom)); }
.privacy-main section + section { margin-top: var(--space-6); }
.privacy-main h2 { margin: 0 0 var(--space-3); }
.privacy-back { margin: var(--space-6) 0 0; }

/* ---- Form ---- */
form { margin: 0; }
fieldset { border: 0; padding: 0; margin: 0; min-width: 0; }
.step { padding-bottom: var(--space-5); }
.step-title { margin: var(--space-5) 0 var(--space-4); }
.step-title:focus { outline: none; }
.field { margin: 0 0 var(--space-6); }
/* L2 (設計總監 P2-6): step 2 on a phone was 1.53 screens (v3 §8: ≤ 1.5); the gap between questions 32 → 24. */
@media (max-width: 599px) { .step .field { margin-bottom: var(--space-5); } }
label, legend, .label, .sublabel { display: block; font-size: var(--fs-small); font-weight: 500; line-height: 1.6; margin: 0 0 var(--space-2); padding: 0; }
.sublabel { margin-top: var(--space-4); }
.req, .opt { font-weight: 400; font-size: var(--fs-tag); color: var(--muted); margin-left: var(--space-1); }
.help { font-size: var(--fs-small); line-height: var(--lh-small); color: var(--muted) !important; margin: 0 0 var(--space-2); }
input[type="text"], input[type="email"], input[type="tel"], select, textarea {
  width: 100%; min-height: 48px; padding: var(--space-3);
  font: 1.0625rem/1.5 var(--font-sans); /* 17px: iOS Safari zooms into any field under 16px (v4 hard rule) */ font-variant-numeric: tabular-nums; color: var(--ink);
  background: var(--white); border: 1px solid var(--field); border-radius: var(--r-1);
}
textarea { min-height: 48px; resize: vertical; }
/* 08: selects look like the text fields (white, 1px --field border) in every engine; the arrow is two CSS gradients. */
select { -webkit-appearance: none; appearance: none; padding-right: 40px;
  background: linear-gradient(45deg, transparent 50%, var(--ink) 50%) no-repeat calc(100% - 20px) 50% / 6px 6px,
    linear-gradient(135deg, var(--ink) 50%, transparent 50%) no-repeat calc(100% - 14px) 50% / 6px 6px, var(--white); }
select::-ms-expand { display: none; }
/* L2 (設計總監 P2-6): two lines to start, then the box grows with the text; never an inner scrollbar.
   Browsers without field-sizing get the same from app.js (scrollHeight, set through el.style: the CSP allows no style=""). */
#topic { field-sizing: content; min-height: calc(2lh + 26px); max-height: none; overflow: hidden; resize: none; }
[aria-invalid="true"] { border: 2px solid var(--error) !important; }
.error { display: flex; gap: var(--space-2); align-items: flex-start; color: var(--error) !important; font-size: var(--fs-small); line-height: var(--lh-small); margin: 0 0 var(--space-2); }
.error::before { content: "!"; flex: none; width: 18px; height: 18px; margin-top: 2px; border: 1.5px solid currentColor; border-radius: 50%; font: 500 12px/15px var(--font-sans); text-align: center; }
.error[hidden] { display: none; }
.count { font-size: var(--fs-tag); color: var(--muted) !important; margin: var(--space-1) 0 0; text-align: right; }
/* 06/07 (設計總監): every choice is its own button, 8px apart, 6px corners. Selected: --selected fill and a 1.5px lamp
   border (inset shadow, so nothing moves); the ✓ sits in the left padding and the text stays centred. */
.choices { display: flex; flex-wrap: wrap; gap: 8px; }
.choice { position: relative; margin: 0; flex: 1 1 0; min-width: 0; }
.choice input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.choice span {
  position: relative; display: flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 20px; border: 1px solid var(--field); border-radius: 6px;
  background: var(--white); font-size: var(--fs-small); font-weight: 400; color: var(--ink); text-align: center;
}
.choice input:checked + span { background: var(--selected); color: var(--ink); font-weight: 500; border-color: var(--lamp); box-shadow: inset 0 0 0 .5px var(--lamp); }
.choice input:checked + span::before { content: "✓"; content: "✓" / ""; position: absolute; left: 8px; top: 50%; transform: translateY(-50%); line-height: 1; }
.choice input:focus-visible + span { outline: 2px solid var(--focus-ring); outline-offset: 2px; z-index: 1; }
/* 07: a question with an error gets a 3px error-colour line on the left and the note above; the buttons keep their own border. */
.choices[aria-invalid="true"] { border: 0 !important; }
.field.group:has(> .choices[aria-invalid="true"]) { border-left: 3px solid var(--error); padding-left: 12px; }
/* Narrow phones: three choices to a row still fit 「不太會」 on one line. */
@media (max-width: 359px) { .choice span { padding-inline: 10px; font-size: .9375rem; } .choice input:checked + span::before { left: 4px; } }
/* 這趟的預算: 2 × 2 at every width, so 「NT$10,000 以上」 never sits alone on a row (文案 N3). */
/* L1: minmax(0, 1fr) so the columns never grow past half the row (1fr's min is the content, which pushed
   「NT$10,000 以上」 17–19px out of the card at 320); below 360 the buttons are tighter so the words still fit. */
[data-name="budgetTier"] { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
/* v4: no nowrap; amounts are short words that keep-all keeps together (「NT$10,000 以上」 may break at its space). */
.choice span { word-break: keep-all; }
/* Bevis (iPhone, 2026-10-21): the same padding on both sides, so the text sits in the middle whether or not the ✓ shows
   (the ✓ is absolute in the left padding). Narrow phones take a little off both sides so 「NT$10,000 以上」 stays on one line. */
[data-name="budgetTier"] .choice span { padding-inline: 14px; letter-spacing: 0; white-space: nowrap; }
@media (max-width: 359px) { [data-name="budgetTier"] .choice span { padding-inline: 10px; font-size: .875rem; letter-spacing: 0; }
  [data-name="budgetTier"] .choice input:checked + span::before { left: 4px; } }
/* Conditional reveal (GOV.UK radios): the follow-up questions sit right under the choices, joined to them
   by a left rule, only while 「帶一位朋友」／「NT$10,000 以上」／「一起聊聊」 is selected. */
.conditional { margin: var(--space-4) 0 0; padding: 0 0 0 var(--space-4); border-left: 4px solid var(--field); }
.conditional[hidden] { display: none; }
/* 有 → the free-text box sits under its own choices, not glued to them. */
.choices + .field { margin-top: var(--space-4); }
.conditional > .field:last-child, .conditional > fieldset:last-child { margin-bottom: 0; }
.friend-birth { margin-top: var(--space-6); }
.sub-title { font-size: var(--fs-body); font-weight: 500; margin: 0 0 var(--space-2); }
.amount { display: flex; align-items: center; gap: var(--space-2); max-width: 16em; }
.amount input { flex: 1 1 auto; }
.amount .unit { flex: none; font-size: var(--fs-small); color: var(--muted); }
.date-row { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: var(--space-2); }
/* Phones (設計總監 post-launch P1-3): at 390 the year select cut 「1990（民國 79）」 to 「1990（民|」. The year takes the
   whole row; month and day share the next one. */
@media (max-width: 599px) {
  .date-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .date-row > .mini:first-child { grid-column: 1 / -1; }
}
/* Narrow phones (設計總監 T4, 2026-10-21): at 320 the 出生時辰 selects had no room for 「早子時 00:00–00:59」.
   Below 360 the booking card loses 8px of side padding each side (24 → 16) and the friend block's indent goes 16 → 12.
   The font stays at 17px; the success card keeps its padding. */
@media (max-width: 359px) {
  .booking > .invite > .invite-body { padding-left: calc(var(--space-5) - 8px); padding-right: calc(var(--space-5) - 8px); }
  .friend-birth { padding-left: var(--space-3); }
}
/* 閏月 box (B3): set off like the other conditional reveals, the note right under the box. */
.leap { border-left: 1px solid var(--line); padding-left: 16px; margin-top: 8px; }
.leap .help { margin-top: 8px; }
.mini span { display: block; font-size: var(--fs-tag); color: var(--muted); margin-bottom: 6px; }
.check-label { display: flex; gap: var(--space-3); align-items: flex-start; font-size: var(--fs-body); font-weight: 400; min-height: 44px; }
.check-label input { flex: none; width: 22px; height: 22px; margin: 4px 0 0; accent-color: var(--clay); }
.form-error { border: 2px solid var(--error); background: var(--error-bg); color: var(--error) !important; padding: var(--space-3) var(--space-4); border-radius: var(--r-1); }
.banner { background: var(--error-bg); padding: var(--space-3); }

/* Step dots: 6px, joined by a 1px line; current = clay with a ring, done = ink, to come = field outline. */
.progress-row { display: flex; align-items: center; gap: var(--space-4); margin-top: var(--space-4); }
.stepper { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: 14px; position: relative; }
.stepper::before { content: ""; position: absolute; left: 4px; right: 4px; top: 50%; border-top: 1px solid var(--field); }
.stepper li { position: relative; }
.pip { display: block; width: 6px; height: 6px; border-radius: 50%; border: 1px solid var(--field); background: var(--paper); }
.stepper li.done .pip { background: var(--ink); border-color: var(--ink); }
.stepper li[aria-current="step"] .pip { background: var(--clay); border-color: var(--clay); box-shadow: 0 0 0 3px var(--paper), 0 0 0 4px var(--clay); }
.progress { font-size: var(--fs-small); color: var(--muted) !important; margin: 0; }

/* The step buttons: in the flow, never sticky (v4: a sticky bar covered the content under it, which read as an empty box). */
.nav { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4) 0 var(--space-6); border-top: 1px solid var(--line); }
.nav .button { margin-left: auto; }
/* After 4 s of waiting: one muted line under the button, not the error colour. */
.submit-slow { flex: 0 0 100%; margin: 0; font-size: var(--fs-small); line-height: 1.6; color: var(--muted) !important; text-align: end; }
/* Step 4: the one privacy line, 13px, right under the 送出 button. */
.privacy-line { flex: 0 0 100%; margin: calc(-1 * var(--space-2)) 0 0; font-size: .8125rem; line-height: 1.6; color: var(--muted) !important; text-align: end; }

/* ---- Calendar ---- */
.calendar { margin: var(--space-2) 0; }
.cal-head { display: grid; grid-template-columns: 44px 1fr 44px; align-items: center; }
.cal-title { grid-column: 2; text-align: center; margin: 0; font-weight: 500; }
.cal-nav { width: 44px; height: 44px; display: grid; place-items: center; background: none; border: 1px solid transparent; border-radius: var(--r-1); color: var(--ink); cursor: pointer; }
.cal-nav.prev { grid-column: 1; grid-row: 1; }
.cal-nav.next { grid-column: 3; grid-row: 1; }
.cal-nav svg { width: 22px; height: 22px; }
.cal-nav[hidden] { display: none; }
.cal-grid { width: 100%; border-collapse: separate; border-spacing: 2px; table-layout: fixed; }
.cal-grid th { font-size: var(--fs-tag); font-weight: 400; color: var(--muted); padding: var(--space-1) 0; }
/* v4: every day cell is the same column: a 40px number box (flex-centred, line-height 1) and a 12px mark row.
   The selected day only paints the box, so its number sits exactly where its neighbours' do (WebKit used to drop it). */
.cal-grid td { height: 56px; min-width: 40px; text-align: center; vertical-align: middle; border-radius: var(--r-1); position: relative; padding: 2px 0; }
.cal-day .num { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; margin: 0 auto; font-size: 1.125rem; line-height: 1; letter-spacing: 0; border-radius: 50%; }
.cal-mark { display: flex; align-items: center; justify-content: center; height: 12px; font-size: .6875rem; line-height: 1; color: var(--muted); }
.cal-day.open { cursor: pointer; }
.cal-day.open .cal-mark::before { content: ""; display: inline-block; width: 5px; height: 5px; border-radius: 50%; background: var(--clay); vertical-align: middle; }
.cal-day.booked .num { text-decoration: line-through; color: var(--muted); }
.cal-day.past .num, .cal-day.later .num { color: var(--disabled-ink); }
/* 不開放: the date stays readable, lighter than an open day; no reason is given. */
.cal-day.closed .num { color: var(--disabled-ink); }
.cal-day.today .num { box-shadow: inset 0 0 0 1px var(--muted); }
.cal-day.selected .num { background: var(--clay); color: var(--button-ink); transition: background-color var(--dur-pick) var(--ease); }
.cal-day.selected .cal-mark { visibility: hidden; }
.cal-day:focus-visible { outline: 2px solid var(--focus); outline-offset: 0; }
.cal-skel { background: var(--paper-2); height: 56px; }
/* v4: each legend item has a small swatch, never a sample digit (the old 「8」 read as a stray number). */
.cal-legend { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); padding: 0; margin: var(--space-2) 0; font-size: var(--fs-tag); color: var(--muted); }
.cal-legend li { display: inline-flex; align-items: center; gap: 6px; }
.cal-legend .swatch { display: inline-block; flex: none; }
.cal-legend .open .swatch { width: 6px; height: 6px; border-radius: 50%; background: var(--clay); }
.cal-legend .booked .swatch { width: 12px; height: 0; border-top: 1px solid var(--muted); }
.date-status { font-size: var(--fs-small); color: var(--muted) !important; }
.date-status:empty { display: none; }
/* B9: why a day could not be picked; muted, not the error colour. Empty, it takes no room. */
.cal-note { font-size: var(--fs-small); color: var(--muted) !important; margin: 8px 0 0; }
.cal-note:empty { display: none; }


/* ---- 404 ---- */
.notfound { min-height: 100svh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 72px var(--gutter); }
.notfound h1 { font-size: var(--fs-h2); margin-bottom: var(--space-4); }
.notfound p { color: var(--night-ink); }

/* ---- Motion: blocks fade in once; reduced motion turns every fade off ---- */
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.js-reveal .reveal > * { opacity: 0; transform: translateY(var(--rise)); }
.js-reveal .reveal.in > * { opacity: 1; transform: none; transition: opacity var(--dur-reveal) var(--ease), transform var(--dur-reveal) var(--ease); }
.success.rising { animation: fade var(--dur-reveal) var(--ease) both; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js-reveal .reveal > * { opacity: 1; transform: none; }
}

/* ---- Desktop ≥ 960 ---- */
@media (min-width: 960px) {
  .block { padding: 120px var(--gutter); }
  .hero { display: grid; grid-template-columns: minmax(0, 1fr) 58vw; min-height: min(100svh, 900px); }
  .hero-photo { grid-column: 2; grid-row: 1; height: 100%; min-height: 0; }
  .hero-text { grid-column: 1; grid-row: 1; align-self: center; margin: 0; z-index: auto; padding: 120px 56px 120px max(var(--gutter), calc((100vw - var(--max)) / 2)); }
  .hero-text::before { content: none; }
  .hero h1 { font-size: clamp(2rem, 3vw, 2.75rem); }
  .hero .lead { font-size: 1.125rem; }
  .hero .button { width: auto; align-self: flex-start; }
  /* 11: 48px high, 32px either side. */
  .button { min-height: 48px; padding-inline: 32px; }
  .stop-list { max-width: 1008px; gap: var(--space-9); }
  .stop-list li { display: grid; grid-template-columns: min(40vw, 480px) minmax(0, 1fr); column-gap: var(--space-moment); align-items: center; }
  .stop-list li:nth-child(even) { grid-template-columns: minmax(0, 1fr) min(40vw, 480px); }
  .stop-list li:nth-child(even) .stop-photo { order: 2; }
  .stop-photo { margin: 0; }
  .stop-list .caption { padding: 0; max-width: 28em; }
  .stop-list li:nth-child(even) .caption { justify-self: end; }
  .guide p { font-size: 1.125rem; }
  .invite-body { padding: var(--space-7) var(--space-7) 0; }
}

@media print {
  .skip { display: none !important; }
  .night, .night *, .deep, .deep * { color: var(--ink) !important; background: none !important; }
}
