/* The Tunnel Book, the camera walk-through (DRAFT 20 Oct 2026; the Sugar Bloom pattern): the stage (js/signature-tunnel-book-walk.js) and the Pass skin
 * (--wk-*, css/occasi-pass.css). Light: ivory paper, blush satin, cut-paper roses; warm ink and gilt.
 *   .tbw-art   the 1080 x 1920 picture: covers a phone, fits whole (contained) on a wide screen; --k = its width / 1080
 *   .tbw-box   a text area at render px (from plates/text_areas.json), scaled by --k
 *   the films sit over the plate; their first frame is the plate, so they cut in with no fade; the words fade out first. */
@font-face{font-family:'Great Vibes';src:url('../assets/fonts/great-vibes-latin.woff2') format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Cormorant';src:url('../assets/fonts/cormorant-latin.woff2') format('woff2');font-weight:300 700;font-display:swap}
@font-face{font-family:'EB Garamond';src:url('../assets/fonts/eb-garamond-latin.woff2') format('woff2');font-weight:400 800;font-display:swap}
@font-face{font-family:'EB Garamond';src:url('../assets/fonts/eb-garamond-italic-latin.woff2') format('woff2');font-style:italic;font-weight:400 800;font-display:swap}

html.tbw-on, html.tbw-on body { height: 100%; margin: 0; overflow: hidden; overscroll-behavior: none; }
body.tbw-page { margin: 0; background: #efe6dc; -webkit-text-size-adjust: 100%; }
.tbw.wk-root {
  /* v221: the Guest guide's ornament: three paper layers, as the book's cut pages */ --wk-orn: linear-gradient(#b08d57, #b08d57) 0 0 / 100% 1px no-repeat, linear-gradient(#b08d57, #b08d57) 50% 2.5px / 76% 1px no-repeat, linear-gradient(#b08d57, #b08d57) 50% 5px / 52% 1px no-repeat;
  --wk-bg: #fbf6ef; --wk-paper: #fffaf7; --wk-ink: #3a2e28; --wk-soft: #6d5a57; --wk-gold: #b08d57; --wk-rule: rgba(176, 141, 87, .34);
  --wk-display: 'EB Garamond', Georgia, serif; --wk-text: 'EB Garamond', Georgia, serif; --wk-display-style: italic; --wk-r: 6px;
  --wk-btn: #3a2e28; --wk-onbtn: #fff7f2;
  --wk-shadow: 0 12px 30px -16px rgba(80, 50, 50, .4), inset 0 0 0 1px rgba(176, 141, 87, .34);
  --tbw-ink: #3a2e28; --tbw-gilt: #b08d57; --tbw-gilt-ink: #4e3a1c;   /* v214: small-caps labels in a deep gold that reads at 4.5:1 or more on the cards */ --tbw-blush: #f3cfd3;
  position: fixed; inset: 0;
}
.tbw.wk-root, .tbw.wk-root *, .tbw .wk-sheet * { font-variant-numeric: lining-nums !important; }
/* the engine's own scenes: the stage is the only one shown; the shared "Will you join us?" scene and the computer's side
   panel are drawn into the hatbox card instead (draft: hidden) */
.tbw [data-wk-film] { overflow: hidden; scroll-snap-type: none; }
.tbw .wk-scene.tbw-scene { padding: 0; display: block; }
.tbw .wk-scene-join, .tbw .wkd-panel, .tbw .wk-progress { display: none !important; }

.tbw-stage { position: absolute; inset: 0; overflow: hidden; container-type: size; background: radial-gradient(120% 80% at 50% 40%, #fbf4ec, #eadccd); touch-action: none; }
.tbw-art { position: absolute; left: 50%; top: 50%; width: max(100cqw, 100cqh * 9 / 16); aspect-ratio: 9 / 16; transform: translate(-50%, -50%); --k: .4; }
/* v214 review: when a stop's content would be cropped on a narrow phone the art box scales down a little (js fit());
   these bands take the plate's own edge colours in the space left above and below */
.tbw-band { position: absolute; left: 50%; top: 0; transform: translateX(-50%); z-index: 0; background-repeat: no-repeat; pointer-events: none; }
.tbw-band.is-bottom { top: auto; bottom: 0; }
@container (min-aspect-ratio: 3 / 4) { .tbw-art { width: min(100cqw, 100cqh * 9 / 16); box-shadow: 0 30px 80px -40px rgba(80, 40, 40, .45); } }
.tbw-plate, .tbw-plate2, .tbw-film, .tbw-confetti { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.tbw-plate { transition: opacity .28s ease; }
.tbw-plate.is-x { opacity: .25; }
.tbw-plate2 { opacity: 0; transition: opacity .32s ease; }
.tbw-plate2.on { opacity: 1; }
.tbw-film { opacity: 0; pointer-events: none; }
.tbw-film.on { opacity: 1; }
.tbw-confetti { pointer-events: none; z-index: 6; }
/* the opening: the closed doors' idle loop covers the hero until it is opened */
.tbw-idle { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 4; pointer-events: none; }
.tbw-idle.is-gone { display: none; }
.tbw-words.is-doors { z-index: 5; }
.tbw-film { z-index: 5; }
.tbw-doors { position: absolute; z-index: 7; left: 50%; bottom: calc(52px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%); min-height: 48px; padding: 0 26px; border: 0; border-radius: 99px; background: rgba(255, 250, 247, .94); color: var(--tbw-ink); font: italic 500 18px 'EB Garamond', serif; box-shadow: 0 8px 22px -12px rgba(80, 40, 40, .55); cursor: pointer; }
.tbw-doors[hidden] { display: none; }

/* the words on the plate */
.tbw-words { position: absolute; inset: 0; z-index: 3; transition: opacity .18s ease; -webkit-user-select: none; user-select: none; }
.tbw-words :is(input, textarea, select, [contenteditable]) { -webkit-user-select: text; user-select: text; }   /* v285 (lead, 2 Nov): a drag never highlights the printed words; the reply's fields stay editable */
.tbw-words.is-off { opacity: 0; pointer-events: none; transition-duration: .12s; }
.tbw-words.is-cut, .tbw-words.is-cut.is-off { transition: none; }   /* v228: the hand-over to and from a film's printed words, in one frame */
.tbw-box { position: absolute; display: grid; place-items: center; text-align: center; color: var(--tbw-ink); }
.tbw-in { width: 100%; max-height: 100%; overflow: hidden; }
.tbw-box p { margin: 0; }
.tbw-names { font: 400 calc(var(--f, 1) * max(22px, calc(var(--k) * 74px))) / 1.05 'Great Vibes', cursive; }
.tbw-names i { font: italic 500 .5em 'EB Garamond', serif; color: var(--tbw-gilt); }
.tbw-date { margin-top: .3em !important; font: 600 calc(var(--f, 1) * max(11px, calc(var(--k) * 27px))) / 1.2 'Cormorant', serif; letter-spacing: .18em; text-transform: uppercase; }
.tbw-evname { font: italic 500 calc(var(--f, 1) * max(13px, calc(var(--k) * 44px))) / 1.05 'EB Garamond', serif; }
.tbw-evline { font: 600 calc(var(--f, 1) * max(10px, calc(var(--k) * 25px))) / 1.1 'Cormorant', serif; letter-spacing: .03em; color: #4a3a35; }
.tbw-sthead { font: 600 calc(var(--f, 1) * max(10px, calc(var(--k) * 26px))) / 1.15 'Cormorant', serif; letter-spacing: .06em; text-transform: uppercase; color: var(--tbw-gilt-ink); }
.tbw-sttext { font: italic 400 calc(var(--f, 1) * max(11px, calc(var(--k) * 28px))) / 1.18 'EB Garamond', serif; }
.tbw-sttitle { font: 400 calc(var(--f, 1) * max(22px, calc(var(--k) * 70px))) / 1 'Great Vibes', cursive; }
.tbw-scroll .tbw-in { overflow-y: auto; max-height: 100%; scrollbar-width: none; }
.tbw-scroll .tbw-sttext + .tbw-sttext { margin-top: .6em; }
.tbw-ppname { font: italic 500 calc(var(--f, 1) * max(10px, calc(var(--k) * 30px))) / 1.05 'EB Garamond', serif; }
.tbw-pprole { font: 600 calc(var(--f, 1) * max(10px, calc(var(--k) * 19px))) / 1.02 'Cormorant', serif; letter-spacing: .05em; text-transform: uppercase; color: #4a3a35; }
/* v212-tb: "+ N more" past twelve people: a small paper tag on a gilt string under the lowest tag (js: the people words) */
.tbw-box.tbw-more { z-index: 2; overflow: visible; }
.tbw-more .tbw-in { position: relative; height: 100%; max-height: none; overflow: visible; filter: drop-shadow(0 calc(var(--k) * 6px) calc(var(--k) * 8px) rgba(80, 50, 40, .28)); }
.tbw-more .tbw-in::before { content: ''; position: absolute; left: 50%; bottom: calc(100% - var(--k) * 14px); width: max(1px, calc(var(--k) * 2.5px)); height: calc(var(--k) * 40px); transform: translateX(-50%); background: linear-gradient(#c9a86a, #b08d57); }
.tbw-moretag { position: relative; display: grid; place-items: center; height: 100%; padding: calc(var(--k) * 16px) calc(var(--k) * 14px) calc(var(--k) * 8px); background: #fbf4e8; clip-path: polygon(16% 0, 84% 0, 100% 26%, 100% 100%, 0 100%, 0 26%); box-shadow: inset 0 0 0 calc(var(--k) * 3px) rgba(176, 141, 87, .6), inset 0 0 0 calc(var(--k) * 7px) #fbf4e8, inset 0 0 0 calc(var(--k) * 8px) rgba(176, 141, 87, .35); }
.tbw-moretag::before { content: ''; position: absolute; left: 50%; top: calc(var(--k) * 9px); width: calc(var(--k) * 12px); height: calc(var(--k) * 12px); transform: translateX(-50%); border-radius: 50%; background: #e9dcc6; box-shadow: inset 0 0 0 calc(var(--k) * 2px) #b08d57; }
.tbw-more p { margin-top: calc(var(--k) * 10px); font: italic 500 calc(var(--f, 1) * max(11px, calc(var(--k) * 30px))) / 1.1 'EB Garamond', serif; color: var(--tbw-ink); white-space: nowrap; }

/* the hatbox: the sugar rose opens it; the reply is drawn on the card (lifted to a readable size on a phone) */
.tbw-rose { position: absolute; z-index: 4; left: 50%; top: 70%; width: 80%; height: 38%; transform: translate(-50%, -50%); border: 0; border-radius: 40%; background: transparent; cursor: pointer; }
.tbw-rose::after { content: attr(aria-label); position: absolute; left: 50%; top: calc(100% + 6px); transform: translateX(-50%); white-space: nowrap; padding: 6px 12px; border-radius: 99px; background: rgba(255, 250, 247, .92); color: var(--tbw-ink); font: italic 500 15px 'EB Garamond', serif; box-shadow: 0 6px 18px -10px rgba(80, 40, 40, .5); }
.tbw-box.tbw-card { position: static; }
.tbw-reply { position: absolute; left: 50%; top: calc(var(--k) * 847px); transform: translate(-50%, -50%); width: min(86cqw, 380px, 100%); max-height: min(78cqh, calc(var(--k) * 1500px)); overflow-y: auto; overscroll-behavior: contain;
  padding: 22px 18px; text-align: center; background: #fffaf7; border-radius: 4px; box-shadow: 0 18px 40px -22px rgba(80, 40, 40, .55), inset 0 0 0 1px rgba(176, 141, 87, .5), inset 0 0 0 5px #fffaf7, inset 0 0 0 6px rgba(176, 141, 87, .25); }
.tbw-reply [data-tbw-change]:not([hidden]) ~ [data-tbw-join] { display: none; }
.tbw-back { display: none; margin: 14px auto 0; min-height: 40px; padding: 0 16px; border: 0; background: none; color: var(--tbw-ink); font: italic 500 15px 'EB Garamond', serif; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.tbw-reply [data-tbw-change]:not([hidden]) + .tbw-back { display: block; }
/* v285.2 (lead 3 Nov): a sheet that brings its own Back (the "can't make it" one) hides the walk's, so there is one Back */
.tbw-reply [data-tbw-change]:not([hidden]):has([data-wk-close]) + .tbw-back { display: none; }
.tbw-stage.is-pass .tbw-dots { display: none; }
.tbw-reply .wk-join { padding: 0 0 12px; }   /* v282: "Made with Occasi" clear of the card's frame (it sat on it) */
/* v262 (study #3 row 6, as Sugar Bloom): the page reads easily on a phone: small capitals and days 13 px, links and body
   14 px. A page that would scroll tightens its spacing (is-s1, is-s2: js fitCard), never its type. */
.tbw-reply { --wk-label: 13px; --wk-tiny: 13px; --wk-body: 14px; }
.tbw-reply .wk-kicker, .tbw-reply .wk-label { letter-spacing: .14em; }
.tbw-reply .wk-jwhen { font-size: 13px; }
.tbw-reply .wk-jwhen b { letter-spacing: .12em; }
.tbw-reply .wk-jrow { grid-template-columns: 4px 62px 1fr 14px; }
.tbw-reply .wk-jrow.is-compact { grid-template-columns: 4px 96px 1fr 14px; }
.tbw-reply .wk-extras, .tbw-reply .wk-sendpass, .tbw-reply .wk-privlink, .tbw-reply .wk-jmore { font-size: 14px; }
.tbw-reply .wk-made { font-size: 13px; opacity: 1; }
.tbw-reply.is-s1 { padding-block: 14px; }
.tbw-reply.is-s1 .wk-h1 { font-size: 27px; margin-top: 2px; }
.tbw-reply.is-s1 .wk-sub { margin-top: 2px; line-height: 1.3; }
.tbw-reply.is-s1 .wk-jlist { margin-top: 8px; }
.tbw-reply.is-s1 .wk-jrow { min-height: 44px; padding-block: 4px; }
.tbw-reply.is-s1 .wk-jrow.is-compact { min-height: 29px; padding-block: 2px; }
.tbw-reply.is-s1 .wk-jmore { min-height: 30px; }
.tbw-reply.is-s1 .wk-yes { min-height: 46px; margin-top: 10px; }
.tbw-reply.is-s1 .wk-namefield { margin-top: 6px; }
.tbw-reply.is-s2 .wk-field input { min-height: 40px; padding-block: 6px; }
.tbw-reply.is-s2 .wk-link { min-height: 32px; padding-block: 4px; }
.tbw-reply.is-s2 .wk-extras { margin-top: 0; }
.tbw-reply.is-s2 .wk-sendpass, .tbw-reply.is-s2 .wk-privlink { min-height: 28px; margin-top: 0; padding-block: 2px; }
.tbw-reply.is-s2 .wk-made { margin-top: 2px; }
.tbw-reply.is-s2 .wk-extras > i { display: none; }   /* "(optional)": the pencil and "Add" say it */
.tbw-reply.is-s3 > * { zoom: var(--rz, 1); }   /* 13 px x 0.92 = 12 px, the floor */
.tbw-reply.is-s3 { padding-block: 8px; }   /* v282: the room for "Made with Occasi" comes from the frame and the button, not the words */
.tbw-reply.is-s3 .wk-yes { margin-top: 6px; }
.tbw-passcard .tbw-in { display: grid; gap: .5em; justify-items: center; }
.tbw-open { margin-top: .9em; min-height: 44px; padding: 4px 16px; max-width: 100%; line-height: 1.15; text-wrap: balance;   /* v285: "Open your wedding guide" wraps evenly on a narrow card */
   border: 0; border-radius: 99px; background: var(--wk-btn); color: var(--wk-onbtn); font: italic 500 16px 'EB Garamond', serif; cursor: pointer; }

/* the way through: the dots, "Next 4" for a fifth event and more, the first hint */
.tbw-dots { position: absolute; z-index: 7; left: 50%; top: calc(6px + env(safe-area-inset-top, 0px)); transform: translateX(-50%); display: flex; gap: 2px; padding: 0 6px; border-radius: 99px; background: rgba(255, 250, 247, .55); }
.tbw-dots button { width: 24px; height: 24px; border: 0; padding: 0; background: transparent; cursor: pointer; display: grid; place-items: center; }
.tbw-dots button::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: rgba(59, 45, 44, .28); box-shadow: 0 0 0 1px rgba(255, 255, 255, .7); }
.tbw-dots button[aria-current]::before { background: var(--tbw-ink); }
.tbw-next4 { position: absolute; z-index: 7; left: 50%; bottom: calc(var(--k) * 150px); transform: translateX(-50%); min-height: 44px; padding: 0 20px; border: 0; border-radius: 99px; background: rgba(255, 250, 247, .94); color: var(--tbw-ink); font: italic 500 16px 'EB Garamond', serif; box-shadow: 0 6px 18px -10px rgba(80, 40, 40, .5); cursor: pointer; }
.tbw-hint { position: absolute; z-index: 7; left: 0; right: 0; bottom: calc(18px + env(safe-area-inset-bottom, 0px)); margin: 0; text-align: center; font: italic 500 15px 'EB Garamond', serif; color: var(--tbw-ink); text-shadow: 0 1px 8px #fff; pointer-events: none; }
.tbw-photo { position: absolute; object-fit: cover; border-radius: 2px; z-index: 0; }
.tbw-error { padding: 2rem; font-family: serif; }
@media (prefers-reduced-motion: reduce) { .tbw-plate, .tbw-plate2, .tbw-words { transition-duration: .01s; } }
/* on a computer the engine frames its film beside a side panel; the walk-through takes the whole window instead */
.tbw.wk-root .wk-app[data-view="film"] { top: 0; bottom: 0; left: 0; width: 100%; height: 100%; border-radius: 0; box-shadow: none; }
.tbw.wk-root .wk-app[data-view="film"] .wk-scene > .tbw-stage { max-width: none; }
/* the printed-text film canvas (OccasiPrintedText.film) sits over the film; the measuring copy of the words is invisible */
.tbw-art .op-filmcanvas { z-index: 5; }
.tbw-words.tbw-measure { opacity: 0; pointer-events: none; z-index: -1; }
.tbw-words.tbw-measure button { visibility: hidden; }
.tbw-words.tbw-measure .tbw-pgbtn { visibility: visible; }   /* v285.2: the pager's arrows are words on its tag, so the film prints them */
/* the people stop: only the biscuits of people who exist, on the bare tree (z between the plate and the words) */
.tbw-bis { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.tbw-bis img { position: absolute; display: block; }
.tbw-film.is-soft { transition: opacity .3s ease; }
/* The Tunnel Book (20 Oct): text areas can lie at an angle on their object (the form on the open book, the cards). The box
   sits at its top-left corner and turns about it; the opening's "Open the invitation"; the book's gold seal opens the reply. */
.tbw-box.is-rot { transform-origin: 0 0; }
.tbw-tagfor { font: italic 500 calc(var(--f, 1) * max(10px, calc(var(--k) * 30px))) / 1.1 'EB Garamond', serif; color: #6a5a52; }
.tbw-seal { position: absolute; z-index: 4; border: 0; border-radius: 50%; background: transparent; cursor: pointer; transform: translate(-50%, -50%); }
.tbw-seal::after { content: attr(aria-label); position: absolute; left: 50%; top: calc(100% + 8px); transform: translateX(-50%); white-space: nowrap; padding: 6px 12px; border-radius: 99px; background: rgba(255, 250, 247, .92); color: var(--tbw-ink); font: italic 500 15px 'EB Garamond', serif; box-shadow: 0 6px 18px -10px rgba(80, 40, 40, .5); }
.tbw-seal[hidden] { display: none; }
.tbw-tags { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.tbw-tags img { position: absolute; display: block; }
.tbw-thanks .tbw-in { display: grid; gap: .45em; justify-items: center; }
/* 31 Oct (lead): the thank-you card's words read at a glance on a phone: the couple's names (and any message line) never
   under 14 px; long names wrap inside the card, never shrink past that. text-wrap: balance evens the lines (no lone
   word on the last line); browsers without it simply wrap as before. */
/* (the card's paper rose and sprig fill its top fifth: the words sit in the clear paper below them) */
.tbw-thanks { padding-top: calc(var(--k) * var(--bh) * .18px); box-sizing: border-box; }
.tbw-thanks .tbw-evline { font-size: max(14px, calc(var(--f, 1) * max(10px, calc(var(--k) * 25px)))); line-height: 1.15; overflow-wrap: break-word; text-wrap: balance; }
/* (lead, 1 Nov: each partner's name is one unit, so a long pair breaks between the two people, "A Smit / & B Ro"; a
   name too wide for the card still wraps inside its own unit, evenly) */
.tbw-thanks .tbw-pn { display: inline-block; max-width: 100%; text-wrap: balance; }
/* the arch: "More events" sits in the open arch above the first card (never over a card, never cropped) */
.tbw-next4 { bottom: auto; top: calc(var(--k) * 740px); }

/* v210: two events to a card (3-4 events on a page); card 2 asks for the reply when there is one event */
.tbw-ev2 .tbw-in { display: grid; gap: .5em; }
.tbw-ev2 .tbw-evone + .tbw-evone { padding-top: .45em; border-top: 1px solid rgba(150, 120, 80, .35); }
.tbw-ev2 .tbw-evname { font-size: .82em; }
/* v210: our story's photos in the scroll */
.tbw-stphoto { display: block; position: relative; margin: .8em auto .4em; width: 72%; aspect-ratio: 888 / 744; }
/* 29 Oct (owner standard): the photo sits in the window of the book's own lace mount (tb_photoframe.py, frames.json) */
.tbw-stphoto img:not(.tbw-pfr) { position: absolute; left: 18.83%; top: 22.48%; width: 62.21%; height: 54.89%; object-fit: cover; display: block; border-radius: 1.6% / 2%; }
.tbw-stgrid.is-2col .tbw-stphoto img:not(.tbw-pfr) { top: 29.04%; height: 41.73%; }
.tbw-stphoto .tbw-pfr, .tbw-ppwin .tbw-pfr { position: absolute; left: 0; top: 0; width: 100%; height: 100%; border-radius: 0; pointer-events: none; }
/* v210: the people's photos on the tags */
.tbw-pp.has-photo .tbw-in { display: grid; justify-items: center; gap: calc(var(--k) * 4px); }
.tbw-ppwin { display: block; position: relative; height: calc(var(--k) * 76px); aspect-ratio: 552 / 696; }
/* 29 Oct (owner standard): the photo in the window of the book's own lace oval (tb_photoframe.py, frames.json) */
.tbw-ppwin img:not(.tbw-pfr) { position: absolute; left: 22.75%; top: 22.31%; width: 54.35%; height: 55.17%; object-fit: cover; display: block; border-radius: 50%; }
/* v210: the reply page's words as the book opens */
.tbw-pageprev .tbw-in { display: grid; gap: .35em; justify-items: center; text-align: center; }
.tbw-ckick { font: 600 calc(var(--f, 1) * max(10px, calc(var(--k) * 22px))) / 1.2 'Cormorant', serif; letter-spacing: .22em; text-transform: uppercase; color: var(--tbw-gilt-ink); }
.tbw-ctitle { font: italic 500 calc(var(--f, 1) * max(18px, calc(var(--k) * 60px))) / 1.05 'EB Garamond', serif; }
.tbw-cfor { font: italic 400 calc(var(--f, 1) * max(11px, calc(var(--k) * 28px))) / 1.2 'EB Garamond', serif; }
.tbw-clist { list-style: none; margin: .3em 0 0; padding: 0; display: grid; gap: .25em; font: 500 calc(var(--f, 1) * max(10px, calc(var(--k) * 26px))) / 1.2 'EB Garamond', serif; }
.tbw-clist span { color: #8a6d45; font-size: .85em; }
/* v211: the posies by count: a bigger tag gets a bigger photo window and bigger words */
.tbw-pp { container-type: size; }
.tbw-pp.has-photo .tbw-ppwin { height: max(30px, min(50cqh, 63cqw)); width: auto; }
.tbw-pp .tbw-ppname { font-size: calc(var(--f, 1) * max(10px, calc(var(--k) * 30px), min(11cqw, 14cqh))); }
.tbw-pp .tbw-pprole { font-size: calc(var(--f, 1) * max(10px, min(6.5cqw, 8cqh))); }
/* 31 Oct (lead): from ten people up the tags are small, so on a phone a name never goes under 12 px (the fit's own floor is
   10: !important outranks its inline steps) and a role never under 9 px; a role too long for the tag wraps inside it instead
   of shrinking, and a single long word (GROOMSMAN) breaks at a hyphen where the phone hyphenates, else it is never cut
   mid-letter (unspaced it is 59 px on a 57 px area at 360: 1 px past each side, still inside the gilt rule).
   Only the people boxes are in the words layer here, so a tenth child = ten.
   (lead) Not left to hyphenation: the words may use 5 render px of the 6-7 px gutter on each side, inside the gilt rule
   (measured on p10-p12; at every count, the gutter grows with the tag), so GROOMSMAN fits whole and centred at 360
   (59 px on 61); only a still longer word breaks. */
/* (v285.1: the 5 render px each side inside the gilt rule are now the tag box itself: text_areas.json people_<n> "grow", so the films carry them too) */
/* 31 Oct (lead): one to nine people, the tags are big and the words were lost mid-card: the name is ~17% of the tag's
   width (16-24 px), the role 55% of it (never under 9 px), the block a little above the middle (the hole and ribbon are
   above, the room is below). Not !important: a name too long for even 16 px still has the fit's own steps, never clipped. */
.tbw-words:not(:has(> .tbw-pp:nth-child(10))) .tbw-pp:not(.has-photo) > .tbw-in { translate: 0 -15cqh; }   /* the area sits low in the gilt frame (its words at ~58%): lifted to ~47%, clear of the hole */
.tbw-words:not(:has(> .tbw-pp:nth-child(10))) .tbw-pp:not(.has-photo) .tbw-ppname { font-size: calc(var(--f, 1) * clamp(16px, 17cqw, 24px)); line-height: 1.05; }
.tbw-words:not(:has(> .tbw-pp:nth-child(10))) .tbw-pp:not(.has-photo) .tbw-pprole { font-size: calc(var(--f, 1) * max(10px, .55 * clamp(16px, 17cqw, 24px))); margin-top: .25em; }
.tbw-words:has(> .tbw-pp:nth-child(10)) .tbw-ppname { font-size: max(10px, calc(var(--f, 1) * max(10px, calc(var(--k) * 30px), min(11cqw, 14cqh)))) !important; line-height: 1; }
.tbw-words:has(> .tbw-pp:nth-child(10)) .tbw-pprole { font-size: max(10px, calc(var(--f, 1) * max(10px, min(6.5cqw, 8cqh)))) !important; letter-spacing: 0; line-height: 1.05; }
/* v214 (owner, 23 Oct): our story at once: up to six moments in two columns on the scroll, each with its photo; nothing
   scrolls; the words fit their cell (the editor's limits keep them readable) */
.tbw-story6 .tbw-in { display: flex; flex-direction: column; height: 100%; }
.tbw-stgrid { display: grid; grid-template-columns: 1fr; gap: .5em .7em; align-content: start; }
.tbw-stgrid.is-2col { grid-template-columns: 1fr 1fr; }
/* one to three moments: each a row, the photo beside its words (the board's height shared, never a tall photo stack) */
.tbw-stgrid:not(.is-2col) .tbw-stcell { display: grid; grid-template-columns: 44% 1fr; grid-template-rows: auto 1fr; column-gap: .7em; align-items: start; }
.tbw-stgrid:not(.is-2col) .tbw-stphoto { grid-row: 1 / span 2; margin: 0; }
.tbw-stgrid:not(.is-2col) .tbw-stcell:not(:has(.tbw-stphoto)) { grid-template-columns: 1fr; }
/* v214 review: one or two moments use the scroll's full height (no blank lower scroll): one moment stands as a large photo
   over its words, two share the height evenly with bigger photos */
.tbw-stgrid.is-one, .tbw-stgrid.is-few { flex: 1 1 auto; align-content: space-evenly; }
.tbw-stgrid.is-one .tbw-stcell { display: block; text-align: center; }
.tbw-stgrid.is-one .tbw-stphoto { width: 92%; margin: 0 auto .6em; }
.tbw-stgrid.is-few .tbw-stcell { grid-template-columns: 52% 1fr; align-items: center; }
.tbw-stgrid.is-one .tbw-sttext, .tbw-stgrid.is-few .tbw-sttext { font-size: calc(var(--f, 1) * max(12px, calc(var(--k) * 32px))); }
.tbw-stcell { min-width: 0; }
.tbw-stgrid .tbw-stphoto { width: 100%; margin: 0 0 .25em; }
.tbw-stgrid.is-2col .tbw-stphoto { aspect-ratio: 888 / 576; }
.tbw-stgrid.is-2col .tbw-sthead { font-size: calc(var(--f, 1) * max(10px, calc(var(--k) * 21px))); }
.tbw-stgrid.is-2col .tbw-sttext { font-size: calc(var(--f, 1) * max(10px, calc(var(--k) * 22px))); line-height: 1.2; }
/* v214: words never clipped (when they are longer than the editor's limits, the box lets them show) */
.tbw-box.is-full, .tbw-box.is-full .tbw-in { overflow: visible; max-height: none; }

/* v221: the reply stop is one screen (one-shot rule); the guide hint would push it over, so the Pass itself carries the guide entry */
.tbw .wk-guidehint { display: none; }
/* v222 (owner, 24 Oct): the opening. "Open the invitation" belongs to the screen, not the picture (on a short phone the picture
   runs past the bottom edge); it fades on the tap. The opening film and its printed tag dissolve in over the closed book
   (0.32 s) while the tag's names dissolve out: one continuous move. The card shadow eases in after the opening (a wide window
   fills edge to edge while the book waits: css/occasi-walk-alive.css .wa-side, .wa-feather). */
.tbw-doors { transition: opacity .25s ease; }
.tbw-doors.is-going { opacity: 0; pointer-events: none; }
.tbw-film.is-xfade, .tbw-art .op-filmcanvas.is-xfade { transition: opacity .32s ease; }
.tbw-words.is-xfade.is-off { transition-duration: .32s; }
.tbw-art { transition: box-shadow .6s ease; }
.tbw-doors { -webkit-tap-highlight-color: transparent; }
/* v222 (one-shot rule): the open reply card is whole on one screen at every size, never scrolled inside. Where a phone crops
   the picture the card slides just enough to stay on screen (js: OccasiWalkAlive.onScreen sets --wa-dx/--wa-dy), and on a short
   screen it may use the screen's height instead of 78 % of it (the card itself is unchanged: same paper, frame and words). */
.tbw-reply { transform: translate(calc(-50% + var(--wa-dx, 0px)), calc(-50% + var(--wa-dy, 0px))); max-height: min(calc(100cqh - 16px), var(--wa-room, 100cqh), max(78cqh, calc(var(--k) * 1500px))); }
.tbw-art .op-filmcanvas.is-held { opacity: 0 !important; }   /* v222: the opening film's words, laid in while the book waits */
/* v267 (owner, 27 Oct): who sent it, before the tap, on the book's own hanging tag ("Specially for / Sophie & James / from
   Amelia & Rohan"; the shared link: "An invitation from" over the couple) */
.tbw-kick { font: 600 calc(var(--f, 1) * max(10px, calc(var(--k) * 21px))) / 1.2 'Cormorant', serif; letter-spacing: .16em; text-transform: uppercase; color: var(--tbw-gilt-ink); }
.tbw-tname { margin-top: .1em !important; font: 400 calc(var(--f, 1) * max(18px, calc(var(--k) * 56px))) / 1.05 'Great Vibes', cursive; }
.tbw-tfrom { margin-top: .25em !important; font: italic 500 calc(var(--f, 1) * max(10px, calc(var(--k) * 26px))) / 1.15 'EB Garamond', serif; color: #4a3a35; }
/* the tag on the bow is narrow: its kicker is the italic line of the old "For" (one line), so the names stay the largest */
.tbw-tag .tbw-kick { font: italic 500 calc(var(--f, 1) * max(10px, calc(var(--k) * 26px))) / 1.1 'EB Garamond', serif; letter-spacing: 0; text-transform: none; color: #6a5a52; }
.tbw-tag .tbw-tfrom { font-size: calc(var(--f, 1) * max(10px, calc(var(--k) * 24px))); }
.tbw-tag .tbw-kick + .tbw-names { font-size: calc(var(--f, 1) * max(18px, calc(var(--k) * 58px))); }
/* v285 (lead, 2 Nov): the script's swash "&" and the loop of its "J" reach past their line boxes, so the fit keeps a margin
   inside the gold frame on every side (the clip edge sat right under the last line and left a stray "(" of the J's loop) */
.tbw-tag .tbw-in { box-sizing: border-box; padding: calc(var(--k) * 30px) 11%; }
/* r8: the closed reply book's cover label, "Kindly reply by <date>": dark ink printed on the card, 10 px or more on a phone, no glow */
.tbw-replyby .tbw-in { display: grid; gap: .1em; justify-items: center; }
.tbw-replyby .tbw-in.op-ink { text-shadow: none; }
.tbw-rbkick { font: italic 500 calc(var(--f, 1) * max(11px, calc(var(--k) * 24px))) / 1.1 'EB Garamond', serif; color: #4a3a35; white-space: nowrap; }
.tbw-rbdate { font: 600 calc(var(--f, 1) * max(11px, calc(var(--k) * 24px))) / 1.1 'Cormorant', serif; letter-spacing: .06em; text-transform: uppercase; color: var(--tbw-ink); white-space: nowrap; }
.tbw-rbname { font: 500 calc(var(--f, 1) * max(12px, calc(var(--k) * 30px))) / 1.05 'Cormorant', serif; color: var(--tbw-ink); text-align: center; overflow-wrap: anywhere; }
/* v267: "Tap to open", Skip and Reply in the book's own material: die-cut ivory card with a gilt double frame (as the book's
   tags and the "+ more" tag); Skip and Reply are hanging tags with a gilt eyelet. Dark ink, 16-18 px, 44 px and more to tap. */
.tbw-paper { position: absolute; display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 44px; padding: 0 18px; border: 0; background: none; color: #2e241f; white-space: nowrap; cursor: pointer; isolation: isolate; filter: drop-shadow(0 4px 5px rgba(80, 50, 40, .3)); -webkit-tap-highlight-color: transparent; }
.tbw-paper::before { content: ''; position: absolute; inset: 0; z-index: -1; background: #fbf4e8; clip-path: polygon(10px 0, calc(100% - 10px) 0, 100% 10px, 100% calc(100% - 10px), calc(100% - 10px) 100%, 10px 100%, 0 calc(100% - 10px), 0 10px); box-shadow: inset 0 0 0 2px rgba(176, 141, 87, .75), inset 0 0 0 5px #fbf4e8, inset 0 0 0 6px rgba(176, 141, 87, .4); }
.tbw-paper[hidden] { display: none; }
.tbw-doors.tbw-paper { min-height: 50px; padding: 0 30px; border-radius: 0; background: none; box-shadow: none; font: italic 600 18px / 1 'EB Garamond', serif; }
.tbw-doors.tbw-paper.has-from { flex-direction: column; gap: 3px; padding: 8px 24px 9px; width: max-content; max-width: calc(100cqw - 32px); }
.tbw-dfrom { font: italic 500 15px / 1.15 'EB Garamond', serif; color: #4a3a35; white-space: normal; max-width: min(78vw, 300px); text-align: center; }
.tbw-flag { z-index: 8; right: 0; padding: 0 12px 0 32px; font: italic 600 17px / 1 'EB Garamond', serif; }
.tbw-flag::before { clip-path: polygon(16px 0, 100% 0, 100% 100%, 16px 100%, 0 50%); box-shadow: inset 0 2px 0 rgba(176, 141, 87, .75), inset 0 -2px 0 rgba(176, 141, 87, .75), inset 0 5px 0 #fbf4e8, inset 0 -5px 0 #fbf4e8, inset 0 6px 0 rgba(176, 141, 87, .4), inset 0 -6px 0 rgba(176, 141, 87, .4); }
.tbw-flag::after { content: ''; position: absolute; left: 13px; top: 50%; width: 9px; height: 9px; margin-top: -4.5px; border-radius: 50%; background: #e9dcc6; box-shadow: inset 0 0 0 2px #b08d57; }
.tbw-skip { top: calc(40px + env(safe-area-inset-top, 0px)); font-size: 16px; }   /* under the place dots (a long "Überspringen" reached them at 360) */
.tbw-replytag { top: calc(40px + env(safe-area-inset-top, 0px)); font-size: 18px; }
@container (min-aspect-ratio: 3 / 4) { .tbw-flag { right: max(0px, calc(50cqw - 100cqh * 9 / 32)); } }
.tbw-seali { width: 22px; height: 22px; flex: none; }
/* v267: the dissolve's still copy over the stage (Skip, Reply); at once with reduced motion */
.tbw-xfade { position: absolute; z-index: 6; pointer-events: none; overflow: hidden; transition: opacity .36s ease; }
.tbw-xfade.is-off { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .tbw-xfade { transition-duration: .01s; } }

.tbw-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }

/* v283 (sense check #12): a celebration card on the arch opens its event */
[data-tbw-event] { cursor: pointer; border-radius: calc(var(--k) * 12px); }
[data-tbw-event]:focus-visible { outline: 2px solid var(--wk-btn, #8a5a64); outline-offset: 3px; }

/* v285.1 (caps fit, 2 Nov): every line 10 px or more on a phone, the words whole on their object at the caps (names 15 + 15,
   events 30, venues 40, people 30, roles 24, story titles 40). Roles, story headings, kickers and the reply page's kicker
   now floor at 10 px (was 9); from ten people up a name may go down to 10 px (was 12) and a role never breaks inside a word
   (no hyphenation, no break anywhere): the camera comes closer instead (js target(): the words' own fit). A script name that
   cannot stay at 13 px or more sets in the design's EB Garamond italic (is-alt1), then its narrower Cormorant (is-alt2). */
.tbw-names i { font-size: max(10px, .5em); }
.tbw-box.is-alt1 :is(.tbw-names, .tbw-tname) { font-family: 'EB Garamond', Georgia, serif; font-style: italic; font-weight: 500; line-height: 1.12; }
.tbw-box.is-alt2 :is(.tbw-names, .tbw-tname, .tbw-evname, .tbw-ppname) { font-family: 'Cormorant', Georgia, serif; font-style: normal; font-weight: 600; line-height: 1.1; }
.tbw-box:is(.is-alt1, .is-alt2) .tbw-names i { font-size: max(10px, .8em); }
/* the scroll's "Our story" swash keeps clear of the first heading's line */
.tbw-story6 .tbw-sttitle { margin-bottom: .12em; }
/* v285.2 (owner 3 Nov "page 2 turned in place"): the pager on a small paper tag, "‹ 1 / 2 ›" in the cards' ink. The events'
   tag hangs on a gilt string from the bow's knot over the cards; the people's from the posy's lowest tag. Drawn inside its box
   (no shadow past the box), so the films print it as it rests. Each arrow is a native button; its tap reaches 44 x 44 px past
   the glyph (::after, outside the paper's clip); the way that is shut is lighter and thinner, never colour alone */
.tbw-box.tbw-p2tag { z-index: 2; place-items: stretch; }
.tbw-p2tag .tbw-in { display: flex; flex-direction: column; align-items: center; height: 100%; max-height: none; overflow: visible; }
.tbw-p2str { flex: 0 0 calc(var(--k) * var(--str, 36) * 1px); width: max(1px, calc(var(--k) * 3px)); background: linear-gradient(#b08d57, #c9a86a 60%, #b08d57); }
.tbw-pager { position: relative; flex: 1 1 auto; display: flex; align-items: center; justify-content: space-between; width: 100%; padding-top: calc(var(--k) * 14px); }
.tbw-p2tag .tbw-p2paper { position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at 50% calc(var(--k) * 14px), #e9dcc6 0 calc(var(--k) * 4px), #b08d57 calc(var(--k) * 4.2px) calc(var(--k) * 6px), transparent calc(var(--k) * 6.4px)), #fbf4e8;
  clip-path: polygon(16% 0, 84% 0, 100% 24%, 100% 100%, 0 100%, 0 24%);
  box-shadow: inset 0 0 0 calc(var(--k) * 3px) rgba(176, 141, 87, .65), inset 0 0 0 calc(var(--k) * 7px) #fbf4e8, inset 0 0 0 calc(var(--k) * 8px) rgba(176, 141, 87, .35), inset 0 calc(var(--k) * -10px) calc(var(--k) * 14px) rgba(120, 90, 60, .12); }
.tbw-pgbtn, .tbw-pglab { position: relative; color: var(--tbw-ink); }
.tbw-pgbtn { all: unset; position: relative; box-sizing: border-box; display: grid; place-items: center; width: 30%; height: 100%; color: var(--tbw-ink);
  font: 500 max(16px, calc(var(--k) * 62px)) / 1 'EB Garamond', serif; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
.tbw-pgbtn::after { content: ''; position: absolute; left: 50%; top: 50%; width: max(100%, 44px); height: max(100%, 44px); transform: translate(-50%, -50%); }
.tbw-pgbtn:focus-visible { outline: 2px solid var(--tbw-gilt-ink); outline-offset: 1px; border-radius: 3px; }
.tbw-pgbtn.is-off { color: rgba(58, 46, 40, .38); font-weight: 400; cursor: default; }
.tbw-pglab { font: italic 500 max(11px, calc(var(--k) * 34px)) / 1 'EB Garamond', serif; white-space: nowrap; }
/* screen-reader status after a turn */
.tbw-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* the turn: the page's still copy fades over the other page, 420 ms (instant with reduced motion: no copy at all) */
.tbw-xfade.is-turn { transition: opacity .26s cubic-bezier(.4, 0, .2, 1); }   /* r20: after its words have left (js turnWords) */
/* v285.1 (caps fit): a tag that has fallen back to Cormorant sets its role without the letter-spacing (long roles stay inside
   the gilt rule on seven and eight tags at 360) */
.tbw-pp.is-alt2 .tbw-pprole { letter-spacing: 0; }
