/* ==========================================================================
   Maison — Beach (the "Beach" Canva design). Loaded after invitation.css.

   One long scroll that follows the Canva pages top to bottom: the painted window (a tap plays the
   video of its shutters opening onto the sea), the wavy frame with the names,
   the countdown, the venue sketch, where to stay, the postcard on getting there, the timeline, the dress
   code and the RSVP card, all on grainy paper. Sizes are in design units: --u is how many CSS pixels
   one design pixel is worth.
     · wide screens:   the 1366-unit canvas fits the width (and roughly the height)
     · narrow screens: the middle ~540 units fill the screen, so the edges crop away
   The window and the frame have their own, larger units on phones (--gu, --wu) so they fill the screen.
   Text never shrinks below a readable minimum; sections grow when they need room.
   ========================================================================== */

.inv--beach {
  --bh-paper: #F8F4ED;
  --bh-ink: #00357A;
  --bh-ink-soft: rgba(0, 53, 122, 0.79);
  --bh-card: rgba(255, 255, 255, 0.5);
  --inv-bg: var(--bh-paper);
  --inv-ink: var(--bh-ink);
  --inv-muted: var(--bh-ink-soft);
  --inv-accent: var(--bh-ink);
  --inv-soft: #EEE7DC;
  --inv-line: rgba(0, 53, 122, 0.3);
  /* The Canva design uses two faces: handwritten capitals (titles, labels, the form) and a thin
     monoline script (names, date, countdown numbers, the lines in between). Gaegu and WindSong are the
     closest free matches; Arabic gets Marhey (light) and Noto Nastaliq Urdu, as fine and flowing as the script. */
  --bh-caps: 'Gaegu', 'Marhey', cursive;
  --bh-caps-weight: 400;
  --bh-script: 'WindSong', 'Noto Nastaliq Urdu', cursive;
  /* WindSong sets about 1.7 times wider than the Canva script: at 0.6 of the Canva sizes it takes the
     same room on the page. */
  --bh-script-scale: 0.6;
  --bh-track: 0.08em;
  --bh-track-sm: 0.2em;
  --inv-font-ui: var(--bh-caps);
  --sec-h: 100vh;
  --u: max(min(100vw / 1366, 100vh / 768), min(100vw / 540, 100vh / 1170));
  --s: var(--u);
  /* The window's unit (see 1 · the window), here so the bird keeps its size from the window to the frame. */
  --bh-gu: max(min(100vw / 1366, 100vh / 768), min(100vw / 330, 100vh / 720));
  --bh-bird: calc(50 * var(--bh-gu));
  /* The paper: the design's grain, tiled. */
  background: var(--bh-paper) url('beach-paper.jpg') 0 0 / 600px auto repeat;
  color: var(--bh-ink);
  font-family: var(--bh-caps);
  font-size: 1rem;
  line-height: 1.4;
  overflow-x: clip;
}
@supports (height: 100svh) {
  .inv--beach {
    --sec-h: 100svh;
    --u: max(min(100vw / 1366, 100svh / 768), min(100vw / 540, 100svh / 1170));
    --bh-gu: max(min(100vw / 1366, 100svh / 768), min(100vw / 330, 100svh / 720));
  }
}
@media (min-width: 700px) {
  .inv.inv--beach { background: var(--bh-paper) url('beach-paper.jpg') 0 0 / 600px auto repeat; }
}
body.inv-body--beach { background: #F8F4ED; }
.inv--beach[lang='ar'] {
  --bh-caps: 'Marhey', 'Gaegu', sans-serif;
  --bh-caps-weight: 300;
  --bh-script: 'Noto Nastaliq Urdu', 'Amiri', serif;
  --bh-script-scale: 0.62;
  --bh-track: 0;
  --bh-track-sm: 0;
  line-height: 1.7;
}
.inv--beach :focus-visible { outline: 2px solid var(--bh-ink); outline-offset: 3px; }
:where(.inv--beach) :is(p, h1, h2, ol, ul, fieldset, legend) { margin: 0; padding: 0; }
:where(.inv--beach) fieldset { border: 0; min-width: 0; }
.inv--beach img { -webkit-user-drag: none; user-select: none; }
.inv--beach .inv-controls { inset-inline-end: max(14px, env(safe-area-inset-right)); }

.bh-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------------ type */
.bh-caps {
  font-family: var(--bh-caps);
  font-weight: var(--bh-caps-weight);
  letter-spacing: var(--bh-track-sm);
  text-transform: uppercase;
  color: var(--bh-ink-soft);
}
.bh-script {
  font-family: var(--bh-script);
  font-weight: 400;
  line-height: 1.06;
  color: var(--bh-ink);
}
.inv--beach[lang='ar'] .bh-caps { text-transform: none; }
.inv--beach[lang='ar'] .bh-script { font-weight: 400; line-height: 2; }
.bh-title {
  font-size: max(calc(33.3 * var(--u)), 24px);
  letter-spacing: var(--bh-track);
  line-height: 1.2;
  color: var(--bh-ink);
  opacity: 0.86;
}
.inv--beach[lang='ar'] .bh-title { font-weight: 300; }

/* ------------------------------------------------------------------ layout helpers */
.bh-page { position: relative; }
.bh-slide { position: relative; z-index: 1; overflow: hidden; }
.bh-canvas { position: relative; width: 100%; }
.bh-flow {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: max(calc(76.8 * var(--u)), 56px) 16px max(calc(70 * var(--u)), 48px);
  text-align: center;
}
/* Art placed by its design coordinates: --x (left), --y (top), --w (width), on a 1366-unit canvas centred
   in its section (--cx is the design x that sits at the section's middle). */
.bh-abs {
  position: absolute;
  left: calc(50% + (var(--x) - var(--cx, 683)) * var(--s));
  top: calc(var(--y) * var(--s));
  width: calc(var(--w) * var(--s));
  max-width: none;
  height: auto;
  pointer-events: none;
}

/* ------------------------------------------------------------------ 1 · the window
   Pages one and two of the Canva design: the window, centred on the first screen, with the line written under
   it. The window is the owners' Kling video of the shutters opening (beach-window.mp4/.webm, cropped round the
   window and colour matched to the page's paper), with its first frame as the closed window and its last frame as
   the open one; the video's edges fade into the paper so no box shows. --gu is the window's unit (larger on
   phones); the line under it has --lu, which keeps it inside the screen. */
.bh-window {
  --gu: var(--bh-gu);
  --lu: min(var(--gu), (100vw - 32px) / 441);
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: var(--sec-h);
  padding-block: calc(24 * var(--gu));
  overflow: hidden;
}
.bh-window__scene { display: flex; flex-direction: column; align-items: center; direction: ltr; }
.bh-window__frame { position: relative; width: calc(334.39 * var(--gu)); max-width: 100%; }
.bh-window__art {
  position: relative;
  width: 100%;
  aspect-ratio: 940 / 1080;
  -webkit-mask: linear-gradient(90deg, transparent 1%, #000 10.5%, #000 89.5%, transparent 99%), linear-gradient(transparent 0.5%, #000 6.3%, #000 94.4%, transparent 99.5%);
  -webkit-mask-composite: source-in;
  mask: linear-gradient(90deg, transparent 1%, #000 10.5%, #000 89.5%, transparent 99%), linear-gradient(transparent 0.5%, #000 6.3%, #000 94.4%, transparent 99.5%);
  mask-composite: intersect;
}
.bh-window__art > * { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Closed (the opening on, not yet tapped): the first frame over the open window, then the video over both once it
   actually plays. Without script, with ?open=1 or the opening off, only the open window shows. */
.bh-window__closed,
.bh-window__video { opacity: 0; }
.bh-live .bh-window__closed { opacity: 1; }
.bh-live .bh-window__video.is-playing { opacity: 1; }
/* Once the video is showing its own frames the closed window under it goes (instantly: the video covers it), and
   at the end the video simply stays on its last frame, the open window. Fading both out together at the end let
   the closed window show through for a moment. */
.bh-live .bh-window__closed.is-covered { opacity: 0; }
/* The video could not play (data saver, reduced motion, an error): the closed window cross fades to the open one. */
.bh-live .bh-window__closed.is-fading { opacity: 0; transition: opacity 0.9s ease; }
/* The line from the Canva design (its own handwriting, at the 80% opacity Canva gives it), centred under the window. */
.bh-window__line { display: block; width: calc(413.5 * var(--lu)); height: auto; margin-block-start: calc(4 * var(--gu)); }
p.bh-window__line {
  text-align: center;
  text-wrap: balance;
  font-size: calc(34 * var(--lu));
  line-height: 1.5;
  color: var(--bh-ink-soft);
}
.inv--beach[lang='ar'] p.bh-window__line { font-weight: 400; }
.bh-window__open {
  position: absolute;
  inset: 0;
  z-index: 2;
  cursor: pointer;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}
/* There is no hint to tap: the whole window is the button. Keyboard focus rings the window itself. */
.bh-window:has(.bh-window__open:focus-visible) .bh-window__frame { outline: 2px solid var(--bh-ink); outline-offset: 6px; border-radius: 4px; }
html:not(.js) .bh-window__open,
.inv-skip-envelope .bh-window__open,
.inv-embed .bh-window__open,
.bh-window__open[hidden] { display: none; }

/* ------------------------------------------------------------------ the bird
   The owners' sprite sheet (beach-bird.webp: 20 frames of 196 × 220 in a row; perched 1 to 3, take off 4 and 5,
   flying 6 to 14, landing 15, 18, 16, 17, settling 19 and 20), sized to the window (--bh-bird, a fifth of the
   window's width, about a real songbird on a real window). A perch is a point where the feet go: on top of the
   arch, a touch left of the middle, and on the top right of the save the date's frame. invitation-beach.js picks
   the frame (--n) and where that frame's feet are in it (--fx, --fy, in sprite pixels), so the bird stays planted
   whatever the pose; it flips (.is-mirrored) to face the way it flies. While flying it leaves the page for a fixed
   layer above everything (.is-flying) and the script places it. Art never mirrors in Arabic (physical sides). */
.bh-perch { position: absolute; width: 0; height: 0; pointer-events: none; }
/* The arch: its top sits 6.8% down the closed frame and 8.9% down the open one (the video settles it lower in its
   last moments; the bird hops down with it, .bh-arch-down). */
.bh-perch--window { z-index: 3; left: 47%; top: 8.89%; }
.bh-live:not(.bh-arch-down) .bh-perch--window { top: 6.76%; }
.bh-arch-down .bh-perch--window { transition: top 0.18s ease-out; }
.bh-perch--frame { z-index: 1; --bh-bird-size: calc(var(--bh-bird) * 1.15); }
.bh-bird {
  --w: var(--bh-bird-size, var(--bh-bird));
  --fx: 68.6;
  --fy: 206;
  --n: 0;
  position: absolute;
  left: calc(var(--fx) / -196 * var(--w));
  top: calc(var(--fy) / -196 * var(--w));
  width: var(--w);
  aspect-ratio: 196 / 220;
  background: url('beach-bird.webp') calc(var(--n) * var(--w) * -1) 0 / calc(var(--w) * 20) auto no-repeat;
  pointer-events: none;
}
.bh-bird.is-mirrored { transform: scaleX(-1); }
.bh-bird.is-flying {
  position: fixed;
  z-index: 26;
  left: 0;
  top: 0;
  will-change: transform;
}

/* ------------------------------------------------------------------ the crab
   Resting (no script, reduced motion, or before it first sets off) it sits on the countdown page where the
   Canva design puts it, by the end of the line. invitation-beach.js walks a copy of it across the countdown
   page (and only that page: .bh-slide clips it), behind the text, right to left, sideways as crabs go: in quick bursts with pauses between, now and then a little
   shuffle back. The walking copy is the same drawing in three layers (the body, and the legs on either side)
   so the legs step while it moves (.is-stepping): the two sides swing out of step (the script bobs the body). Physical
   sides on purpose: the drawing never mirrors. */
.bh-countdown__perch {
  position: absolute;
  z-index: -1;
  inset-inline-start: calc(100% + 20 * var(--u));
  top: 30%;
  width: calc(116 * var(--u));
  pointer-events: none;
}
/* Phones: there is no room beside the line, so it sits just below its end. */
@media (max-width: 599px) {
  .bh-countdown__perch { inset-inline-start: auto; inset-inline-end: -10px; top: 92%; width: 64px; }
}
.bh-countdown__perch img { width: 100%; height: auto; }
.bh-countdown__perch.is-gone { visibility: hidden; }
.bh-crab {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  width: max(calc(116 * var(--u)), 62px);
  aspect-ratio: 348 / 275;
  pointer-events: none;
  visibility: hidden;
  will-change: transform;
}
.bh-crab.is-walking { visibility: visible; }
.bh-crab__body,
.bh-crab__legs { position: absolute; inset: 0; width: 100%; height: auto; }
/* The legs on the lower left and on the right (cut from the drawing with soft edges, beach-crab-legs-*.webp; the
   body is the rest, beach-crab-body.webp). Each set pivots where it meets the shell. */
.bh-crab__legs--l { transform-origin: 31.6% 63.6%; }
.bh-crab__legs--r { transform-origin: 69% 44%; }
.bh-crab__legs--l { animation: bh-step-l 0.2s linear infinite; }
.bh-crab__legs--r { animation: bh-step-r 0.2s linear infinite; }
.bh-crab__legs { animation-play-state: paused; }
.bh-crab.is-stepping .bh-crab__legs { animation-play-state: running; }
@keyframes bh-step-l {
  0%, 100% { transform: rotate(-7deg) translateY(0); }
  25% { transform: rotate(0deg) translateY(-1.5%); }
  50% { transform: rotate(7deg) translateY(0); }
  75% { transform: rotate(0deg) translateY(1%); }
}
@keyframes bh-step-r {
  0%, 100% { transform: rotate(7deg) translateY(0); }
  25% { transform: rotate(0deg) translateY(1%); }
  50% { transform: rotate(-7deg) translateY(0); }
  75% { transform: rotate(0deg) translateY(-1.5%); }
}

/* ------------------------------------------------------------------ 2 · save the date
   The frame at its Canva size (page three, y shifted up by 100 so the canvas starts just above it), with
   the four lines centred inside it. */
.bh-names {
  overflow: visible;
  /* One full screen, so when the page has glided here from the window nothing of the countdown below shows until
     the guest scrolls on. flow-root keeps the frame's top margin inside the section (the frame stays put). */
  display: flow-root;
  min-height: var(--sec-h);
  --wu: max(min(100vw / 1366, 100vh / 768), min((100vw - 16px) / 470, 100vh / 700));
  --u: var(--wu);
  --s: var(--wu);
}
@supports (height: 100svh) {
  .bh-names { --wu: max(min(100vw / 1366, 100svh / 768), min((100vw - 16px) / 470, 100svh / 700)); }
}
.bh-canvas--names {
  height: calc(628 * var(--s));
  /* Centred on its screen, and always with room above the frame for the bird that lands on it. */
  margin-block: max(calc(var(--bh-bird) * 1.25), calc((var(--sec-h) - 628 * var(--s)) / 2 - 40px)) 0;
}
.bh-names__frame { z-index: -1; }
.bh-names__text {
  position: absolute;
  left: 50%;
  top: calc(52 * var(--s));
  translate: -50% 0;
  width: calc(400 * var(--s));
  height: calc(520 * var(--s));
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-block-end: calc(10 * var(--s));
  text-align: center;
}
.bh-names__save {
  font-size: max(calc(17.5 * var(--s)), 13px);
  letter-spacing: 0.1em;
  rotate: 1.5deg;
  color: var(--bh-ink);
  opacity: 0.86;
}
.bh-names__couple {
  margin-block-start: calc(18 * var(--s));
  font-size: calc(var(--fs) * var(--s) * var(--bh-script-scale) * 1.1);
  word-spacing: 0.12em;
  line-height: 1.3;
  text-wrap: balance;
}
.bh-names__date {
  margin-block-start: calc(6 * var(--s));
  font-size: calc(60 * var(--s) * var(--bh-script-scale) * 1.4);
  letter-spacing: 0.12em;
  direction: ltr;
}
.inv--beach[lang='ar'] .bh-names__couple { font-size: calc(var(--fs) * var(--s) * 0.82); line-height: 1.5; }
.inv--beach[lang='ar'] .bh-names__date { font-size: calc(60 * var(--s) * 0.62); font-weight: 400; letter-spacing: 0.04em; }
.bh-names__venue,
.bh-names__note {
  font-size: max(calc(11.5 * var(--s)), 11px);
  line-height: 1.25;
}
.bh-names__venue { margin-block-start: calc(14 * var(--s)); }
.bh-names__note { margin-block-start: calc(10 * var(--s)); max-width: calc(300 * var(--s)); }
.inv--beach[lang='ar'] :is(.bh-names__venue, .bh-names__note) { font-size: max(calc(14 * var(--s)), 12px); line-height: 1.5; }
.inv--beach[lang='ar'] .bh-names__save { font-size: max(calc(19 * var(--s)), 14px); letter-spacing: 0; }

/* ------------------------------------------------------------------ 3 · countdown */
.bh-countdown .bh-flow { padding-block-start: max(calc(96 * var(--u)), 64px); padding-block-end: max(calc(96 * var(--u)), 76px); }
.bh-cd {
  display: grid;
  grid-template-columns: repeat(4, max(calc(99.7 * var(--u)), 72px));
  justify-content: center;
  margin-block-start: max(calc(44 * var(--u)), 26px);
}
.bh-cd__cell { display: flex; flex-direction: column; align-items: center; gap: max(calc(6 * var(--u)), 4px); }
.bh-cd__num {
  font-size: max(calc(72 * var(--u) * var(--bh-script-scale)), 32px);
  letter-spacing: 0.1em;
  line-height: 1.1;
}
.inv--beach[lang='ar'] .bh-cd__num { font-size: max(calc(72 * var(--u) * 0.5), 28px); font-weight: 400; letter-spacing: 0; line-height: 1.6; }
.bh-cd__unit {
  font-size: max(calc(17.84 * var(--u)), 13px);
  letter-spacing: 0.04em;
  line-height: 1.2;
}
.inv--beach[lang='ar'] .bh-cd__unit { font-size: max(calc(17.84 * var(--u)), 15px); }
.bh-cd__done { margin-block-start: calc(20 * var(--u)); font-size: max(calc(70 * var(--u) * var(--bh-script-scale)), 30px); }
.bh-countdown__end {
  position: relative;
  max-width: min(max(calc(430 * var(--u)), 330px), 100%);
  margin-block-start: max(calc(64 * var(--u)), 40px);
}
.bh-countdown__line {
  font-size: max(calc(48 * var(--u) * var(--bh-script-scale)), 24px);
  line-height: 1.7;
  letter-spacing: 0.06em;
  text-wrap: balance;
}
.inv--beach[lang='ar'] .bh-countdown__line { font-size: max(calc(48 * var(--u) * 0.56), 21px); letter-spacing: 0; }

/* ------------------------------------------------------------------ 4 · the venue */
.bh-venue .bh-flow { padding-block-start: max(calc(76 * var(--u)), 56px); }
.bh-venue__art {
  position: relative;
  z-index: -1;
  width: max(calc(376 * var(--u)), min(320px, 100%));
  height: auto;
  margin-block-start: max(calc(-28 * var(--u)), -20px);
  margin-inline-start: max(calc(32 * var(--u)), 20px);
}
.bh-venue__name {
  margin-block-start: max(calc(26 * var(--u)), 20px);
  font-size: max(calc(44 * var(--u) * var(--bh-script-scale)), 22px);
  letter-spacing: 0.08em;
  line-height: 1.35;
}
.inv--beach[lang='ar'] .bh-venue__name { font-size: max(calc(44 * var(--u) * 0.56), 20px); letter-spacing: 0; line-height: 1.6; }
.bh-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: max(calc(187 * var(--u)), 150px);
  min-height: max(calc(37 * var(--u)), 38px);
  padding: 4px 22px;
  border: 1px solid var(--bh-ink-soft);
  border-radius: 999px;
  font-size: max(calc(12.27 * var(--u)), 13px);
  line-height: 1;
  color: var(--bh-ink-soft);
  text-decoration: none;
  transition: background-color 0.25s, color 0.25s;
}
.bh-pill:hover { background: var(--bh-ink); color: var(--bh-paper); }
.inv--beach[lang='ar'] .bh-pill { font-size: max(calc(15 * var(--u)), 15px); }
.bh-venue .bh-pill { margin-block-start: max(calc(24 * var(--u)), 18px); }

/* ------------------------------------------------------------------ 5 · where to stay */
.bh-stay .bh-flow { padding-block-end: max(calc(54 * var(--u)), 48px); }
.bh-stay__art {
  width: max(calc(115.67 * var(--u)), 92px);
  height: auto;
  margin-block-start: max(calc(70 * var(--u)), 32px);
}
.bh-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: max(calc(274 * var(--u)), min(260px, 100%));
  min-height: max(calc(48 * var(--u)), 48px);
  margin-block-start: max(calc(56 * var(--u)), 32px);
  padding: 8px max(calc(30 * var(--u)), 18px);
  background: rgba(0, 53, 122, 0.62);
  font-size: max(calc(12.27 * var(--u)), 13px);
  line-height: 1.3;
  color: var(--bh-paper);
  text-decoration: none;
  text-wrap: balance;
  transition: background-color 0.25s;
}
.bh-button:hover { background: var(--bh-ink); }
.inv--beach[lang='ar'] .bh-button { font-size: max(calc(15 * var(--u)), 15px); }

/* ------------------------------------------------------------------ 6 · getting there
   The postcard is the design's own scalloped card, stretched by its edges (border-image) so it grows with
   the lines inside it; the blue watercolour stripes run behind, repeating sideways on wide screens. */
.bh-travel {
  display: flex;
  justify-content: center;
  padding: max(calc(60 * var(--u)), 40px) 16px max(calc(80 * var(--u)), 48px);
  background: #F8F4ED url('beach-stripes.jpg') 50% 50% / auto max(100%, calc(604 * var(--u))) repeat-x;
}
.bh-travel__card {
  position: relative;
  width: min(max(calc(362 * var(--u)), 300px), 100%);
  min-height: max(calc(463 * var(--u)), 380px);
  padding: max(calc(40 * var(--u)), 32px) max(calc(30 * var(--u)), 26px);
  border: max(calc(18 * var(--u)), 14px) solid transparent;
  border-image: url('beach-postcard.webp') 64 fill / max(calc(21 * var(--u)), 17px) round;
  text-align: center;
}
.bh-travel__stamp {
  position: absolute;
  top: max(calc(94 * var(--u)), 76px);
  inset-inline-end: calc(-1 * max(calc(90 * var(--u)), 54px));
  width: max(calc(164 * var(--u)), 104px);
  height: auto;
  pointer-events: none;
}
.inv--beach[lang='ar'] .bh-travel__stamp { inset-inline-end: auto; right: calc(-1 * max(calc(90 * var(--u)), 54px)); }
@media (max-width: 599px) {
  .bh-travel__stamp,
  .inv--beach[lang='ar'] .bh-travel__stamp { inset-inline-end: auto; right: -18px; top: -30px; width: 96px; rotate: 8deg; }
}
.bh-travel__title {
  font-size: max(calc(52 * var(--u) * var(--bh-script-scale)), 26px);
  letter-spacing: 0.08em;
  line-height: 1.3;
}
.inv--beach[lang='ar'] .bh-travel__title { font-size: max(calc(52 * var(--u) * 0.56), 24px); letter-spacing: 0; }
.bh-travel__list {
  display: grid;
  gap: max(calc(56 * var(--u)), 34px);
  margin-block-start: max(calc(46 * var(--u)), 30px);
  list-style: none;
}
.bh-travel__item { display: grid; justify-items: center; gap: max(calc(6 * var(--u)), 4px); }
.bh-travel__way {
  font-size: max(calc(32 * var(--u) * var(--bh-script-scale)), 19px);
  letter-spacing: 0.1em;
  line-height: 1.3;
}
.inv--beach[lang='ar'] .bh-travel__way { font-size: max(calc(32 * var(--u) * 0.62), 19px); letter-spacing: 0; }
.bh-travel__detail { font-size: max(calc(12.27 * var(--u)), 13px); line-height: 1.25; }
.inv--beach[lang='ar'] .bh-travel__detail { font-size: max(calc(15 * var(--u)), 15px); line-height: 1.6; }

/* ------------------------------------------------------------------ 7 · timeline
   The island sits at the bottom of the page, to the left of the list, as on Canva page eight (physical
   side on purpose: the art never mirrors in Arabic). */
.bh-timeline .bh-flow { padding-block-end: max(calc(170 * var(--u)), 150px); }
.bh-timeline__art {
  position: absolute;
  z-index: -1;
  bottom: 0;
  left: calc(50% - 274 * var(--u));
  width: max(calc(267.67 * var(--u)), 170px);
  height: auto;
  pointer-events: none;
}
@media (max-width: 599px) {
  .bh-timeline__art { left: -24px; opacity: 0.9; }
}
.bh-tl {
  display: grid;
  gap: max(calc(56 * var(--u)), 26px);
  margin-block-start: max(calc(62 * var(--u)), 34px);
  list-style: none;
}
.bh-tl__item { font-size: max(calc(12.27 * var(--u)), 13px); line-height: 1.25; }
.inv--beach[lang='ar'] .bh-tl__item { font-size: max(calc(15 * var(--u)), 15px); line-height: 1.6; }
.bh-tl__time { unicode-bidi: isolate; }

/* ------------------------------------------------------------------ 8 · dress code */
.bh-dress .bh-flow { padding-block-start: max(calc(54 * var(--u)), 48px); }
.bh-dress__code { margin-block-start: max(calc(10 * var(--u)), 6px); font-size: max(calc(34 * var(--u) * var(--bh-script-scale)), 20px); letter-spacing: 0.1em; }
.inv--beach[lang='ar'] .bh-dress__code { font-size: max(calc(34 * var(--u) * 0.62), 19px); letter-spacing: 0; }
.bh-dress__art {
  width: max(calc(428 * var(--u)), min(340px, 100%));
  height: auto;
  margin-block-start: max(calc(34 * var(--u)), 22px);
}
.bh-dress__note {
  max-width: max(calc(320 * var(--u)), 280px);
  text-wrap: balance;
  margin-block-start: max(calc(34 * var(--u)), 22px);
  font-size: max(calc(12.27 * var(--u)), 13px);
  line-height: 1.25;
}
.inv--beach[lang='ar'] .bh-dress__note { font-size: max(calc(15 * var(--u)), 15px); line-height: 1.6; }
.bh-palette {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: max(calc(10 * var(--u)), 8px);
  margin-block-start: max(calc(30 * var(--u)), 20px);
  list-style: none;
  direction: ltr;
}
.bh-palette__dot { width: max(calc(68 * var(--u)), 52px); aspect-ratio: 1; }
.bh-palette__dot img { width: 100%; height: 100%; object-fit: contain; }
/* The couple's own colours: the watercolour dot's shape and grain, tinted. */
.bh-palette__dot--tint {
  background: var(--c);
  -webkit-mask: url('beach-swatch-3.webp') center / contain no-repeat;
  mask: url('beach-swatch-3.webp') center / contain no-repeat;
}

/* ------------------------------------------------------------------ 9 · RSVP */
.bh-rsvp__by { display: flex; flex-direction: column; align-items: center; }
.bh-rsvp__by-line { margin-block-start: max(calc(16 * var(--u)), 8px); line-height: 1.25; font-size: max(calc(34 * var(--u) * var(--bh-script-scale)), 20px); letter-spacing: 0.08em; }
.inv--beach[lang='ar'] .bh-rsvp__by-line { font-size: max(calc(34 * var(--u) * 0.62), 19px); letter-spacing: 0; }
.bh-rsvp__by-date { margin-block-start: max(calc(8 * var(--u)), 6px); font-size: max(calc(12.27 * var(--u)), 13px); line-height: 1.3; }
.bh-rsvp__by-date sup { font-size: 0.62em; line-height: 0; vertical-align: 0.7em; }
.inv--beach[lang='ar'] .bh-rsvp__by-date { font-size: max(calc(15 * var(--u)), 15px); }
.bh-rsvp__card {
  --pad: max(calc(32 * var(--u)), 22px);
  width: min(max(calc(428 * var(--u)), 340px), 100%);
  margin-block-start: max(calc(44 * var(--u)), 32px);
  padding: var(--pad);
  background: var(--bh-card);
  text-align: start;
}
/* Spacing: each label sits close to its own line, with clearly more room between one field and the next. */
.bh-form { display: grid; gap: max(calc(34 * var(--u)), 28px); }
.bh-field { display: grid; gap: max(calc(4 * var(--u)), 2px); }
.bh-field:has(.bh-box) { gap: max(calc(10 * var(--u)), 8px); }
.bh-label {
  display: block;
  font-size: max(calc(12.27 * var(--u)), 13px);
  line-height: 1.25;
}
.inv--beach[lang='ar'] .bh-label { font-size: max(calc(15 * var(--u)), 15px); line-height: 1.4; }
.bh-attend { gap: max(calc(10 * var(--u)), 8px); }
.bh-attend legend { margin-block-end: max(calc(12 * var(--u)), 10px); }
.bh-opt { display: flex; align-items: center; gap: max(calc(13 * var(--u)), 10px); cursor: pointer; }
.bh-opt span {
  font-size: max(calc(12.27 * var(--u)), 13px);
  letter-spacing: 0;
  color: var(--bh-ink);
  line-height: 1.4;
}
.inv--beach[lang='ar'] .bh-opt span { font-size: max(calc(15 * var(--u)), 15px); }
.bh-opt input {
  flex: none;
  display: grid;
  place-items: center;
  width: max(calc(16.7 * var(--u)), 18px);
  height: max(calc(16.7 * var(--u)), 18px);
  margin: 0;
  border: 1.5px solid var(--bh-ink);
  border-radius: 50%;
  background: #F1EFEB;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}
.bh-opt input::before {
  content: '';
  width: 50%;
  height: 50%;
  border-radius: 50%;
  background: var(--bh-ink);
  transform: scale(0);
  transition: transform 0.15s ease;
}
.bh-opt input:checked::before { transform: scale(1); }
.bh-line {
  width: 100%;
  min-height: 32px;
  padding: 2px 0 4px;
  border: 0;
  border-block-end: 1px solid var(--bh-ink);
  border-radius: 0;
  background: transparent;
  font: inherit;
  font-family: var(--bh-caps);
  font-size: 16px;
  color: var(--bh-ink);
}
select.bh-line { appearance: none; -webkit-appearance: none; cursor: pointer; background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%2300357A' stroke-width='1.4'/%3E%3C/svg%3E") no-repeat right 4px center; padding-inline-end: 22px; }
[dir='rtl'] select.bh-line { background-position: left 4px center; }
.bh-box {
  width: 100%;
  min-height: max(calc(97.5 * var(--u)), 96px);
  padding: max(calc(10 * var(--u)), 10px) max(calc(11.5 * var(--u)), 10px);
  border: 1px solid rgba(0, 53, 122, 0.6);
  border-radius: 0;
  background: var(--bh-card);
  font-family: var(--bh-caps);
  font-size: 16px;
  color: var(--bh-ink);
  resize: vertical;
}
.bh-box::placeholder {
  font-size: max(calc(12.27 * var(--u)), 13px);
  letter-spacing: var(--bh-track-sm);
  text-transform: uppercase;
  color: var(--bh-ink-soft);
}
.inv--beach[lang='ar'] .bh-box::placeholder { text-transform: none; font-size: 15px; }
.bh-submit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: max(calc(47.9 * var(--u)), 46px);
  margin-block-start: max(calc(6 * var(--u)), 4px);
  background: rgba(0, 53, 122, 0.62);
  font-size: max(calc(12.27 * var(--u)), 13px);
  color: var(--bh-paper);
  text-decoration: none;
  transition: background-color 0.25s;
}
.bh-submit:hover { background: var(--bh-ink); }
.bh-submit:disabled { opacity: 0.6; cursor: progress; }
.inv--beach[lang='ar'] .bh-submit { font-size: max(calc(15 * var(--u)), 15px); }
.bh-rsvp__thanks { font-size: max(calc(40 * var(--u) * var(--bh-script-scale)), 24px); line-height: 1.3; text-align: center; }
.inv--beach[lang='ar'] .bh-rsvp__thanks { font-size: max(calc(40 * var(--u) * 0.6), 20px); }
.bh-rsvp__error { font-family: var(--bh-caps); color: #8A1C1C; }

/* ------------------------------------------------------------------ 10 · footer */
.bh-footer {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: 18px;
  padding: max(calc(40 * var(--u)), 32px) 16px max(calc(70 * var(--u)), 48px);
  text-align: center;
}
.bh-footer__names { font-size: max(calc(53.3 * var(--u) * var(--bh-script-scale)), 30px); }
.inv--beach[lang='ar'] .bh-footer__names { font-size: max(calc(53.3 * var(--u) * 0.56), 24px); }
.bh-footer__closing { font-size: max(calc(12.27 * var(--u)), 13px); }
.bh-footer__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.bh-footer .bh-pill { min-width: 0; padding-inline: 18px; }
.bh-calendar .inv-calendar__menu { font-family: var(--bh-caps); }
.inv--beach .inv-footer__credit { font-family: var(--bh-caps); color: var(--bh-ink-soft); }
