﻿/* Wedding portal - 紅白 (crimson and white), simple mizuhiki frames. */

@font-face {
  font-family: "Mobo";
  src: url("fonts/Mobo-Regular.woff2") format("woff2");
  font-weight: 100 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Mobo";
  src: url("fonts/Mobo-Bold.woff2") format("woff2");
  font-weight: 600 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --font: "Mobo", "Noto Sans JP", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic", "Yu Gothic UI", sans-serif;
  --primary: #c41e3a;
  --primary-dark: #9b1730;
  --grad: linear-gradient(165deg, #9b1730 0%, #c41e3a 52%, #e8a0a8 100%);
  --bg: #fff8f6;
  --card: #ffffff;
  --text: #2a1f1f;
  /* HIG contrast: darkened from #8a6e6e so 13px secondary text clears
     4.5:1 on the warm white surfaces. */
  --muted: #7a6060;
  --border: #f0c8c8;
  /* HIG hairline: crimson-tinted rgba for in-card row separators. */
  --hairline: rgba(196, 30, 58, .14);
  /* iOS tinted-button fill (8% crimson). */
  --tint: rgba(196, 30, 58, .08);
  --danger: #c41e3a;
  --gold: #c4a06a;
  --gold-soft: rgba(196, 160, 106, .35);
  --accent: #fff6f4;
  --ok: #6a7d5c;
  --warn: #bd8a4c;
  --aka: #c41e3a;
  --shiro: #ffffff;
  --shadow: 0 1px 2px rgba(80, 30, 40, .05), 0 8px 20px rgba(80, 30, 40, .07);
  /* HIG corner scale: cards 14 / buttons & inputs 10 / pills 999 /
     modals 16 (continuous-corner feel). */
  --radius: 14px;
}

* { box-sizing: border-box; }

html {
  scroll-padding-top: 88px;
  width: 100%;
  max-width: 100%;
  /* clip (not hidden): hidden turns ancestors into scroll containers,
     which breaks position:sticky (the envelope scene). hidden stays
     as a fallback for old browsers. */
  overflow-x: hidden;
  overflow-x: clip;
  overscroll-behavior-x: none;
  -webkit-text-size-adjust: 100%;
}

img, video, canvas, svg, iframe { max-width: 100%; }
input, select, textarea { max-width: 100%; }

body {
  margin: 0;
  width: 100%;
  max-width: 100%;
  overflow-x: hidden;
  overflow-x: clip;
  overscroll-behavior-x: none;
  /* One typeface for the whole site: Noto Sans JP for a lighter,
     popper gothic than the old mincho. */
  font-family: var(--font);
  letter-spacing: .01em;
  background-color: var(--bg);
  /* Washi paper: soft red glows in the corners over a faint seigaiha
     (blue-sea-wave) arc pattern - a classic wa motif, kept whisper
     light so text always wins. */
  background-image:
    radial-gradient(900px 380px at 92% -8%, rgba(196, 30, 58, .08), transparent 58%),
    radial-gradient(700px 340px at -8% 4%, rgba(196, 30, 58, .06), transparent 52%),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='80' height='40' viewBox='0 0 80 40'><g fill='none' stroke='%23c41e3a' stroke-opacity='.07' stroke-width='1.2'><path d='M-20 40 a20 20 0 0 1 40 0'/><path d='M-12 40 a12 12 0 0 1 24 0'/><path d='M20 40 a20 20 0 0 1 40 0'/><path d='M28 40 a12 12 0 0 1 24 0'/><path d='M60 40 a20 20 0 0 1 40 0'/><path d='M68 40 a12 12 0 0 1 24 0'/><path d='M0 20 a20 20 0 0 1 40 0'/><path d='M8 20 a12 12 0 0 1 24 0'/><path d='M40 20 a20 20 0 0 1 40 0'/><path d='M48 20 a12 12 0 0 1 24 0'/><path d='M-40 20 a20 20 0 0 1 40 0'/><path d='M-32 20 a12 12 0 0 1 24 0'/></g></svg>");
  background-size: auto, auto, 80px 40px;
  color: var(--text);
  /* HIG type base (plan A, chosen after a side-by-side comparison):
     iOS Body = 17pt with the standard 22pt leading (1.47). The rest
     of the scale follows: Title 28 / Headline 20 / Subhead 15 /
     Footnote 13. */
  font-size: 17px;
  line-height: 1.47;
  min-height: 100vh;
}

h1, h2, h3, h4, h5, .brand {
  font-family: var(--font);
}

button, input, select, textarea { font-family: inherit; }

.hidden { display: none !important; }

/* ---------- login ---------- */
.login-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--grad);
  padding: 16px;
}
.login-card {
  background: rgba(255, 255, 255, .97);
  backdrop-filter: blur(10px);
  border-radius: 12px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  padding: 34px 30px;
  width: 100%;
  max-width: 390px;
}
.login-card h1 {
  margin: 0 0 22px; font-size: 24px; text-align: center;
  color: var(--primary-dark); letter-spacing: .14em;
}
.btn.small.wide { width: 100%; margin-top: 8px; }
.login-card label { display: block; margin-bottom: 14px; font-size: 13px; color: var(--muted); }
.login-card input {
  display: block; width: 100%; margin-top: 5px;
  /* 16px so iOS never auto-zooms on the login fields (a <16px input
     makes Safari zoom in on focus and STAY zoomed after login). */
  padding: 11px 12px; border: 1px solid var(--border); border-radius: 10px; font-size: 16px;
  background: #fff;
  transition: border-color .15s, box-shadow .15s;
}
.login-card input:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(196, 30, 58, .12);
}
.lang-row { margin-top: 18px; text-align: center; }
.demo-hint {
  margin: 16px 0 0; padding: 10px 12px;
  background: var(--accent); border-radius: 8px;
  font-size: 12px; color: var(--muted); line-height: 1.6;
  border: 1px dashed rgba(196, 160, 106, .5);
}
.hub-wrap {
  min-height: 100vh;
  padding: 20px 16px 48px;
}
.hub-inner { max-width: 760px; margin: 0 auto; }
.hub-top {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 10px; margin-bottom: 18px;
}
.hub-lead { color: var(--muted); line-height: 1.7; margin: 0 0 22px; }
.hub-grid { display: grid; gap: 16px; }
.hub-card .tpl-ver {
  font-size: 11px; color: var(--muted); letter-spacing: .06em;
}
.hub-card h3 { margin: 4px 0 8px; font-size: 20px; color: var(--primary-dark); }
.hub-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.hub-back { flex: 0 0 auto; }
.demo-badge {
  font-size: 10px; font-weight: 700; letter-spacing: .08em;
  color: #fdfaf2; background: var(--danger);
  border-radius: 999px; padding: 2px 8px; margin-left: 8px;
  vertical-align: middle; font-family: inherit;
}

/* ---------- header ---------- */
header {
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 14px;
  padding: 10px 18px; position: sticky; top: 0; z-index: 10;
  flex-wrap: wrap;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow-x: hidden;
}
#app-screen, #hub-screen, #login-screen {
  width: 100%;
  max-width: 100%;
  overflow-x: hidden;
  overflow-x: clip;
  min-width: 0;
}
.brand {
  font-weight: 700; font-size: 17px; letter-spacing: .18em;
  color: var(--primary-dark);
  border-left: 3px solid var(--aka); padding-left: 10px;
}
#main-nav { display: flex; gap: 2px; flex: 1; flex-wrap: wrap; }
.nav-btn {
  border: none; background: transparent; padding: 10px 16px;
  min-height: 44px;
  /* HIG selection: the active tab gets a rounded pill highlight
     (iOS sidebar/segment style) instead of an underline. */
  border-radius: 999px; cursor: pointer; font-size: 15px; color: var(--muted);
  font-family: var(--font);
  letter-spacing: .1em;
  transition: background .15s, color .15s, transform .15s;
}
.nav-btn:hover { background: var(--accent); color: var(--primary-dark); }
.nav-btn:active { transform: scale(.97); }
.nav-btn.active {
  background: rgba(196, 30, 58, .10); color: var(--primary-dark); font-weight: 700;
}
.header-right { display: flex; align-items: center; gap: 10px; }
.user-name { font-size: 13px; color: var(--muted); }
.lang-select {
  border: 1px solid var(--border); border-radius: 6px;
  padding: 5px 10px; font-size: 12px; background: #fff; color: var(--text); cursor: pointer;
}

/* ---------- layout ---------- */
main { max-width: 1000px; margin: 0 auto; padding: 24px 18px 70px; min-width: 0; }
.view, .card, .admin-box, .home-hero, .invite-card { max-width: 100%; min-width: 0; }
/* HIG motion: the incoming tab fades in and rises slightly (the
   display:none -> block flip restarts the animation on each switch). */
@keyframes view-enter {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
.view.active { animation: view-enter .22s ease-out; }
.view h2 {
  /* HIG type scale (A): screen title 28px (iOS Title 1). */
  font-size: 28px; margin: 0; letter-spacing: .12em;
  color: var(--primary-dark);
  border-bottom: none; padding-bottom: 0;
}
.wa-title {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  margin: 4px 0 18px;
}
.wa-title h2, .wa-title h3 {
  margin: 0; display: inline-flex; align-items: center; gap: 4px;
}
.wa-sec {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  /* HIG type scale (A): section heading 20px/600 (iOS Headline+);
     32px above = section rhythm. */
  font-size: 20px; font-weight: 600; margin: 32px 0 12px; letter-spacing: .12em;
  color: var(--primary-dark);
}
.wa-sec .mizu { flex: 0 0 auto; }
.mizu {
  display: inline-flex; width: 72px; height: 36px;
  overflow: hidden;
  /* Mizuhiki strands (helpers.js): parallel thin cords through a
     plum knot. --mizu-a = red strands, --mizu-b = the gold accent
     strand woven through the middle. */
  --mizu-a: #c41e3a;
  --mizu-b: #c9a24b;
}
.mizu.knot { width: 34px; height: 34px; }
.mizu.ume { display: block; width: 52px; height: 52px; margin: 0 auto; }
.mizu.bar { display: block; width: min(420px, 92%); height: 44px; margin: 0 auto; }
.mizu.gold { --mizu-a: #b8944a; --mizu-b: #e8cf8a; }
.mizu svg { width: 100%; height: 100%; }
.mizu-strand {
  fill: none; stroke-linecap: round; stroke-linejoin: round;
}
.mizu-c1, .mizu-c3 { stroke: var(--mizu-a); }
.mizu-c2 { stroke: var(--mizu-b); }
.home-hero .mizu { --mizu-a: rgba(255,255,255,.95); --mizu-b: #ecd489; margin-bottom: 4px; }
.home-hero .mizu.gold { --mizu-a: #f0d78c; --mizu-b: rgba(255,255,255,.92); }
.view h3 { font-size: 20px; font-weight: 600; margin: 24px 0 8px; letter-spacing: .04em; }
.card, .home-panel, .host-card, .mood-fig, .album-card, .q-modal-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.card {
  /* 8pt rhythm (A): 24px inside, 16px between cards. */
  padding: 24px; margin-bottom: 16px;
  transition: transform .15s, box-shadow .15s;
}
.card:hover { transform: translateY(-1px); }
.card-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.card-head strong { font-size: 17px; }
.card-head .meta { flex: 1; }
.card-body { font-size: 17px; margin: 8px 0 4px; line-height: 1.6; }
/* Secondary text = iOS Subheadline 15px (was 13px footnote). */
.meta { font-size: 15px; color: var(--muted); }
.note { font-size: 15px; color: var(--muted); }
.error { color: var(--danger); font-size: 15px; }

/* ---------- buttons / forms ----------
   HIG button roles: default = iOS "tinted" (8% crimson fill, crimson
   text, no border), .primary = crimson filled (44px min height),
   .danger keeps its existing treatment. Every button has a press
   state (:active): scale .97 + a slight dim over 150ms. */
.btn {
  border: none; background: var(--tint); color: var(--primary-dark);
  padding: 10px 18px; min-height: 44px; border-radius: 10px;
  cursor: pointer; font-size: 17px;
  letter-spacing: .04em;
  transition: background .15s, transform .15s, box-shadow .15s, filter .15s;
}
.btn:hover { background: rgba(196, 30, 58, .13); }
.btn:active { transform: scale(.97); filter: brightness(.95); }
.btn.primary {
  background: var(--primary); border: none; color: #fdfaf2; font-weight: 600;
  letter-spacing: .06em;
  box-shadow: 0 3px 10px rgba(155, 23, 48, .28);
}
.btn.primary:hover { background: var(--primary-dark); }
.btn.danger { color: var(--danger); border: 1px solid rgba(181, 68, 44, .45); background: #fff; }
.btn.danger:hover { background: #faf0ec; }
.btn.small { padding: 6px 14px; min-height: 36px; font-size: 14px; border-radius: 8px; }
.btn.wide { width: 100%; margin-top: 8px; padding: 12px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

label { display: block; margin: 12px 0; font-size: 15px; color: var(--muted); }
label input, label select, label textarea {
  display: block; width: 100%; margin-top: 5px;
  /* 44px tap target, 17px text (never under 16px: iOS zoom). */
  min-height: 44px;
  padding: 11px 14px; border: 1px solid var(--border); border-radius: 10px;
  font-size: 17px; font-family: inherit; background: #fff;
  transition: border-color .15s, box-shadow .15s;
}
label input:focus, label select:focus, label textarea:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(196, 30, 58, .1);
}
/* One placeholder grey everywhere. */
input::placeholder, textarea::placeholder { color: #b3a6a6; opacity: 1; }
textarea { min-height: 72px; resize: vertical; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
/* "Pick several people" box in the schedule form: full grid width. */
.bulk-pick { grid-column: 1 / -1; margin: 4px 0 8px; }
.bulk-pick summary { cursor: pointer; font-size: 13px; }
.bulk-group { margin: 6px 0 2px; padding-left: 4px; }
.bulk-group .aud-list { padding-left: 18px; }

.admin-box {
  background: linear-gradient(180deg, rgba(196, 30, 58, .03), transparent),
              var(--card);
  border: 1px dashed rgba(196, 30, 58, .35);
  border-radius: var(--radius); padding: 13px 18px; margin-bottom: 18px;
}
.admin-box summary { cursor: pointer; font-size: 14px; color: var(--primary-dark); font-weight: 600; }
.admin-box .btn { margin-top: 8px; }

/* ---------- home / countdown ---------- */
.home-hero {
  text-align: center; padding: 52px 20px;
  background: var(--grad);
  color: #fff; border-radius: 12px; margin-bottom: 18px;
  box-shadow: var(--shadow);
  position: relative; overflow: hidden;
  /* Kakejiku-style mounting: a double gold outer frame with a fine
     white inner hairline (::before below). */
  border: 3px double var(--gold);
}
.home-hero::before {
  content: ""; position: absolute; inset: 9px; z-index: 1;
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 8px; pointer-events: none;
}
/* With a photo set the hero becomes the main visual of the invitation. */
.home-hero.has-photo { padding: 92px 20px; }
.home-hero::after {
  content: ""; position: absolute; inset: 0;
  /* Soft top light only - no pattern over the photo (the seigaiha
     overlay read as fish scales on portraits, so it was removed). */
  background:
    radial-gradient(700px 240px at 50% 0%, rgba(255, 255, 255, .10), transparent 65%);
  pointer-events: none;
}
/* Overrides `.view h2`, which would paint this dark on the dark hero. */
.home-hero h2 {
  margin: 0 0 14px; padding-bottom: 14px;
  font-size: 30px; letter-spacing: .18em;
  color: #fff; border-bottom: none;
  position: relative;
}
/* Thin gold rule under the couple's names. */
.home-hero h2::after {
  content: ""; position: absolute; left: 50%; bottom: 0;
  transform: translateX(-50%);
  width: 96px; height: 2px; background: #fff;
  opacity: .85;
}
.home-hero .note { color: rgba(253, 250, 242, .85); }
.countdown-label { font-size: 16px; opacity: .92; margin: 4px 0 12px; letter-spacing: .1em; }
.countdown { display: flex; justify-content: center; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.cd-num {
  font-size: 52px; font-weight: 700; line-height: 1.1;
  font-family: var(--font);
  font-variant-numeric: tabular-nums;
}
.cd-unit { font-size: 15px; opacity: .85; margin-right: 12px; }
.countdown-date { font-size: 13px; opacity: .8; margin-top: 12px; letter-spacing: .08em; }

/* ---------- board / polls ---------- */
.poll { background: var(--accent); border-radius: 8px; padding: 14px; margin-top: 12px; min-width: 0; max-width: 100%; overflow: hidden; }
.poll-q { font-size: 14px; font-weight: 600; margin: 0 0 10px; }
.poll-choices { display: flex; gap: 8px; flex-wrap: wrap; min-width: 0; }
.poll-btn {
  border: 1px solid rgba(196, 30, 58, .5); background: #fff; color: var(--primary-dark);
  padding: 7px 15px; border-radius: 6px; cursor: pointer; font-size: 14px;
  transition: background .15s, color .15s;
}
.poll-btn:hover { background: rgba(196, 30, 58, .06); }
.poll-btn:active { transform: scale(.97); }
.poll-btn.chosen { background: var(--primary-dark); border: none; color: #fdfaf2; font-weight: 600; }
.poll-count { font-size: 12px; opacity: .8; margin-left: 4px; }
.poll-people { margin: 0 0 10px; }
.poll-people-label { display: block; font-size: 13px; font-weight: 600; margin: 0 0 6px; }
.poll-people-list { display: flex; flex-direction: column; gap: 2px; }
.resp-list { margin: 8px 0 0; padding-left: 18px; font-size: 13px; }

/* ---------- calendar: whereabouts board ---------- */
.where-board {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 20px; margin-bottom: 16px;
  box-shadow: var(--shadow);
}
.where-board h3 { margin: 0 0 12px; font-size: 15px; }
.where-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 10px;
}
.where-card {
  border-radius: 8px; padding: 10px 12px;
  display: flex; flex-direction: column; gap: 2px;
  border: 1px solid var(--border);
}
.where-card.stay { background: #eef2e4; border-color: #cdd8b8; }
.where-card.move { background: #f8ece4; border-color: #e5c9b8; }
.where-card.event { background: #e7edf1; border-color: #c8d6de; }
.where-card.home { background: #f4f1e8; border-color: var(--border); }
/* Read-only name cell in the chart editor rows (registry owns names). */
.fam-name-static { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.fam-name-static strong { font-size: 14px; }
.where-name { font-weight: 700; font-size: 14px; }
.where-loc { font-size: 13px; }
.where-group { margin-top: 10px; }
.where-group h4 { margin: 0 0 6px; font-size: 13px; color: var(--primary-dark); }
.loc-frame {
  border: 1.5px solid var(--border); border-radius: 10px;
  padding: 10px 12px; margin: 10px 0;
}
.loc-frame.stay-frame { border-color: #b8c99c; background: #f6f8ee; }
.loc-frame.move-frame { border-color: #dcb49b; background: #faf2ea; }
/* Home bases share the same "same place = same frame" treatment. */
.loc-frame.home-frame { border-color: #d8d0ba; background: #f8f5ec; }
/* Collapsed by default: the board shows each place with a head-count
   pill; tapping the summary reveals the names. */
details.loc-frame > summary {
  cursor: pointer; list-style: none; user-select: none;
}
details.loc-frame > summary::-webkit-details-marker { display: none; }
details.loc-frame > summary h4 {
  margin: 0; display: flex; align-items: center; gap: 8px;
}
details.loc-frame[open] > summary h4 { margin-bottom: 8px; }
.loc-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 24px; height: 24px; padding: 0 7px;
  border-radius: 999px; background: var(--primary-dark); color: #fdfaf2;
  font-size: 12px; font-weight: 700;
}
details.loc-frame > summary::after {
  content: "▸"; margin-left: auto; color: var(--muted); font-size: 12px;
}
details.loc-frame[open] > summary::after { content: "▾"; }
details.loc-frame > summary { display: flex; align-items: center; }
details.loc-frame > summary h4 { flex: 1; }
.loc-frame h4 { margin: 0 0 8px; font-size: 14px; }
.home-list { margin-top: 12px; }
.home-list h4 { margin: 0 0 6px; font-size: 13px; color: var(--muted); }
.home-chip {
  display: inline-block; background: #f2eee1; border: 1px solid var(--border);
  border-radius: 999px; padding: 3px 12px; margin: 2px 6px 2px 0; font-size: 12px;
}
.where-date {
  margin-left: 10px; padding: 3px 8px; border: 1px solid var(--border);
  border-radius: 6px; font-size: 13px; font-family: inherit;
}

/* ---------- calendar: toolbar / segmented control ---------- */
.cal-toolbar {
  display: flex; justify-content: space-between; align-items: center;
  gap: 10px; flex-wrap: nowrap; margin-bottom: 12px;
}
.cal-toolbar .seg { flex: 0 1 auto; min-width: 0; }
.cal-toolbar-actions { display: flex; gap: 8px; flex: 0 0 auto; align-items: center; }
.cal-toolbar #trip-add-open, .cal-toolbar #guest-input-open { flex: 0 0 auto; white-space: nowrap; }
.guest-sched-top { margin: 0 0 12px; }

.guest-sched-lead { color: var(--muted); margin: 0 0 10px; line-height: 1.55; }
.guest-sched-members { font-size: 13px; color: var(--muted); margin: 0 0 14px; }
.guest-sched-toolbar {
  display: flex; justify-content: flex-end; align-items: center;
  gap: 10px; margin-bottom: 12px;
}
.guest-sched-toolbar-bottom { margin: 16px 0 8px; }
.guest-trip-fab { display: none; }
@media (max-width: 640px) {
  .guest-sched-toolbar-top { display: none; }
  .guest-trip-fab {
    display: flex; align-items: center; justify-content: center;
    position: fixed; right: 22px; bottom: 88px; z-index: 89;
    width: 56px; height: 56px; border-radius: 50%;
    border: 3px solid #fff;
    background: var(--primary-dark); color: #fff;
    font-size: 28px; line-height: 1; cursor: pointer;
    box-shadow: 0 8px 22px rgba(90, 30, 30, .28);
  }
}
.bulk-group-name {
  margin: 8px 0 4px; font-size: 13px; font-weight: 700; color: var(--muted);
}
.lodge-slide {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  transition: grid-template-rows .28s ease;
}
.lodge-slide > .lodge-request { overflow: hidden; min-height: 0; }
.lodge-slide.is-open { grid-template-rows: 1fr; }
.prog-jump .btn[disabled] { opacity: .55; cursor: default; }
.home-panel.guest-sched-cta { cursor: pointer; }
.home-welcome {
  margin: 8px 16px 18px; text-align: center; line-height: 1.7;
  color: var(--ink); font-size: 15px;
}
.env-open-cue {
  position: absolute; left: 0; right: 0; bottom: 14%; z-index: 8;
  margin: 0; text-align: center; font-size: 16px; font-weight: 700;
  color: var(--primary-dark);
  opacity: min(1, max(0, calc(1 - var(--p, 0) * 5)));
  pointer-events: none;
}
.invite-sched-cta { margin: 18px 0 8px; text-align: center; }
.prog-jump { display: flex; justify-content: flex-end; margin: 0 0 14px; }
.pending-kicker { font-size: 13px; font-weight: 700; margin: 10px 0 4px; color: var(--primary-dark); }
.pending-block + .pending-block { margin-top: 8px; }
.rsvp-side-events { margin: 16px 0 8px; }
.rsvp-side-events h5 { margin: 0 0 8px; }
.rsvp-side-event { margin: 10px 0 16px; }
.rsvp-side-event > .meta { display: block; }
.ev-person { margin: 0 0 8px; }
.ev-other-row { margin: 0 0 8px; }
.ev-home-desc {
  display: block; margin: 6px 0 8px; font-size: 13px; line-height: 1.6;
  color: var(--ink); white-space: pre-wrap;
}
.home-item .ev-home-desc { color: var(--muted); margin: 2px 0 0; }
.who-banner {
  background: rgba(181, 68, 44, .06); border: 1px solid rgba(181, 68, 44, .28);
  border-radius: 10px; padding: 10px 12px; margin: 0 0 12px;
}
.who-banner-msg { margin: 0 0 6px; font-weight: 600; }
.who-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.who-label { font-size: 12px; color: var(--muted); }
.who-chip {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  background: #fff; border: 1px solid var(--border); font-size: 13px;
}
.lodge-panel { margin: 0 0 18px; }
.lodge-card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px; margin-bottom: 12px;
  box-shadow: var(--shadow);
}
.lodge-lead { color: var(--muted); line-height: 1.6; margin: 0 0 10px; }
.lodge-assigned { margin: 0 0 12px; padding-left: 0; list-style: none; line-height: 1.7; }
.lodge-person { margin: 0 0 10px; }
.lodge-person:last-child { margin-bottom: 0; }
.lodge-person-name { font-weight: 700; color: var(--text); margin: 0 0 2px; }
.lodge-stays { margin: 0; padding-left: 1.2em; }
.lodge-need-btns { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.lodge-request { margin-top: 12px; }
.lodge-admin-row { padding: 8px 0; border-bottom: 1px solid var(--hairline); }
.lodge-admin-row:last-child { border-bottom: none; }
.seg {
  display: inline-flex; background: var(--accent);
  border-radius: 8px; padding: 3px; gap: 2px;
}
.seg-btn {
  border: none; background: transparent; padding: 6px 16px;
  border-radius: 6px; cursor: pointer; font-size: 13px; color: var(--muted);
  transition: background .15s, color .15s, transform .15s;
}
.seg-btn:active { transform: scale(.97); }
.seg-btn.on { background: #fffdf7; color: var(--primary-dark); font-weight: 600; box-shadow: 0 1px 4px rgba(60, 50, 30, .18); }
.cal-nav { display: flex; align-items: center; gap: 10px; }
.trip-list-head h3 { margin: 18px 0 8px; }
.trip-month-seg { flex-wrap: wrap; max-width: 100%; }

/* ---------- schedule: datetime fields / table / gantt ---------- */
.trip-dt { grid-column: 1 / -1; }
.trip-dt-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 4px;
}
.trip-dt-row input[type="date"] { width: auto; min-width: 10em; }
.tr-pickup-lab { display: flex; align-items: center; gap: 8px; min-height: 44px; }
.tr-pickup-lab input { width: auto; min-height: 0; }

.trip-table-tools { display: flex; flex-direction: column; gap: 8px; margin: 0 0 12px; }
.trip-table-tools .seg { display: flex; flex-wrap: wrap; width: 100%; }
.trip-table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; margin-bottom: 16px; }
.trip-table .trip-sort,
.trip-grid .trip-sort {
  border: 0; background: transparent; padding: 0; margin: 0;
  font: inherit; color: inherit; cursor: pointer; text-align: left;
  min-height: 0;
}
.trip-table .row-actions { white-space: nowrap; }

.trip-grid {
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
  background: var(--card);
  box-shadow: var(--shadow);
  margin-bottom: 16px;
}
.trip-grid-head, .trip-grid-row {
  display: grid;
  grid-template-columns: minmax(7em, .9fr) minmax(0, 1.7fr) minmax(7.2em, .8fr) minmax(5.2em, .55fr) 18px;
  gap: 8px 12px;
  align-items: center;
  padding: 11px 14px;
}
.trip-grid-head {
  background: var(--accent);
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}
.trip-grid-row {
  width: 100%;
  border: 0;
  border-top: 1px solid var(--hairline);
  background: transparent;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  min-height: 56px;
}
.trip-grid-row:hover, .trip-grid-row:focus-visible { background: #faf6ee; }
.trip-grid-who { font-weight: 600; overflow-wrap: anywhere; line-height: 1.35; }
.trip-grid-plan {
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px 8px;
}
.trip-kind {
  display: inline-flex; align-items: center;
  border-radius: 999px; padding: 2px 8px;
  font-size: 11px; font-weight: 700; letter-spacing: .04em;
  white-space: nowrap;
}
.trip-kind.move { background: #4f7cac; color: #f4f8fc; }
.trip-kind.stay { background: #5d8a5a; color: #f3f8f2; }
.trip-sum { font-weight: 600; overflow-wrap: anywhere; }
.trip-chip {
  display: inline-flex; border-radius: 999px; padding: 2px 8px;
  font-size: 11px; white-space: nowrap;
  background: #f3e6c8; color: var(--primary-dark);
}
.trip-chip.pickup { background: #f0d9c8; }
.trip-note-preview {
  flex-basis: 100%;
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.trip-grid-when {
  font-variant-numeric: tabular-nums;
  font-size: 13px; line-height: 1.4;
  white-space: nowrap;
}
.trip-grid-when .meta { display: block; white-space: nowrap; }
.trip-grid-arr { font-size: 12px; color: var(--muted); white-space: nowrap; }
.trip-grid-go {
  color: var(--muted); font-size: 18px; line-height: 1;
  text-align: center;
}
.trip-table-tools .seg.trip-sort-bar { display: none; }
.trip-modal-actions {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 0 16px 4px;
}
.trip-form-card {
  width: 100%;
  max-width: min(520px, calc(100vw - 24px));
  max-height: min(88vh, 760px);
  overflow: auto;
}
.trip-form-body { padding: 4px 0 16px; }
.trip-form-card .form-grid,
.trip-form-card .aud-box,
.trip-form-card .trip-form-actions { padding: 0 16px; }
.trip-form-card .bulk-pick { margin-top: 0; }
.trip-form-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-top: 8px;
}
.trip-form-actions .btn { margin-top: 0; }
@media (max-width: 720px) {
  .trip-table-tools .seg.trip-sort-bar { display: flex; flex-wrap: wrap; width: 100%; }
  .trip-grid-head { display: none; }
  .trip-grid-row {
    grid-template-columns: 1fr auto 18px;
    grid-template-areas:
      "who arr go"
      "plan plan plan"
      "when when when";
    gap: 4px 10px;
    padding: 12px 14px;
  }
  .trip-grid-who { grid-area: who; }
  .trip-grid-plan { grid-area: plan; }
  .trip-grid-when { grid-area: when; }
  .trip-grid-arr { grid-area: arr; }
  .trip-grid-go { grid-area: go; }
}

.gantt-wrap {
  width: 100%; max-width: 100%; overflow-x: auto;
  border: 1px solid var(--border); border-radius: 12px;
  background: #fffdf7; box-shadow: var(--shadow); margin-bottom: 16px;
  -webkit-overflow-scrolling: touch;
}
.gantt-inner { min-width: calc(132px + var(--days, 3) * 72px); }
.gantt-row {
  display: grid; grid-template-columns: 132px 1fr;
  border-bottom: 1px solid var(--hairline); min-height: 44px;
}
.gantt-row:last-child { border-bottom: none; }
.gantt-head { position: sticky; top: 0; z-index: 2; background: var(--accent); }
.gantt-name {
  position: sticky; left: 0; z-index: 1;
  padding: 8px 10px; background: #fffdf7;
  font-weight: 700; font-size: 13px; white-space: nowrap;
  border-right: 1px solid var(--border);
  display: flex; align-items: center; gap: 6px;
}
.gantt-head .gantt-name { background: var(--accent); }
.gantt-name.is-indent { padding-left: 22px; font-weight: 500; color: var(--muted); }
.gantt-group { cursor: pointer; }
.gantt-group:hover .gantt-name { background: var(--accent); }
.gantt-track {
  position: relative;
  min-width: calc(var(--days, 3) * 72px);
  background-image:
    repeating-linear-gradient(
      to right,
      transparent 0,
      transparent calc(100% / var(--days, 3) / 4 - 1px),
      rgba(80, 60, 40, .06) calc(100% / var(--days, 3) / 4 - 1px),
      rgba(80, 60, 40, .06) calc(100% / var(--days, 3) / 4)
    ),
    repeating-linear-gradient(
      to right,
      transparent 0,
      transparent calc(100% / var(--days, 3) - 1px),
      var(--border) calc(100% / var(--days, 3) - 1px),
      var(--border) calc(100% / var(--days, 3))
    );
}
.gantt-days {
  display: grid; grid-template-columns: repeat(var(--days, 3), minmax(72px, 1fr));
  min-height: 48px;
}
.gantt-day {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; font-size: 12px; color: var(--muted); font-weight: 600;
  border-right: 1px solid var(--border);
}
.gantt-day.is-today { color: var(--danger); }
.gantt-day.is-wedding { background: rgba(181, 68, 44, .08); color: var(--primary-dark); }
.gantt-day-n { font-size: 15px; line-height: 1.1; }
.gantt-wed { font-size: 10px; letter-spacing: .04em; }
.gantt-bar {
  position: absolute; height: 26px; padding: 0 8px;
  border: 0; border-radius: 6px; cursor: pointer;
  font-size: 11px; font-weight: 700; line-height: 26px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-align: left; box-shadow: 0 1px 3px rgba(40, 30, 20, .16);
}
.gantt-bar.move { background: #4f7cac; color: #f4f8fc; }
.gantt-bar.stay { background: #5d8a5a; color: #f3f8f2; }
.gantt-bar:hover { filter: brightness(1.08); }

.trip-modal {
  position: fixed; inset: 0; z-index: 120;
  background: rgba(80, 20, 28, .4); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.trip-modal.hidden, .trip-modal[hidden] { display: none; }
.trip-modal-card {
  width: 100%; max-width: 440px; max-height: 80vh; overflow: auto;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 16px; box-shadow: var(--shadow); padding: 0 0 16px;
}
.trip-modal-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 12px 10px 16px; border-bottom: 1px solid var(--border);
}
.trip-modal-bar h4 { margin: 0; flex: 1; font-size: 16px; }
.trip-modal-x {
  width: 36px; height: 36px; border: 0; border-radius: 8px;
  background: transparent; font-size: 22px; cursor: pointer;
}
.trip-modal-body { padding: 12px 16px; display: flex; flex-direction: column; gap: 8px; }
.trip-dl { display: grid; grid-template-columns: 7.5em 1fr; gap: 6px 12px; font-size: 14px; }
.trip-dl dt { color: var(--muted); }
.trip-dl dd { margin: 0; overflow-wrap: anywhere; }

/* ---------- calendar: month grid ---------- */
.cal-grid {
  display: grid; grid-template-columns: repeat(7, 1fr);
  gap: 2px; background: var(--border); border: 1px solid var(--border);
  border-radius: 12px; overflow: hidden; margin-bottom: 16px;
  box-shadow: var(--shadow);
}
.cal-wd { background: var(--accent); text-align: center; font-size: 12px; padding: 7px 0; color: var(--muted); font-weight: 600; }
.cal-cell { background: #fffdf7; min-height: 88px; padding: 5px; font-size: 11px; }
.cal-cell.empty { background: #f7f4ea; }
.cal-cell.today { outline: 2px solid var(--danger); outline-offset: -2px; background: #fdfaf1; }
.cal-day { font-size: 12px; font-weight: 700; display: block; margin-bottom: 3px; }
.chip {
  display: block; border-radius: 4px; padding: 2px 5px; margin-bottom: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip.move { background: #f6e3da; color: #8a3d28; }
.chip.stay { background: #e8eddc; color: #4a5d3a; }
.chip.event { background: #dde7ec; color: #23485e; font-weight: 700; }
.chip.pevent { background: #e9e2ef; color: #5b4a70; }

/* ---------- pending RSVP banner ---------- */
.pending-box {
  background: linear-gradient(180deg, rgba(181, 68, 44, .06), transparent), var(--card);
  border: 1px solid rgba(181, 68, 44, .45);
  border-radius: var(--radius); padding: 20px; margin-bottom: 16px;
  box-shadow: var(--shadow);
}
.pending-box h3 { margin: 0 0 8px; font-size: 15px; }
.pending-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 0; border-bottom: 1px solid var(--hairline);
  min-width: 0;
}
.pending-row:last-child { border-bottom: none; }
.pending-row .meta { flex: 1 1 100%; min-width: 0; }
.pending-btns { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; }
.pending-btns .btn { flex: 1 1 0; min-width: 0; }

/* ---------- program (schedule of the day) ---------- */
.prog-day {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 20px; margin-bottom: 16px;
  box-shadow: var(--shadow);
}
.prog-day.prog-today { border-color: var(--danger); }
.prog-day h3 { margin: 0 0 10px; font-size: 15px; }
.prog-item {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 9px 0; border-bottom: 1px solid var(--hairline);
}
.prog-item:last-child { border-bottom: none; }
.prog-time {
  min-width: 88px; font-weight: 700; font-variant-numeric: tabular-nums;
  font-family: var(--font);
  color: var(--primary-dark); font-size: 14px;
}
.prog-body { flex: 1; min-width: 0; }
.prog-body .note { margin: 3px 0 0; }

/* ---------- calendar: timeline (gantt) ---------- */
.tl-wrap {
  width: 100%; max-width: 100%; overflow-x: auto;
  border-radius: 12px; box-shadow: var(--shadow); margin-bottom: 16px;
  -webkit-overflow-scrolling: touch;
}
.tl { border-collapse: collapse; width: 100%; background: #fffdf7; font-size: 12px; }
.tl th, .tl td { border: 1px solid var(--border); text-align: center; min-width: 26px; height: 30px; padding: 0; }
.tl th { background: var(--accent); color: var(--muted); font-weight: 600; font-size: 11px; }
.tl-name {
  text-align: left !important; padding: 0 10px !important;
  font-weight: 700; white-space: nowrap; background: #fffdf7;
  position: sticky; left: 0; min-width: 90px !important;
}
.tl-stay { background: #8fac74; }
.tl-move { background: #cf7a55; }
.tl-event { background: #7d92ad; }
.tl-today { box-shadow: inset 2px 0 0 var(--danger), inset -2px 0 0 var(--danger); }

/* ---------- tables ---------- */
.table {
  width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 12px; overflow: hidden; box-shadow: var(--shadow);
}
.table th, .table td { border-bottom: 1px solid var(--border); padding: 10px 12px; text-align: left; vertical-align: top; }
.table tr:last-child td { border-bottom: none; }
.table th { background: var(--accent); font-weight: 600; color: var(--muted); }

/* ---------- events ---------- */
.event-card { border-left: 4px solid var(--primary); }
.rsvp-row { display: flex; gap: 8px; margin: 10px 0; flex-wrap: wrap; }
.rsvp-row .btn { min-width: 0; }

/* ---------- gallery ---------- */
.gallery-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 16px;
}
.gallery-item {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden; margin: 0;
  box-shadow: var(--shadow);
  transition: transform .15s;
}
.gallery-item:hover { transform: translateY(-2px); }
.gallery-item img, .gallery-item video {
  width: 100%; height: 145px; object-fit: cover; display: block; background: #1c1b18;
}
.gallery-item figcaption { padding: 9px 10px; font-size: 12px; display: flex; flex-direction: column; gap: 2px; }
/* Inside an album: one horizontal filmstrip. Photos scroll sideways
   (swipe on phones) instead of opening in a new tab. */
.gallery-strip {
  display: flex; gap: 14px; overflow-x: auto; padding: 4px 2px 12px;
  scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
}
.gallery-strip .gallery-item {
  flex: 0 0 min(74vw, 340px); scroll-snap-align: center;
}
.gallery-strip .gallery-item img, .gallery-strip .gallery-item video {
  height: min(52vw, 240px);
}

/* ---------- home dashboard ---------- */
.home-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px;
}
.home-panel {
  padding: 20px;
  cursor: pointer; transition: transform .15s, border-color .15s;
}
.home-panel:hover { transform: translateY(-2px); }
.home-panel h3 { margin: 0 0 10px; font-size: 17px; }
.home-item { padding: 12px 0; border-bottom: 1px solid var(--hairline); display: flex; flex-direction: column; gap: 2px; }
.home-item:last-child { border-bottom: none; }

/* ---------- free text poll ---------- */
.poll-text-row {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 8px; min-width: 0; width: 100%; max-width: 100%;
}
.poll-text-fields {
  display: flex; flex-direction: column; gap: 8px;
  min-width: 0; width: 100%; max-width: 100%;
}
.poll-text-input {
  display: block; width: 100%; max-width: 100%; min-width: 0;
  padding: 8px 11px; border: 1px solid var(--border); border-radius: 6px;
  font-size: 14px; font-family: inherit; background: #fff;
}
textarea.poll-text-input { min-height: 88px; resize: vertical; }
.poll-text-input:focus { outline: none; border-color: var(--primary); }
.poll-text-fields .btn {
  width: auto; max-width: 100%; white-space: nowrap;
  flex: none; align-self: flex-start;
}

/* ---------- timeline groups ---------- */
.tl-group { cursor: pointer; }
.tl-group:hover .tl-gname { background: var(--accent); }
.tl-gname { font-weight: 800; }
.tl-indent { padding-left: 26px !important; font-weight: 400 !important; color: var(--muted); }
.tl-cnt { font-size: 10px; font-weight: 700; color: #fff; }

/* ---------- admin page ---------- */
.ppl-row {
  display: grid; grid-template-columns: max-content minmax(0, 1fr) auto; gap: 10px;
  margin: 8px 0; align-items: start;
  padding: 10px; background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
}
.ppl-row > .ppl-id { display: none !important; }
.ppl-row > .photo-pick {
  width: max-content; max-width: 100%;
  flex-wrap: nowrap; align-items: flex-start;
}
.ppl-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; min-width: 0; }
.ppl-fields .ppl-bio { grid-column: 1 / -1; min-height: 52px; }
.ppl-fields .ppl-rel-org { grid-column: 1 / -1; }
.ppl-fields .ppl-rel-wrap { display: contents; }
.ppl-fields .ppl-inlaw-lab,
.ppl-fields .ppl-childof-lab {
  grid-column: 1 / -1;
  display: flex; flex-direction: column; gap: 4px;
  font-size: 13px; color: var(--muted);
}
.ppl-fields .ppl-inlaw-lab.hidden,
.ppl-fields .ppl-childof-lab.hidden { display: none; }
.ppl-row input:not([type="file"]):not([type="hidden"]):not([type="checkbox"]),
.ppl-row select, .ppl-row textarea {
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px;
  font-size: 13px; font-family: inherit; width: 100%; background: #fff;
}
#ga-result code, .acct-url {
  background: var(--accent); padding: 3px 8px; border-radius: 4px;
  font-size: 12px; word-break: break-all;
}
.save-ok {
  margin: 12px 0 0;
  padding: 10px 12px;
  background: #eef5e8;
  border: 1px solid #6a7d5c;
  color: #3d4d34;
  border-radius: 8px;
  font-weight: 600;
}
.grp-row, .acct-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 10px 0;
  border-bottom: 1px dashed var(--border);
}
.grp-row:last-child, .acct-row:last-child { border-bottom: none; }
.grp-row .grp-name { flex: 1 1 160px; min-width: 0; }
.grp-count { font-size: 12px; color: var(--muted); white-space: nowrap; }
.grp-add { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; align-items: center; }
#grp-save { display: inline-block; margin-top: 4px; }
.grp-add input, .grp-row .grp-name {
  flex: 1 1 180px; min-width: 0;
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px;
  font-size: 14px; font-family: inherit; background: #fff;
}
.acct-meta { flex: 1 1 180px; min-width: 0; }
.acct-meta strong { display: block; }
.row-actions { white-space: nowrap; }

/* ---------- audience (visibility) controls ---------- */
.aud-box { margin: 10px 0; }
.aud-list { display: flex; gap: 4px 14px; flex-wrap: wrap; margin-top: 4px; }
.aud-item {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px;
  font-size: 15px; color: var(--text); margin: 0; cursor: pointer;
}
.aud-item input { width: auto; margin: 0; }
.aud-badge {
  font-size: 11px; background: #f6e3da; color: #8a3d28;
  border-radius: 999px; padding: 2px 9px; white-space: nowrap;
}
.aud-eye {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  margin-left: 4px;
  padding: 0; border: none; background: transparent;
  color: #9a6b58; cursor: pointer;
  vertical-align: middle; flex-shrink: 0;
}
.aud-eye svg { display: block; pointer-events: none; }
.aud-eye-tip {
  display: none;
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  transform: translateX(-50%);
  min-width: 8em;
  max-width: min(80vw, 280px);
  padding: 6px 10px;
  background: #3a2a24;
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.4;
  border-radius: 8px;
  white-space: normal;
  text-align: center;
  z-index: 40;
  pointer-events: none;
  box-shadow: 0 4px 12px rgba(0,0,0,.18);
}
.aud-eye-tip::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 100%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: #3a2a24;
}
.aud-eye:hover .aud-eye-tip,
.aud-eye:focus-visible .aud-eye-tip,
.aud-eye.open .aud-eye-tip { display: block; }

/* ---------- info tab ---------- */
.info-card { border-left: 4px solid var(--ok); }
.file-link { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; text-decoration: none; }

.poll-other-row .meta { white-space: nowrap; }

.place-btns {
  display: grid; grid-template-columns: max-content;
  justify-items: stretch; gap: 6px;
  margin-top: 10px; max-width: 100%;
}
.place-btns > .btn {
  width: 100%; text-align: center; box-sizing: border-box;
}
.place-detail-body {
  margin-top: 8px; font-size: 13px; line-height: 1.8;
}
.contact-card { border-left: 3px solid var(--aka); }

/* ---------- room assignment (admin) ---------- */
.room-publish {
  display: flex; align-items: center; gap: 6px 14px; flex-wrap: wrap;
  background: #faf7ef; border: 1px solid var(--border);
  border-radius: 8px; padding: 6px 12px; margin-bottom: 8px; font-size: 13px;
}
.room-period { display: block; margin-bottom: 6px; }
.rm-chip.static { cursor: default; }
.room-group-block {
  border-left: 3px solid rgba(196, 160, 106, .55);
  padding-left: 10px; margin: 10px 0 14px;
}
.rg-name { margin: 0 4px 0 0; }
.rooms-admin { margin-top: 16px; }
.rooms-admin h3 { margin-top: 0; }
.room-add label { margin: 4px 0; }
.room-place { margin-top: 16px; }
.room-place h4 { margin: 0 0 8px; font-size: 14px; }
.room-pool {
  background: var(--accent); border: 1px dashed var(--border);
  border-radius: 8px; padding: 8px 10px; margin-bottom: 8px;
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-height: 38px;
}
.room-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; }
.room-card {
  background: #fffdf7; border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; min-height: 74px;
  transition: border-color .15s, box-shadow .15s;
}
.room-card.over-cap { border-color: var(--danger); background: #faf1ee; }
.room-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.room-head .meta { flex: 0 0 auto; }
.room-head .room-dates {
  flex: 1 1 100%; min-width: 0;
  white-space: normal; overflow-wrap: anywhere;
}
.rm-edit-label { flex: 1 1 7em; min-width: 5em; min-height: 36px; font-size: 16px; font-weight: 600; }
.room-occupants { display: flex; gap: 6px; flex-wrap: wrap; min-height: 26px; }
.rm-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: var(--primary-dark); color: #fdfaf2; font-size: 12px; font-weight: 600;
  border-radius: 999px; padding: 3px 10px; cursor: grab; user-select: none;
}
.rm-chip:active { cursor: grabbing; }
/* Compact "assign to room" pickers: a small quiet control beside the
   name chip, not a full-size form field (it looked oversized). On
   touch devices they grow back to 16px so iOS does not zoom on focus. */
.rm-assign, .rm-add {
  font-size: 12px;
  max-width: 160px;
  margin: 4px 0 0;
  background: #fff; color: var(--text);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 2px 8px;
}
.rm-chip .rm-assign {
  display: inline-block;
  margin: 0 0 0 6px;
  font-weight: 400;
}
@media (pointer: coarse) {
  .rm-assign, .rm-add { font-size: 16px; max-width: 100%; }
  .rm-chip .rm-assign { display: block; margin: 4px 0 0; }
}
.csv-bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 10px; }
.csv-bar.compact { margin-top: 8px; }
@media (pointer: coarse) {
  .rm-chip { font-size: 14px; padding: 6px 12px; }
  .rm-remove { width: 22px; height: 22px; font-size: 14px; }
}
.rm-remove {
  /* Solid white disc with the chip colour for the ×: the old translucent
     white-on-pink version measured only 3:1 contrast. */
  border: none; background: #fff; color: var(--primary-dark);
  border-radius: 50%; width: 16px; height: 16px; font-size: 11px; font-weight: 700; line-height: 1;
  cursor: pointer; padding: 0;
}
.drop-hover { border-color: var(--primary) !important; box-shadow: 0 0 0 3px rgba(196, 30, 58, .16); }

/* ---------- floating question button + modal ---------- */
.q-fab {
  position: fixed; bottom: 24px; right: 22px; z-index: 90;
  width: 58px; height: 58px; border-radius: 50%;
  border: 3px solid #fff;
  background: var(--aka); color: #fff; cursor: pointer;
  box-shadow: 0 0 0 2px var(--aka), 0 8px 22px rgba(90, 30, 30, .28);
  display: flex; align-items: center; justify-content: center;
  padding: 0; transition: transform .15s;
  font-family: var(--font);
  font-size: 28px; font-weight: 700; line-height: 1;
}
.q-fab:hover { transform: scale(1.08); }
.q-fab:active { transform: scale(.94); }
.q-modal {
  position: fixed; inset: 0; z-index: 95;
  background: rgba(80, 20, 28, .4); backdrop-filter: blur(3px);
  display: flex; align-items: flex-end; justify-content: flex-end; padding: 20px;
}
.q-modal-card {
  width: 100%; max-width: 420px;
  max-height: 70vh; overflow-y: auto; padding: 20px;
  border-radius: 16px; position: relative;
}
.q-modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.q-modal-card textarea {
  width: 100%; padding: 9px 11px; border: 1px solid var(--border);
  border-radius: 6px; font-size: 14px; font-family: inherit; margin-bottom: 8px;
  background: #fff;
}
.q-modal-card h4 { margin: 16px 0 6px; font-size: 13px; color: var(--muted); }
.q-item { border-top: 1px solid var(--hairline); padding: 10px 0; }
.q-item.q-done { opacity: .75; }
.q-q { margin: 0 0 4px; font-size: 14px; }
.q-reply {
  background: var(--accent); border-radius: 8px; padding: 8px 12px;
  border-left: 3px solid var(--primary);
  margin: 6px 0 0; font-size: 13px;
}
.q-reply-row { display: flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.q-reply-input {
  flex: 1; min-width: 0; padding: 7px 10px;
  border: 1px solid var(--border); border-radius: 6px; font-size: 13px; font-family: inherit;
  background: #fff;
}

/* ---------- map ---------- */
.map-canvas {
  height: 420px; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--border); box-shadow: var(--shadow);
  margin-bottom: 16px; z-index: 1;
  max-width: 100%;
}
.map-canvas .leaflet-container { width: 100% !important; max-width: 100%; }
.place-row { padding: 12px 16px; }

/* ---------- invitation (home) ---------- */
.invite-card {
  padding: 32px;
}
.invite-text {
  font-size: 17px; line-height: 2; margin: 0 0 16px;
  font-family: var(--font);
  letter-spacing: .04em;
}
.invite-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 10px 0; }
.invite-fact {
  background: var(--accent); border-radius: 10px; padding: 14px 18px;
  border-left: 3px solid var(--primary);
}
/* Fact-box labels stay compact (Subheadline 15), values are body 17. */
.invite-fact h4 { margin: 0 0 6px; font-size: 15px; color: var(--primary-dark); }
.invite-fact p { margin: 0; font-size: 17px; }
.invite-h {
  margin: 22px 0 8px; font-size: 14px; color: var(--primary-dark);
  letter-spacing: .1em; border-bottom: 1px solid var(--gold-soft); padding-bottom: 5px;
}
.hosts {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 10px 16px;
  align-items: start;
  margin: 8px 0 18px;
}
.hosts.n1 { grid-template-columns: minmax(0, 320px); justify-content: center; }
.hosts .mizu { align-self: center; }
/* The quiet heart between the groom and the bride. */
.hosts .host-heart {
  align-self: center; justify-self: center;
  display: inline-flex; width: 38px; height: 38px;
}
.host-heart svg { width: 100%; height: 100%; }
.host-card {
  text-align: center; background: #fff;
  padding: 12px 12px 16px;
}
.host-card img, .host-photo {
  width: 100%; aspect-ratio: 3 / 4; max-height: 280px;
  object-fit: cover; border-radius: 4px;
  margin-bottom: 10px;
  border: 1px solid var(--border);
}
.host-photo.empty {
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); font-size: 42px; font-family: var(--font);
  color: var(--primary-dark);
}
.host-card strong {
  display: block; font-size: 17px; letter-spacing: .14em;
  font-family: var(--font);
}
.host-preview {
  width: 72px; height: 96px; object-fit: cover; border-radius: 4px;
  grid-column: 1 / -1; justify-self: start;
}
/* ---- Photo collage (moodStrip) --------------------------------
   Up to five prints in a loose, hand-placed arrangement. The layout
   pattern (s0-s3) is chosen per page by a seed in helpers.js, so
   each page gets its own stable composition. Prints alternate
   portrait / square / landscape and every other one gets a strip of
   washi tape. */
.mood-strip {
  display: flex; justify-content: center; align-items: center;
  gap: 6px 12px; margin: 14px 0 24px; flex-wrap: wrap;
  max-width: 100%;
  padding-top: 10px;              /* room for the tape */
}
.mood-fig {
  position: relative;
  margin: 0; min-width: 0;
  flex: 0 1 clamp(110px, 24%, 210px);
  background: #fff; padding: 7px 7px 18px;
  transition: transform .25s ease;
}
.mood-fig img { display: block; width: 100%; aspect-ratio: 3/4; object-fit: cover; }
.mood-fig:hover { transform: scale(1.04) rotate(0deg) !important; z-index: 2; }
/* Washi tape accent. */
.mood-fig.tape::before {
  content: ""; position: absolute; top: -9px; left: 50%; z-index: 1;
  width: 58px; height: 17px;
  transform: translateX(-50%) rotate(-5deg);
  background: linear-gradient(100deg,
    rgba(201, 162, 75, .38), rgba(201, 162, 75, .52));
  border-left: 1px dashed rgba(255,255,255,.7);
  border-right: 1px dashed rgba(255,255,255,.7);
}
/* Print variety: alternate shapes and give one print more presence. */
.mood-fig.f1 img { aspect-ratio: 1 / 1; }
.mood-fig.f3 img { aspect-ratio: 4 / 3; }
.mood-fig.f0 { flex-basis: clamp(130px, 30%, 250px); }
/* Layout patterns (rotation + vertical drift). */
.mood-strip.s0 .f0 { transform: rotate(-3deg); }
.mood-strip.s0 .f1 { transform: rotate(2.4deg) translateY(12px); }
.mood-strip.s0 .f2 { transform: rotate(-1.6deg) translateY(-8px); }
.mood-strip.s0 .f3 { transform: rotate(2.8deg) translateY(6px); }
.mood-strip.s0 .f4 { transform: rotate(-2.2deg) translateY(-4px); }
.mood-strip.s1 .f0 { transform: rotate(2.6deg) translateY(6px); }
.mood-strip.s1 .f1 { transform: rotate(-2.8deg) translateY(-10px); }
.mood-strip.s1 .f2 { transform: rotate(1.8deg) translateY(10px); }
.mood-strip.s1 .f3 { transform: rotate(-2.4deg); }
.mood-strip.s1 .f4 { transform: rotate(2deg) translateY(-6px); }
.mood-strip.s2 .f0 { transform: rotate(-1.6deg) translateY(12px); }
.mood-strip.s2 .f1 { transform: rotate(1.4deg); }
.mood-strip.s2 .f2 { transform: rotate(-2.6deg) translateY(-10px); }
.mood-strip.s2 .f3 { transform: rotate(2.2deg); }
.mood-strip.s2 .f4 { transform: rotate(-1.8deg) translateY(12px); }
.mood-strip.s3 .f0 { transform: rotate(1.8deg) translateY(-8px); }
.mood-strip.s3 .f1 { transform: rotate(-2.4deg) translateY(8px); }
.mood-strip.s3 .f2 { transform: rotate(2.6deg) translateY(-4px); }
.mood-strip.s3 .f3 { transform: rotate(-1.4deg) translateY(10px); }
.mood-strip.s3 .f4 { transform: rotate(2.4deg); }
/* Admin-chosen arrangements (写真の並べ方) override the seeded
   pattern: the strip carries .l-row / .l-feature / .l-scatter
   instead of .s0-.s3. */
.mood-strip.l-row { align-items: flex-start; }
.mood-strip.l-row .mood-fig,
.mood-strip.l-row .mood-fig.f0 { flex-basis: clamp(105px, 19%, 185px); }
.mood-strip.l-row .mood-fig:nth-child(odd) { transform: rotate(-1.2deg); }
.mood-strip.l-row .mood-fig:nth-child(even) { transform: rotate(1.2deg); }
.mood-strip.l-feature .mood-fig.f0 {
  flex-basis: clamp(190px, 44%, 340px); transform: rotate(-1.4deg);
}
.mood-strip.l-feature .mood-fig { flex-basis: clamp(90px, 16%, 150px); }
.mood-strip.l-feature .f1 { transform: rotate(2.2deg) translateY(10px); }
.mood-strip.l-feature .f2 { transform: rotate(-2deg) translateY(-6px); }
.mood-strip.l-feature .f3 { transform: rotate(1.6deg) translateY(8px); }
.mood-strip.l-feature .f4 { transform: rotate(-2.4deg); }
.mood-strip.l-scatter .f0 { transform: rotate(-4.5deg) translateY(14px); }
.mood-strip.l-scatter .f1 { transform: rotate(3.6deg) translateY(-14px); }
.mood-strip.l-scatter .f2 { transform: rotate(-2.6deg) translateY(10px); }
.mood-strip.l-scatter .f3 { transform: rotate(4.2deg) translateY(-8px); }
.mood-strip.l-scatter .f4 { transform: rotate(-3.4deg) translateY(12px); }
/* A lone photo becomes a centered feature print. */
.mood-strip.n1 .mood-fig { flex-basis: min(320px, 72%); }
/* Slight overlap for a hand-stacked feel on wider screens. */
@media (min-width: 720px) {
  .mood-strip.n4 .mood-fig, .mood-strip.n5 .mood-fig { margin-left: -14px; }
  .mood-strip.n4 .mood-fig:first-child,
  .mood-strip.n5 .mood-fig:first-child { margin-left: 0; }
}
/* Phones: one compact row, whatever the arrangement, so the collage
   never adds meaningful scroll length. */
@media (max-width: 640px) {
  .mood-strip { flex-wrap: nowrap; gap: 6px; margin: 10px 0 16px; padding-top: 8px; }
  .mood-strip .mood-fig, .mood-strip .mood-fig.f0 {
    flex: 1 1 0; min-width: 0; padding: 4px 4px 10px;
    transform: none !important;
  }
  .mood-strip .mood-fig:nth-child(odd) { transform: rotate(-1.6deg) !important; }
  .mood-strip .mood-fig:nth-child(even) { transform: rotate(1.6deg) !important; }
  .mood-strip.n1 .mood-fig { flex: 0 1 min(230px, 68%); }
  .mood-fig.tape::before { width: 40px; height: 12px; top: -6px; }
}
.mood-layout-label { display: block; margin: 8px 0 2px; font-size: 13px; }
.mood-layout-label select { width: auto; max-width: 100%; }
/* Admin-only numbering: badge N on each print = frame N in the
   editor, so "この枠を消す" is unambiguous. */
.mood-fig-num {
  position: absolute; top: 4px; left: 4px; z-index: 2;
  min-width: 20px; height: 20px; padding: 0 6px;
  background: rgba(60, 42, 30, .72); color: #fff; border-radius: 999px;
  font-size: 12px; font-weight: 700; line-height: 20px; text-align: center;
}
.mood-slot-num {
  display: block; margin-bottom: 2px;
  font-size: 12px; font-weight: 700; color: var(--muted);
}

/* Scroll-driven reveal (home): sections rise softly into view. */
.reveal { opacity: 0; transform: translateY(16px);
  transition: opacity .6s ease, transform .6s ease; }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------- envelope scrollytelling (home invitation) ----------
   A shūgi-bukuro style envelope pinned to the viewport while the
   surrounding stage scrolls by. --p (0..1, set from JS) drives the
   whole sequence:
     --f  flap fold        (p 0.04 - 0.34)
     --fo flap fade-away   (p 0.30 - 0.42)
     --l  letter rising    (p 0.36 - 0.62)
     --s  letter expanding (p 0.60 - 0.94)
   The letter carries the REAL invitation content: it rises out of
   the pocket (z-layered under it, so the envelope clips it like a
   real one), then scales up to full size while the envelope fades -
   one continuous object. Depth layers drift against the pinned
   scene for a near/far parallax feel. */
/* Full-bleed breakout: the stage (and the letter-main surface after
   it) span the whole viewport even though main is width-capped.
   Tap-to-open (v5): the stage is one viewport tall - no scroll
   driving - and a tap plays the sequence (home.js bindEnvelope). */
.env-stage {
  height: 100vh;
  height: 100dvh;
  width: 100vw;
  margin: 8px calc(50% - 50vw) 0;
}
.env-sticky {
  position: relative; height: 100%;
  overflow: hidden;
}
.env-scene {
  position: relative; width: 100%; height: 100%;
  cursor: pointer;
  perspective: 900px;
  --f:  min(1, max(0, calc((var(--p, 0) - 0.04) / 0.26)));
  --fo: min(1, max(0, calc((var(--p, 0) - 0.26) / 0.12)));
  --l:  min(1, max(0, calc((var(--p, 0) - 0.30) / 0.22)));
  /* The widening phase owns nearly half the timeline (0.52-0.95) so
     the white sheet unfolds unhurriedly (paired with the longer
     DURATION in home.js). */
  --s:  min(1, max(0, calc((var(--p, 0) - 0.52) / 0.43)));
  /* --w runs WITH --s: the paper grows straight from the envelope to
     the full viewport, with no intermediate fixed-width card stage. */
  --w:  min(1, max(0, calc((var(--p, 0) - 0.52) / 0.43)));
}
/* Depth: the back layer drifts down, the front layer drifts up, so
   the pinned centre reads as sitting between near and far planes. */
.env-depth { position: absolute; inset: -12% 0; pointer-events: none; }
.env-depth.back { z-index: 0; transform: translateY(calc(var(--p, 0) * 130px)); }
.env-depth.front { z-index: 6; transform: translateY(calc(var(--p, 0) * -170px)); }
.env-blob { position: absolute; border-radius: 50%; }
.env-blob.b1 {
  width: 360px; height: 360px; left: 4%; top: 10%;
  background: radial-gradient(circle, rgba(201, 162, 75, .20), transparent 68%);
}
.env-blob.b2 {
  width: 460px; height: 460px; right: 2%; bottom: 6%;
  background: radial-gradient(circle, rgba(196, 30, 58, .11), transparent 68%);
}
/* Drifting petals are little SVG illustrations; the season theme
   swaps the artwork itself (sakura petal / young leaf / maple leaf /
   snowflake), not just the colour. --petal-img is the main piece,
   --petal-img2 an accent variant (see the .season-* blocks). */
.env-petal {
  position: absolute; width: 26px; height: 26px;
  background: none;
  background-image: var(--petal-img);
  background-size: contain; background-repeat: no-repeat;
  background-position: center;
  /* Ambient drift: petals sway and sink continuously. The keyframes
     animate the independent `translate` / `rotate` properties so they
     COMPOSE with each petal's static transform below (browsers
     without those properties simply show still petals). */
  animation: petal-drift var(--pdur, 9s) ease-in-out var(--pdel, 0s) infinite alternate;
}
@keyframes petal-drift {
  0%   { translate: 0 -10px; rotate: -6deg; }
  45%  { translate: 12px 12px; rotate: 10deg; }
  100% { translate: -10px 34px; rotate: -14deg; }
}
@media (prefers-reduced-motion: reduce) {
  .env-petal { animation: none; }
}
.env-depth.back .env-petal { filter: blur(1.5px); opacity: .55; }
.env-petal.d1 { left: 16%; top: 24%; transform: rotate(24deg); --pdur: 8.5s; }
.env-petal.d2 { left: 74%; top: 16%; transform: rotate(-40deg) scale(.85); --pdur: 11s; --pdel: -3s; }
.env-petal.d3 { left: 30%; top: 74%; transform: rotate(70deg) scale(1.1); --pdur: 9.5s; --pdel: -6s; }
.env-petal.d4 { left: 10%; top: 60%; transform: rotate(-18deg) scale(1.5); opacity: .8; --pdur: 12s; --pdel: -2s; }
.env-petal.d5 { right: 12%; top: 32%; transform: rotate(48deg) scale(1.3); background-image: var(--petal-img2, var(--petal-img)); --pdur: 10s; --pdel: -8s; }
.env-petal.d6 { right: 24%; bottom: 12%; transform: rotate(-64deg) scale(1.2); opacity: .75; --pdur: 8s; --pdel: -4s; }
.envelope {
  position: absolute; left: 50%; top: 50%; z-index: 3;
  width: min(300px, 72vw);
  aspect-ratio: 3 / 4;
  pointer-events: none;
  transform: translate(-50%, calc(-50% + var(--s) * 140px));
  /* Fades quickly once the letter starts expanding, so the growing
     letter is never hidden behind the pocket. */
  opacity: min(1, max(0, calc(1 - var(--s) * 2.5)));
}
/* The progress transform lives on a WRAPPER, never on the .card
   itself: .card:hover sets its own transform, and transforms replace
   (not compose) - putting both on one element made the letter jump
   off-centre the moment the cursor touched it. */
.env-letter-track {
  position: absolute; left: 50%; top: 50%; z-index: 2;
  /* Final phase --w: the PAPER widens to the full viewport. The text
     column inside (.env-letter-inner) keeps a fixed width, so the
     text never re-wraps while the sheet grows. */
  width: calc(min(680px, 92vw) * (1 - var(--w)) + 100vw * var(--w));
  pointer-events: none;
  /* Start tucked fully INSIDE the envelope box (+10px, small scale:
     the scaled letter fits behind the pocket, so nothing peeks out
     below), rise to -120px so the top emerges above the flap line,
     then the offset collapses to 0 as the letter expands. */
  --env-off: calc((1 - var(--l)) * 10px - var(--l) * 120px);
  transform: translate(-50%, calc(-50% + var(--env-off) * (1 - var(--s))))
             scale(calc(0.40 + var(--s) * 0.60));
}
.env-stage.env-done .env-letter-track { pointer-events: auto; }
.env-letter {
  margin: 0;
  max-height: calc(86vh + var(--w) * 100vh);
  overflow: hidden;
  text-align: center;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  /* Grows into a full-screen sheet at the end of the stage, so the
     .letter-main surface after the stage continues it seamlessly. */
  min-height: calc(var(--w) * 100dvh);
  background: var(--card);
  /* Card chrome melts away as the sheet becomes the page itself. */
  border-color: rgba(214, 197, 163, calc(1 - var(--w)));
  border-radius: calc(12px * (1 - var(--w)));
  box-shadow: 0 12px 30px rgba(60, 42, 30, calc(0.16 * (1 - var(--w))));
}
/* Opened: the letter becomes a normal block of the page. env-done
   drops the viewport-height stretch (home.js then animates the stage
   down to the letter's own height), and env-settled switches the
   letter to static flow - the paper and the sections below it read
   as one continuous sheet with no blank stretch in between. */
.env-stage.env-done .env-letter {
  min-height: 0; max-height: none; overflow: visible;
}
.env-stage.env-done.env-settled { height: auto; }
.env-stage.env-done.env-settled .env-sticky { height: auto; }
.env-stage.env-done.env-settled .env-letter-track {
  position: static; transform: none; width: 100vw;
}
.env-letter-inner { width: 100%; max-width: min(640px, 90vw); margin: 0 auto; }
.env-letter .mizu.knot { display: block; margin: 0 auto 2px; }
/* The page surface the letter turns into: full bleed, same paper. */
.letter-main {
  width: 100vw;
  margin: 0 calc(50% - 50vw);
  background: var(--card);
  /* Small top padding: the letter paper sits directly above, and the
     two must read as one sheet. */
  padding: 12px 0 56px;
}
.letter-main-inner {
  max-width: 1000px; margin: 0 auto; padding: 0 18px;
  min-width: 0;
}
.env-letter-sub {
  display: block; text-align: center; margin-bottom: 10px;
  font-size: 12px; letter-spacing: .3em; color: var(--muted);
}
/* The envelope face is a classic wa invitation card: warm white
   paper, thin red rules down both edges, clusters of red-and-gold
   plum blossoms (filled + outline) in opposite corners, and a red
   mizuhiki knot with INVITATION lettering at the centre. */
.env-pocket {
  position: absolute; inset: 0;
  background:
    linear-gradient(#c23b2e, #c23b2e) 8px 0 / 2.5px 100% no-repeat,
    linear-gradient(#c23b2e, #c23b2e) 14px 0 / 1px 100% no-repeat,
    linear-gradient(#c23b2e, #c23b2e) calc(100% - 8px) 0 / 2.5px 100% no-repeat,
    linear-gradient(#c23b2e, #c23b2e) calc(100% - 14px) 0 / 1px 100% no-repeat,
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 400'><defs><g id='u'><circle cx='0' cy='-4.4' r='4'/><circle cx='4.2' cy='-1.4' r='4'/><circle cx='2.6' cy='3.6' r='4'/><circle cx='-2.6' cy='3.6' r='4'/><circle cx='-4.2' cy='-1.4' r='4'/></g></defs><path d='M24 178 Q70 96 144 104' stroke='%23dfc386' stroke-width='2' fill='none'/><path d='M272 280 Q222 372 148 354' stroke='%23dfc386' stroke-width='2' fill='none'/><use href='%23u' transform='translate(62 118) scale(2.4)' fill='%23cf3527'/><circle cx='62' cy='118' r='4' fill='%23d9b96a'/><use href='%23u' transform='translate(112 150) scale(1.8)' fill='%23cf3527'/><circle cx='112' cy='150' r='3' fill='%23d9b96a'/><g transform='translate(36 160) scale(1.7)' fill='%23fffdf8' stroke='%23cf3527' stroke-width='1'><use href='%23u'/></g><circle cx='36' cy='160' r='2.6' fill='%23d9b96a'/><circle cx='92' cy='106' r='3.4' fill='%23cf3527'/><circle cx='146' cy='156' r='2.6' fill='%23cf3527'/><circle cx='20' cy='128' r='2.4' fill='%23cf3527'/><use href='%23u' transform='translate(232 338) scale(2.6)' fill='%23cf3527'/><circle cx='232' cy='338' r='4.2' fill='%23d9b96a'/><use href='%23u' transform='translate(194 304) scale(1.8)' fill='%23cf3527'/><circle cx='194' cy='304' r='3' fill='%23d9b96a'/><g transform='translate(260 294) scale(1.9)' fill='%23fffdf8' stroke='%23cf3527' stroke-width='1'><use href='%23u'/></g><circle cx='260' cy='294' r='2.8' fill='%23d9b96a'/><use href='%23u' transform='translate(170 366) scale(1.4)' fill='%23cf3527'/><circle cx='170' cy='366' r='2.4' fill='%23d9b96a'/><circle cx='150' cy='330' r='3' fill='%23cf3527'/><circle cx='272' cy='356' r='2.6' fill='%23cf3527'/><circle cx='214' cy='272' r='2.4' fill='%23cf3527'/></svg>") center / 100% 100% no-repeat,
    linear-gradient(175deg, #fffdf9, #faf4e8);
  border: 1px solid var(--gold-soft, #dcc98f);
  border-radius: 6px;
  box-shadow: 0 10px 26px rgba(60, 42, 30, .16);
  display: flex; align-items: center; justify-content: center;
}
.env-pocket-center {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  transform: translateY(-10%);
}
.env-pocket .mizu.ume { width: 64px; height: 64px; }
.env-invite-label {
  font-family: var(--font);
  font-size: 12px; letter-spacing: .42em; text-indent: .42em;
  color: #8a4a3b;
}
.env-flap {
  position: absolute; top: 0; left: 0; right: 0;
  height: 38%;
  background: linear-gradient(180deg, #fdf8ee, #f5ecd8);
  border: 1px solid var(--gold-soft, #dcc98f);
  border-radius: 6px 6px 0 0;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  transform-origin: top center;
  transform: rotateX(calc(var(--f) * -176deg));
  /* The back face stays visible while folding open (like the inner
     side of a real flap); --fo then fades it away so the rising
     letter is never covered. */
  opacity: calc(1 - var(--fo));
}
/* Sealed page: everything below the envelope stays hidden until the
   guest opens it - the home page is deliberately short before the
   tap and grows once the letter unfolds. */
.env-unopened .letter-main { display: none; }
.env-hint {
  position: absolute; left: 0; right: 0; bottom: 7%; z-index: 7;
  margin: 0; text-align: center; font-size: 13px; font-weight: 600;
  letter-spacing: .18em; color: var(--primary-dark);
  opacity: min(1, max(0, calc(1 - var(--p, 0) * 5)));
}
/* Closed envelope on screen: a gentle breathing pulse says "tap me". */
.env-scene.env-ready .envelope {
  animation: env-pulse 1.9s ease-in-out infinite;
}
@keyframes env-pulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50% { transform: translate(-50%, -50%) scale(1.06); }
}
.env-scene.env-opening, .env-stage.env-done .env-scene { cursor: default; }
.env-scene:focus-visible {
  outline: 3px solid var(--gold); outline-offset: -3px;
}
@media (max-width: 640px) {
  .envelope { width: min(260px, 72vw); }
  .env-blob.b1, .env-blob.b2 { width: 260px; height: 260px; }
}
.invite-card { position: relative; overflow: hidden; }
.invite-corner {
  position: absolute; width: 42px; height: 42px; pointer-events: none;
  background:
    linear-gradient(var(--gold), var(--gold)) no-repeat,
    linear-gradient(var(--aka), var(--aka)) no-repeat;
  background-size: 18px 1px, 1px 18px;
  opacity: .75;
}
.invite-corner.tl { top: 10px; left: 10px; background-position: left top, left top; }
.invite-corner.tr { top: 10px; right: 10px; background-position: right top, right top; }
.album-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px; margin-top: 8px;
}
.album-card {
  display: flex; flex-direction: column; align-items: stretch;
  overflow: hidden; cursor: pointer; padding: 0;
  text-align: left; color: inherit; font: inherit;
  transition: transform .15s;
}
.album-card:hover { transform: translateY(-3px); }
.album-card img, .album-empty {
  width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block;
  background: #efe4d0;
}
.album-empty { display: flex; align-items: center; justify-content: center; }
.album-name {
  font-family: var(--font); font-size: 16px; letter-spacing: .1em;
  padding: 10px 12px 0; color: var(--primary-dark);
}
.album-card .meta { padding: 4px 12px 12px; }
.where-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px;
}
.where-head .wa-sec { margin: 0; }
.faq-item {
  border: 1px solid var(--border); border-radius: 12px;
  padding: 10px 14px; margin-bottom: 8px; background: #fffdf7;
}
.faq-item summary { cursor: pointer; font-size: 14px; font-weight: 600; }
.faq-item p { margin: 8px 0 2px; font-size: 13px; color: var(--muted); line-height: 1.8; }
.rsvp-group { margin: 10px 0; min-width: 0; }
.rsvp-group h5 {
  margin: 0 0 6px; font-size: 13px;
  display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline;
}
.rsvp-member {
  display: flex; align-items: center; gap: 8px; padding: 6px 0;
  flex-wrap: wrap; min-width: 0;
}
.rsvp-name { min-width: 0; font-size: 14px; font-weight: 600; }
.rsvp-member .btn { min-width: 0; }
.rsvp-allergy {
  padding: 0 0 8px 0; margin-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
}
.rsvp-allergy:last-child { border-bottom: none; }
.rsvp-allergy label { margin: 0; font-size: 12px; }
.rsvp-allergy input { width: 100%; max-width: 100%; }
/* Severity / notes hangs off the allergy field: indented, and faded
   while the allergy itself is still empty (remains editable). */
.rsvp-allergy .rsvp-allergy-detail {
  display: block; margin-top: 6px; padding-left: 14px;
  border-left: 2px solid var(--hairline);
  transition: opacity .15s ease;
}
.rsvp-allergy .rsvp-allergy-detail.is-idle { opacity: .55; }
.rsvp-allergy .rsvp-allergy-detail.is-idle:focus-within { opacity: 1; }
.rsvp-review {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px;
  padding: 10px 0; border-bottom: 1px solid var(--hairline);
}
.rsvp-review:last-child { border-bottom: none; }
.rsvp-pill {
  font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 999px;
  white-space: nowrap;
}
.rsvp-pill.yes { background: #eef6e6; color: #4a5d3a; }
.rsvp-pill.no { background: #f4f1ea; color: #6f6759; }
.rsvp-pill.maybe { background: #fdf6e6; color: #8a6a28; }
.rsvp-pill.none { background: #f0eeea; color: var(--muted); }
.rsvp-confirm-row { margin: 12px 0 4px; display: flex; gap: 8px; flex-wrap: wrap; }
.rsvp-sent { margin: 0 0 10px; }
/* Compact admin RSVP: totals strip, collapsible groups, one line
   per member (name / status select / allergy). */
.rsvp-total-strip {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 12px;
}
.rsvp-fold {
  border: 1px solid var(--border); border-radius: 12px;
  background: #fff; margin: 0 0 8px;
}
.rsvp-fold summary {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; cursor: pointer; list-style: none;
  font-weight: 700;
}
.rsvp-fold summary::-webkit-details-marker { display: none; }
.rsvp-fold summary::before {
  content: "▸"; color: var(--muted); font-weight: 400;
  transition: transform .15s ease;
}
.rsvp-fold[open] summary::before { transform: rotate(90deg); }
.rsvp-fold-meta {
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-left: auto; font-weight: 400;
}
.rsvp-admin-row {
  display: grid;
  grid-template-columns: minmax(88px, 1fr) auto minmax(120px, 1.3fr) minmax(120px, 1.3fr);
  gap: 8px; align-items: center;
  padding: 7px 12px; border-top: 1px solid var(--border);
}
.rsvp-admin-row .rsvp-name { overflow-wrap: anywhere; }
.rsvp-admin-row select, .rsvp-admin-row input { margin: 0; width: auto; }
.rsvp-admin-row .rsvp-allergy-in,
.rsvp-admin-row .rsvp-allergy-detail-in { width: 100%; }
@media (max-width: 560px) {
  .rsvp-admin-row { grid-template-columns: 1fr auto; }
  .rsvp-admin-row .rsvp-allergy-in,
  .rsvp-admin-row .rsvp-allergy-detail-in { grid-column: 1 / -1; }
}
hr.thin { border: none; border-top: 1px dashed var(--border); margin: 6px 0; }

/* ---------- seating chart ---------- */
.seat-toolbar {
  display: flex; gap: 14px; align-items: flex-end; flex-wrap: wrap;
}
.seat-toolbar label { margin: 0; font-size: 12px; }
.seat-toolbar input[type="number"] { width: 90px; }
.seat-pub {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; white-space: nowrap;
}
.seat-pub input { width: auto; margin: 0; }
.page-pub-list { display: flex; flex-direction: column; gap: 2px; margin: 10px 0 14px; }
.page-pub {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; margin: 6px 0; color: var(--text);
}
.page-pub input[type="checkbox"] {
  display: inline-block; width: auto; min-height: 0;
  margin: 0; padding: 0; border: none; box-shadow: none;
}
.page-pub.is-locked { color: var(--muted); }
.seat-chart-wrap { padding: 12px; width: 100%; max-width: 100%; overflow-x: auto; }
.seat-chart {
  width: 100%; height: auto; max-height: 68vh;
  display: block; touch-action: none;
}
.seat-room {
  fill: #fbf8f2; stroke: var(--muted); stroke-width: .05;
}
.seat-corner {
  fill: var(--card); stroke: var(--primary); stroke-width: .05;
  cursor: grab;
}
.seat-corner.sel { fill: var(--gold); stroke: #8d7238; }
.seat-toolbar2 { margin-top: 10px; }
.seat-tbl { cursor: grab; }
.seat-tbl.dragging { cursor: grabbing; opacity: .85; }
.seat-top {
  fill: #fff; stroke: var(--primary); stroke-width: .05;
}
.seat-tbl.mine .seat-top { fill: #fdf6e6; stroke: var(--gold); stroke-width: .08; }
.seat-dot { fill: #fff; stroke: var(--muted); stroke-width: .03; }
.seat-dot.taken { fill: var(--primary); stroke: var(--primary-dark); }
.seat-dot.mine { fill: var(--gold); stroke: #8d7238; }
.seat-label {
  text-anchor: middle; font-size: .34px; font-weight: 700;
  fill: var(--text); pointer-events: none;
}
.seat-count {
  text-anchor: middle; font-size: .24px; fill: var(--muted);
  pointer-events: none;
}
.seat-h {
  margin: 20px 0 8px; font-size: 14px; color: var(--primary-dark);
  letter-spacing: .1em;
}
.seat-cards {
  display: grid; gap: 12px;
  /* min(230px, 100%): on a narrow screen a card may shrink below
     230px instead of pushing the grid wider than the page. */
  grid-template-columns: repeat(auto-fill, minmax(min(230px, 100%), 1fr));
}
.seat-card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 14px; box-shadow: var(--shadow);
  min-width: 0;
}
.seat-card.mine { border-color: var(--gold); background: #fffdf6; }
.seat-card-head { display: flex; gap: 6px; align-items: center; margin-bottom: 8px; min-width: 0; }
/* The table-name input must be allowed to SHRINK: its intrinsic size
   (~20 characters) otherwise forces the card, and with it the whole
   grid, wider than the page. */
.seat-card-head input { margin: 0; font-weight: 700; flex: 1 1 60px; min-width: 0; width: auto; }
.seat-card-head select { margin: 0; width: auto; flex: 0 0 auto; }
.seat-seats select { min-width: 0; max-width: 100%; }
.seat-seats { list-style: none; margin: 0; padding: 0; }
.seat-seats li {
  display: flex; align-items: center; gap: 8px;
  padding: 3px 0; font-size: 13px;
}
.seat-seats li.mine { font-weight: 700; color: var(--primary-dark); }
.seat-seats select { margin: 0; font-size: 13px; padding: 4px 8px; }
.seat-no {
  flex: 0 0 20px; text-align: center; font-size: 11px;
  color: var(--muted); border: 1px solid var(--border); border-radius: 4px;
}
.seat-card-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.seat-fix { cursor: grab; }
.seat-fix.dragging { cursor: grabbing; opacity: .85; }
.seat-fix-shape { fill: #ece6d8; stroke: #8a7d68; stroke-width: .04; }
.seat-fix.kind-mc .seat-fix-shape { fill: #f3e4b4; stroke: #8d7238; }
.seat-fix-inner { fill: #fff; stroke: #8d7238; stroke-width: .04; }
.seat-fix.kind-pillar .seat-fix-shape { fill: #cfc8ba; stroke: #6f6759; }
.seat-fix-mark { stroke: #6f6759; stroke-width: .05; }
.seat-fix.kind-cake .seat-fix-shape { fill: #f7e8ee; stroke: #b07a8a; }
.seat-fix.kind-screen .seat-fix-shape { fill: #3d3a36; stroke: #2a2723; }
.seat-fix.kind-reception .seat-fix-shape { fill: #e8dcc4; stroke: #7a6a4a; }
.seat-fix.kind-entrance .seat-fix-shape {
  fill: rgba(138, 125, 104, .12); stroke: #8a7d68;
  stroke-width: .06; stroke-dasharray: .12 .08;
}
.seat-fix.kind-stage .seat-fix-shape { fill: #efe6d2; stroke: #8d7238; }
.seat-fix-label {
  text-anchor: middle; font-size: .28px; font-weight: 700;
  fill: var(--text); pointer-events: none;
}
.seat-fix-bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: end; margin-top: 10px; }
.seat-fix-list { display: grid; gap: 8px; margin-top: 10px; }
.seat-fix-row {
  display: grid; gap: 8px; align-items: center;
  grid-template-columns: 1.4fr repeat(auto-fit, minmax(90px, 1fr)) auto;
}
.seat-fix-row input, .seat-fix-row label { margin: 0; }
.seat-fix-row label { font-size: 12px; color: var(--muted); }
/* per-chair editing + drag & drop assignment (admin) */
.seat-chart.admin .seat-dot { cursor: grab; touch-action: none; }
.seat-dot.sel { stroke: var(--gold); stroke-width: .07; }
.seat-dot.drop-hover { fill: var(--gold); stroke: #8d7238; stroke-width: .06; }
.seat-guide {
  stroke: var(--gold); stroke-width: .04;
  stroke-dasharray: .18 .12; pointer-events: none;
}
.seat-del-btn { cursor: pointer; }
.seat-del-btn circle { fill: #fff; stroke: #b3413f; stroke-width: .04; }
.seat-del-btn text {
  fill: #b3413f; font-size: .3px; font-weight: 700;
  text-anchor: middle; pointer-events: none;
}
.seat-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.seat-chip {
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--card); padding: 4px 12px; font-size: 13px;
  cursor: grab; touch-action: none; user-select: none;
  -webkit-user-select: none;
}
.seat-chip.seated { background: #eef6e6; border-color: #6a8f4e; color: #4c6b38; }
.seat-chip-ghost {
  position: fixed; z-index: 1000; pointer-events: none;
  opacity: .85; box-shadow: var(--shadow);
}

/* ---------- family tree ---------- */
.fam-card { margin-bottom: 14px; }
.fam-card-head { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.fam-card-head input { margin: 0; font-weight: 700; flex: 1; min-width: 140px; }
.fam-card-head select { margin: 0; }
.fam-editing-badge {
  display: none;
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  padding: 3px 10px; border-radius: 999px;
  background: var(--primary); color: #fff; white-space: nowrap;
}
.fam-card-focus .fam-editing-badge,
.fam-chart-card.fam-editing .fam-editing-badge { display: inline-flex; }
.fam-card-focus,
.fam-chart-card.fam-editing {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
}
.fam-h {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px;
  margin: 16px 0 8px; font-size: 13px; color: var(--primary-dark);
  letter-spacing: .1em;
}
.fam-scroll-wrap { position: relative; }
.fam-scroll {
  width: 100%; max-width: 100%; overflow-x: auto;
  padding: 4px 0 8px; -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.fam-scroll-wrap::before,
.fam-scroll-wrap::after {
  content: "";
  position: absolute;
  top: 4px; bottom: 8px;
  width: 28px;
  pointer-events: none;
  z-index: 1;
  opacity: 0;
  transition: opacity .15s;
}
.fam-scroll-wrap::before {
  left: 0;
  background: linear-gradient(to right, var(--card), transparent);
}
.fam-scroll-wrap::after {
  right: 0;
  background: linear-gradient(to left, var(--card), transparent);
}
.fam-scroll-wrap.can-left::before,
.fam-scroll-wrap.can-right::after { opacity: 1; }
.fam-pan-hint { display: none; }
.fam-view-bar { display: flex; justify-content: center; margin: 0 0 10px; }
.fam-view-seg { display: flex; width: 100%; max-width: 440px; }
.fam-view-seg .seg-btn { flex: 1; min-height: 40px; font-size: 14px; padding: 8px 10px; }
@media (max-width: 640px) {
  .fam-view-seg { max-width: none; flex-direction: column; }
  .fam-view-seg .seg-btn { min-height: 44px; font-size: 15px; width: 100%; }
}
/* Inline width is the chart's natural pixel size so a two-person tree
   never stretches into giant cards. Desktop still shrinks with
   max-width:100%. Phones drop that cap and pan sideways. */
.fam-chart { max-width: 100%; height: auto; display: block; margin: 0 auto; }
@media (max-width: 640px) {
  .fam-chart { max-width: none; }
  .fam-chart-card { padding-left: 12px; padding-right: 12px; }
  .fam-chart-card .fam-scroll-wrap {
    margin-left: -12px;
    margin-right: -12px;
  }
  .fam-scroll-wrap.fam-scroll-wide + .fam-pan-hint { display: block; }
}
.fam-link { stroke: var(--muted); stroke-width: 1.4; fill: none; }
.fam-person { cursor: pointer; }
.fam-person:focus-visible { outline: none; }
.fam-person:focus-visible > rect:first-of-type {
  stroke: var(--gold); stroke-width: 4;
}
.fam-box rect {
  fill: var(--card); stroke: var(--primary); stroke-width: 1.4;
}
.fam-box.mine rect { fill: #fdf6e6; stroke: var(--gold); stroke-width: 2.2; }
.fam-box.rsvp-yes rect { stroke: #6a8f4e; }
.fam-box.rsvp-no rect { fill: #f4f1ea; stroke: #b0a89a; }
.fam-box.rsvp-no { opacity: .78; }
.fam-box.rsvp-maybe rect { stroke: #c4a35a; stroke-dasharray: 4 3; }
.fam-box.rsvp-none rect { stroke: var(--muted); }
.fam-box.rsvp-off rect { stroke: #9aa3ad; stroke-dasharray: 2 3; }
.fam-box.fam-anchor { filter: drop-shadow(0 1px 4px rgba(196, 160, 106, .45)); }
.fam-box.fam-anchor > rect:not(.fam-anchor-halo) {
  stroke: var(--gold); stroke-width: 3.8;
}
.fam-anchor-halo {
  fill: none; stroke: var(--gold); stroke-width: 5.5; opacity: .5;
}
.fam-photo-bg { fill: #efe8d8; }
.fam-split { stroke: rgba(196, 30, 58, .14); stroke-width: 1; }
.fam-avatar-bg { fill: #efe8d8; }
.fam-avatar-ring { fill: none; stroke: var(--primary); stroke-width: 1.6; }
.fam-box.rsvp-yes .fam-avatar-ring { stroke: #6a8f4e; }
.fam-box.rsvp-no .fam-avatar-ring { stroke: #b0a89a; }
.fam-initial { text-anchor: middle; font-size: 36px; font-weight: 700; fill: var(--primary-dark); }
.fam-name {
  text-anchor: middle; font-size: 13px; font-weight: 700; fill: var(--text);
}
.fam-kana { text-anchor: middle; font-size: 10px; fill: var(--muted); }
.fam-nick { text-anchor: middle; font-size: 10px; font-style: italic; fill: var(--primary-dark); }
.fam-note { text-anchor: middle; font-size: 11px; fill: var(--muted); }
.fam-rsvp { text-anchor: middle; font-size: 9px; font-weight: 700; fill: var(--primary-dark); }
.fam-box.rsvp-no .fam-rsvp { fill: #8a8174; }
.fam-legend { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 0; }
.fam-lg {
  font-size: 11px; padding: 2px 8px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--card);
}
.fam-lg.rsvp-yes { border-color: #6a8f4e; background: #eef6e6; }
.fam-lg.rsvp-no { border-color: #b0a89a; background: #f4f1ea; color: #6f6759; }
.fam-lg.rsvp-maybe { border-color: #c4a35a; background: #fdf6e6; }
.fam-lg.rsvp-none { color: var(--muted); }
.fam-lg.rsvp-off { border-style: dashed; color: #6f7a86; }
.fam-rows { display: grid; gap: 10px; }
.fam-row {
  display: grid; gap: 6px; align-items: center;
  grid-template-columns: auto repeat(3, minmax(110px, 1fr));
}
.fam-row input, .fam-row select { margin: 0; font-size: 13px; padding: 6px 8px; }
.fam-shownick-lab {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; margin: 0; cursor: pointer; white-space: nowrap;
}
.fam-shownick-lab input { width: auto; margin: 0; }
.fam-row-id { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.fam-row .photo-pick { flex-direction: column; align-items: center; }
.fam-row .photo-pick-frame { width: 56px; height: 74px; }
.fam-row .photo-pick-actions { flex-direction: column; }
.fam-thumb {
  width: 36px; height: 36px; border-radius: 50%; object-fit: cover;
  border: 1.5px solid var(--primary); background: #efe8d8;
}
.fam-thumb.empty {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: var(--primary-dark);
}
.fam-add-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; align-items: center; }
.fam-add-row select { margin: 0; max-width: 280px; }
/* connect-lines mode, inline link panel and drag-to-chart (admin) */
.fam-chart-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.fam-connect-toggle.active { background: var(--primary); color: #fff; }
.fam-person.fam-sel > rect:first-of-type { stroke: var(--gold); stroke-width: 4; }
.fam-link-panel {
  margin-top: 10px; padding: 10px 12px; border: 1px dashed var(--primary);
  border-radius: 10px; background: rgba(196, 30, 58, .04);
}
.fam-link-panel .fam-h { margin-top: 0; }
.fam-link-fields { display: flex; flex-wrap: wrap; gap: 10px; }
.fam-link-fields label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 12px; margin: 0; min-width: 160px;
}
.fam-link-fields select, .fam-link-fields input { margin: 0; font-size: 13px; padding: 6px 8px; }
.fam-link-rel { display: flex; gap: 6px; flex-wrap: wrap; }
.fam-link-actions { display: flex; gap: 8px; margin-top: 10px; }
.fam-drag-ghost {
  position: fixed; z-index: 1000; pointer-events: none;
  padding: 4px 12px; border-radius: 999px; border: 1px solid var(--primary);
  background: var(--card); font-size: 13px; box-shadow: var(--shadow); opacity: .9;
}
.fam-chart-card.fam-drop-hot { outline: 2px dashed var(--primary); outline-offset: -4px; }
/* pointer-event dragging needs the browser's touch gestures disabled
   on the drag handle; applied for admins only via the class */
.guest-card.draggable { touch-action: none; }
@media (max-width: 900px) {
  .fam-row { grid-template-columns: auto 1fr; }
  .fam-shownick-lab, .fam-row button { grid-column: 1 / -1; }
}

.mail-opt {
  display: flex; flex-direction: column; align-items: stretch;
  margin-top: 16px; padding-top: 14px; border-top: 1px dashed var(--border);
}
.mail-opt textarea { min-height: 72px; }
.mail-opt .meta { display: block; margin-top: 4px; }
.mail-opt.standalone { margin-top: 0; padding-top: 0; border-top: none; }
.mail-opt-row {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: flex-start; gap: 10px 12px; width: 100%;
}
.mail-opt-row .aud-item { flex: 0 1 auto; min-width: 0; }
.mail-opt-row #mail-save { flex: 0 0 auto; margin: 0; }
.notify-box {
  margin: 12px 0 4px; padding: 10px 12px;
  background: #faf7ef; border: 1px solid var(--border); border-radius: 8px;
}
.notify-who { margin-top: 8px; }
.notify-box .btn { margin-top: 8px; }

/* ---------- toast ---------- */
/* HIG: pill shape over a blurred translucent plate, entering with a
   short fade-up from below. */
@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
.toast {
  position: fixed; bottom: 90px; left: 50%; transform: translateX(-50%);
  background: rgba(43, 42, 38, .82); color: #fdfaf2; padding: 12px 22px;
  border-radius: 999px; font-size: 15px; font-weight: 600; z-index: 200;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .35);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  max-width: calc(100% - 24px);
  text-align: center;
  animation: toast-in .25s ease-out;
}
.toast.error { background: rgba(181, 68, 44, .88); }
.toast.ok { background: rgba(74, 98, 58, .88); }

/* Bottom-sheet entry (used by the ≤640px overlay rules below). */
@keyframes sheet-up {
  from { opacity: .5; transform: translateY(24px); }
  to { opacity: 1; transform: none; }
}

/* HIG accessibility: every decorative motion added in this pass is
   disabled under prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) {
  .view.active, .toast,
  .q-modal-card, .person-sheet-card, .face-adjust-card, .lightbox img {
    animation: none !important;
  }
  .btn:active, .nav-btn:active, .poll-btn:active, .seg-btn:active,
  .side-btn:active, .q-fab:active, .guest-card:active {
    transform: none;
  }
  .card:hover, .home-panel:hover, .gallery-item:hover,
  .album-card:hover, .guest-card:hover, .q-fab:hover {
    transform: none;
  }
}

@media (max-width: 640px) {
  /* Every text control at 16px: below that iOS Safari zooms the page
     on focus (and keeps the zoom). !important because many controls
     carry class-level sizes (13-14px) that would win over an element
     selector - those were still triggering the zoom. */
  input, select, textarea { font-size: 16px !important; }
  .hub-back { font-size: 12px; padding: 6px 8px; }
  .form-grid { grid-template-columns: 1fr; }
  .home-grid { grid-template-columns: 1fr; }
  /* Guest registry rows: photo on top, then one field per line -
     two 13px columns squeezed next to the photo were unusable. */
  .ppl-row { grid-template-columns: 1fr; }
  .ppl-fields { grid-template-columns: 1fr; }
  .ppl-row input, .ppl-row select, .ppl-row textarea { font-size: 16px; }
  .ppl-row > .btn { grid-column: 1 / -1; justify-self: end; }
  /* Room assignment on phones: chips become full-width rows with the
     picker below the name, instead of pills squeezed side by side. */
  .room-pool { display: block; }
  .room-pool .rm-chip {
    display: flex; flex-wrap: wrap; align-items: center;
    width: 100%; box-sizing: border-box; margin: 6px 0;
    border-radius: 10px; padding: 8px 12px;
  }
  .room-pool .rm-chip .rm-assign { flex: 1 1 100%; margin: 6px 0 0; max-width: none; }
  .room-head { flex-wrap: wrap; }
  .room-occupants .rm-chip { max-width: 100%; }
  /* Decoration-to-content ratio on small screens: slimmer headings
     and knots so the content keeps the room. */
  .view h2 { font-size: 24px; letter-spacing: .08em; }
  .mizu.bar { height: 34px; width: min(300px, 88%); }
  .mizu.knot { width: 28px; height: 28px; }
  .side-btn { padding: 10px 12px; font-size: 14px; }
  /* Wide tables scroll inside the page instead of stretching it. */
  .table { display: block; width: 100%; max-width: 100%; overflow-x: auto; }
  /* Action cells (edit/delete) may wrap on phones so the schedule list
     does not need a sideways scroll just for its buttons. */
  .row-actions { white-space: normal; }
  .row-actions .btn, .row-actions select { margin-top: 4px; }
  .invite-grid { grid-template-columns: 1fr; }
  /* Groom and bride stay SIDE BY SIDE on phones - smaller photos and
     tighter cards instead of stacking one above the other. */
  .hosts { grid-template-columns: 1fr auto 1fr; gap: 6px 8px; }
  .hosts.n1 { grid-template-columns: 1fr; justify-items: center; }
  .hosts.n1 .host-card { width: min(280px, 100%); }
  .host-card { padding: 8px 6px 10px; }
  .host-card img, .host-photo { max-height: 150px; margin-bottom: 6px; }
  .host-card strong { font-size: 14px; letter-spacing: .06em; }
  .host-photo.empty { font-size: 30px; }
  .hosts .host-heart { width: 26px; height: 26px; }
  .map-canvas { height: 300px; max-width: 100%; }
  /* HIG bottom sheets: on phones the overlays rise from the bottom
     edge - 16px top corners, a centred grabber bar, 250ms slide-up. */
  .q-modal { padding: 0; align-items: flex-end; justify-content: center; }
  .person-sheet, .face-adjust { align-items: flex-end; padding: 0; }
  .q-modal-card, .person-sheet-card, .face-adjust-card {
    max-width: 100%;
    border-radius: 16px 16px 0 0;
    border-bottom: none;
    padding-top: 26px;
    animation: sheet-up .25s ease-out;
  }
  .q-modal-card::before, .person-sheet-card::before, .face-adjust-card::before {
    content: ""; position: absolute; top: 8px; left: 50%;
    transform: translateX(-50%);
    width: 36px; height: 5px; border-radius: 999px;
    background: rgba(60, 42, 30, .22);
  }
  /* The lightbox stays a centred viewer; it only shares the 250ms
     rise-in so it does not pop. */
  .lightbox img { animation: sheet-up .25s ease-out; }
  .cal-cell { min-height: 60px; }
  .chip { font-size: 9px; }
  header { gap: 6px; row-gap: 6px; padding: 8px 12px; }
  .brand {
    font-size: 14px; letter-spacing: .06em; padding-left: 8px;
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .header-right { margin-left: auto; gap: 6px; min-width: 0; flex-shrink: 1; }
  .home-hero h2 { font-size: 24px; letter-spacing: .08em; overflow-wrap: anywhere; }
  main { overflow-x: hidden; overflow-x: clip; }
  .lang-select { padding: 4px 6px; font-size: 11px; }
  .user-name { font-size: 12px; }
  /* Tabs stay inside the phone width. They scroll inside the nav,
     not the whole page (iPhone 12 was shifting left/right). */
  #main-nav {
    order: 3; flex: 1 1 100%; flex-wrap: nowrap;
    min-width: 0; width: 100%; max-width: 100%;
    overflow-x: auto; overflow-y: hidden;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
    touch-action: pan-x;
  }
  #main-nav::-webkit-scrollbar { display: none; }
  /* Mobile-first ergonomics: every tap target at least ~44px tall
     (tabs and buttons were 30-33px), roomier cards, and the content
     column gets breathing room above the thumb zone. */
  .nav-btn { flex: 0 0 auto; padding: 12px 14px; font-size: 15px; min-height: 44px; }
  .btn { min-height: 44px; }
  .btn.small { min-height: 36px; }
  .card { border-radius: 12px; }
  main { padding: 16px 12px 80px; }
  .home-hero { padding: 32px 16px; }
  .card { padding: 16px; }
  .cd-num { font-size: 38px; }
  .cal-toolbar { flex-direction: row; align-items: center; }
  .gantt-row { grid-template-columns: 96px 1fr; }
  .trip-modal { align-items: flex-end; padding: 0; }
  .trip-modal-card { max-width: 100%; border-radius: 16px 16px 0 0; }
  .trip-dl { grid-template-columns: 6.2em 1fr; }
  .seat-fix-row { grid-template-columns: 1fr; }
  .where-grid { grid-template-columns: 1fr; }
  .gallery-grid, .album-grid, .guest-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }
  .invite-card { padding: 20px 16px; }
  .rsvp-member {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 6px;
    padding: 10px 0 4px;
  }
  .rsvp-name { grid-column: 1 / -1; }
  .rsvp-member .btn, .rsvp-row .btn, .pending-btns .btn {
    width: 100%;
    padding: 9px 4px;
    font-size: 13px;
    white-space: nowrap;
  }
  .rsvp-row, .pending-btns {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    width: 100%;
    gap: 6px;
  }
  .poll-choices { display: grid; grid-template-columns: 1fr 1fr; width: 100%; }
  .poll-btn { width: 100%; justify-content: center; }
}

@media (max-width: 480px) {
  /* Keeps the brand and the controls on one row on phones. */
  .user-name { display: none; }
  .fam-row { grid-template-columns: 1fr; }
  .cd-num { font-size: 32px; }
}

/* ---------- photo upload frames ---------- */
.photo-pick { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; position: relative; z-index: 1; }
.photo-pick-frame {
  width: 72px; height: 96px; flex: 0 0 auto;
  border: 1px solid var(--border);
  background: var(--accent); overflow: hidden;
  border-radius: 4px;
}
.photo-pick.wide .photo-pick-frame { width: 160px; height: 90px; }
.photo-pick-frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-pick-empty {
  display: flex; align-items: center; justify-content: center;
  height: 100%; padding: 6px; text-align: center;
  font-size: 11px; color: var(--muted); letter-spacing: .08em;
}
.photo-pick-actions { display: flex; flex-direction: column; gap: 6px; position: relative; z-index: 2; width: max-content; max-width: 100%; }
.photo-pick-actions .btn { margin: 0; width: auto; white-space: nowrap; }
/* Author `label input { display:block }` beats the UA [hidden] rule, so
   the native file control was showing and stretching the photo column. */
.photo-pick-file,
.photo-pick-actions input[type="file"] {
  display: none !important;
  width: auto;
  margin: 0;
}
.photo-pick-actions > label.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  margin: 0;
  white-space: nowrap;
}
.mood-slots { display: flex; flex-wrap: wrap; gap: 14px; margin: 10px 0; }
.mood-slot {
  display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
  padding: 8px;
  border: 1px dashed var(--gold-soft);
  background: #fff;
  border-radius: 8px;
}
.mood-slot .photo-pick-frame { width: 90px; height: 120px; }

/* ---------- guests tab ---------- */
.side-toggle {
  display: flex; justify-content: center; gap: 0; margin: 0 0 18px;
  border: 1px solid var(--aka);
  background: #fff; overflow: hidden; border-radius: 8px;
  scroll-margin-top: 72px;
}
.side-btn {
  flex: 1; border: none; background: #fff; color: var(--aka);
  padding: 12px 16px; font-size: 16px; letter-spacing: .18em;
  font-family: var(--font); cursor: pointer;
}
.side-btn + .side-btn { border-left: 1px solid var(--aka); }
.side-btn:active { transform: scale(.97); }
.side-btn.active { background: var(--aka); color: #fff; font-weight: 700; }
.guest-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 14px; margin-top: 10px;
}
.guest-card {
  display: flex; flex-direction: column; align-items: center;
  gap: 8px; padding: 12px 8px 14px;
  background: #fff; color: inherit; font: inherit; text-align: center;
  cursor: pointer;
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  transition: transform .15s;
}
.guest-card:hover { transform: translateY(-2px); }
.guest-card:active { transform: scale(.98); }
.guest-card img, .guest-av {
  width: 72px; height: 72px; border-radius: 50%; object-fit: cover;
  border: 1px solid var(--border); background: var(--accent);
}
.guest-av {
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font); font-size: 22px; color: var(--primary-dark);
}
.guest-card strong { font-size: 14px; letter-spacing: .08em; }
.fam-person { cursor: pointer; }
.fam-chart .fam-person:hover .fam-avatar-ring { stroke: var(--aka); stroke-width: 2.5; }

.person-sheet {
  position: fixed; inset: 0; z-index: 96;
  background: rgba(80, 20, 28, .4); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.person-sheet-card {
  background: #fff; width: 100%; max-width: 420px;
  max-height: 85vh; overflow-y: auto; padding: 20px 20px 16px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  border-radius: 16px;
  position: relative;
}
.person-sheet-close {
  position: absolute; top: 10px; right: 10px;
}
.person-sheet-photo {
  width: 140px; height: 180px; object-fit: cover; display: block;
  margin: 8px auto 14px;
  border: 1px solid var(--border);
  border-radius: 4px;
}
.person-sheet-photo.empty {
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); font-size: 42px;
  font-family: var(--font); color: var(--primary-dark);
}
.person-sheet-card h3 {
  text-align: center; margin: 0 0 4px; letter-spacing: .14em;
}
.person-sheet-card .meta { text-align: center; display: block; }
.person-sheet-bio { font-size: 14px; line-height: 1.8; margin: 12px 0 0; }

/* ---------- seating usability (v5) ---------- */
.seat-tip {
  position: fixed; z-index: 1200; pointer-events: none;
  background: #fff; border: 1px solid var(--border); border-radius: 6px;
  box-shadow: var(--shadow); padding: 6px 10px;
  font-size: 12px; line-height: 1.6; max-width: 240px;
}
.seat-tip strong { display: block; margin-bottom: 2px; }
.seat-slot {
  fill: none; stroke: var(--gold); stroke-width: .04;
  stroke-dasharray: .1 .08; opacity: .5; pointer-events: none;
}
.seat-slot.active { opacity: 1; stroke-width: .08; }

/* ---------- admin guest registry (v5) ---------- */
.ppl-side-toggle { margin: 0 0 12px; }
.ppl-fold-count {
  margin-left: auto; font-weight: 400; color: var(--muted); font-size: 13px;
}
.ppl-fold .ppl-fold-rows { padding: 4px 12px 0; }
.ppl-fold .ppl-add-group { margin: 8px 12px 12px; }

/* ---------- seasonal petal themes (v5) ----------
   One class on #view-home (set from the admin home settings) swaps the
   petal ILLUSTRATIONS of the envelope scene and lays the same motif,
   very faintly, over the invitation paper and the page surface below.
   Spring (sakura) is the default. Artwork per season:
     sakura = notched cherry petal / summer = young leaf with a vein /
     autumn = maple (momiji) leaf / winter = six-arm snowflake. */
.season-sakura {
  /* A full five-petal cherry blossom (notched petals, gold centre) -
     unmistakably sakura even at 26px. */
  --petal-img: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g fill='%23e2879b' fill-opacity='.92' stroke='%23c95f77' stroke-width='.5'><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(72 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(144 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(216 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(288 12 12)'/></g><circle cx='12' cy='12' r='1.5' fill='%23d9b36a'/></svg>");
  --petal-img2: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g fill='%23f0b6c3' fill-opacity='.9' stroke='%23d98ba0' stroke-width='.5'><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(72 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(144 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(216 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(288 12 12)'/></g><circle cx='12' cy='12' r='1.5' fill='%23c41e3a'/></svg>");
}
.season-summer {
  /* A young leaf with a midrib, side veins and a little stem. */
  --petal-img: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 1.5 C18.5 6.5 18.5 15.5 12 21 C5.5 15.5 5.5 6.5 12 1.5 Z' fill='%235a8f4e' fill-opacity='.85' stroke='%23477a3c' stroke-width='.6'/><g stroke='%23eef6e8' stroke-width='.9' fill='none'><path d='M12 4 V20'/><path d='M12 8 L8.5 11 M12 8 L15.5 11'/><path d='M12 12.5 L9 15 M12 12.5 L15 15'/></g><path d='M12 21 L12 23.5' stroke='%23477a3c' stroke-width='1.2'/></svg>");
  --petal-img2: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 1.5 C18.5 6.5 18.5 15.5 12 21 C5.5 15.5 5.5 6.5 12 1.5 Z' fill='%238fac74' fill-opacity='.85' stroke='%236a8f4e' stroke-width='.6'/><g stroke='%23f2f7ec' stroke-width='.9' fill='none'><path d='M12 4 V20'/><path d='M12 8 L8.5 11 M12 8 L15.5 11'/><path d='M12 12.5 L9 15 M12 12.5 L15 15'/></g><path d='M12 21 L12 23.5' stroke='%236a8f4e' stroke-width='1.2'/></svg>");
}
.season-autumn {
  /* A real momiji silhouette: seven slim pointed lobes fanning
     upward from the base with deep notches between them, light
     veins running base-to-tip, and a curved petiole - reads as a
     Japanese maple, not an abstract star. */
  --petal-img: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8.8 13.5 L5.8 12.5 L8.6 12 L4.9 8.4 L9.6 10.5 L7.1 4 L11.1 9.7 L12 1.8 L12.9 9.7 L16.9 4 L14.4 10.5 L19.1 8.4 L15.4 12 L18.2 12.5 L15.2 13.5 L12 14.6 Z' fill='%23c8552a' fill-opacity='.95' stroke='%23a34620' stroke-width='.4' stroke-linejoin='round'/><g stroke='%23f7e3d2' stroke-opacity='.75' stroke-width='.55' fill='none'><path d='M12 13.2 L12 2.6 M12 13.2 L7.5 4.8 M12 13.2 L5.6 8.8 M12 13.2 L6.5 12.3 M12 13.2 L16.5 4.8 M12 13.2 L18.4 8.8 M12 13.2 L17.5 12.3'/></g><path d='M12 14.6 C11.9 16.8 11.5 19.4 11 21.8' stroke='%23a34620' stroke-width='1.1' fill='none' stroke-linecap='round'/></svg>");
  --petal-img2: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8.8 13.5 L5.8 12.5 L8.6 12 L4.9 8.4 L9.6 10.5 L7.1 4 L11.1 9.7 L12 1.8 L12.9 9.7 L16.9 4 L14.4 10.5 L19.1 8.4 L15.4 12 L18.2 12.5 L15.2 13.5 L12 14.6 Z' fill='%23b3413f' fill-opacity='.93' stroke='%23922f2e' stroke-width='.4' stroke-linejoin='round'/><g stroke='%23f2d9d5' stroke-opacity='.7' stroke-width='.55' fill='none'><path d='M12 13.2 L12 2.6 M12 13.2 L7.5 4.8 M12 13.2 L5.6 8.8 M12 13.2 L6.5 12.3 M12 13.2 L16.5 4.8 M12 13.2 L18.4 8.8 M12 13.2 L17.5 12.3'/></g><path d='M12 14.6 C11.9 16.8 11.5 19.4 11 21.8' stroke='%23922f2e' stroke-width='1.1' fill='none' stroke-linecap='round'/></svg>");
}
.season-winter {
  /* A six-arm snowflake with side branches on every arm. */
  --petal-img: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g stroke='%23ffffff' stroke-width='1.7' stroke-linecap='round' fill='none'><path d='M12 1.5 V22.5 M2.9 6.75 L21.1 17.25 M21.1 6.75 L2.9 17.25'/><path d='M12 4.5 L9.8 6.6 M12 4.5 L14.2 6.6 M12 19.5 L9.8 17.4 M12 19.5 L14.2 17.4'/><path d='M5.2 8.1 L5.4 11.1 M5.2 8.1 L8.1 7.3 M18.8 15.9 L18.6 12.9 M18.8 15.9 L15.9 16.7'/><path d='M18.8 8.1 L15.9 7.3 M18.8 8.1 L18.6 11.1 M5.2 15.9 L8.1 16.7 M5.2 15.9 L5.4 12.9'/></g><circle cx='12' cy='12' r='1.4' fill='%23ffffff'/></svg>");
  --petal-img2: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><g stroke='%23bcd4e8' stroke-width='1.7' stroke-linecap='round' fill='none'><path d='M12 1.5 V22.5 M2.9 6.75 L21.1 17.25 M21.1 6.75 L2.9 17.25'/><path d='M12 4.5 L9.8 6.6 M12 4.5 L14.2 6.6 M12 19.5 L9.8 17.4 M12 19.5 L14.2 17.4'/><path d='M5.2 8.1 L5.4 11.1 M5.2 8.1 L8.1 7.3 M18.8 15.9 L18.6 12.9 M18.8 15.9 L15.9 16.7'/><path d='M18.8 8.1 L15.9 7.3 M18.8 8.1 L18.6 11.1 M5.2 15.9 L8.1 16.7 M5.2 15.9 L5.4 12.9'/></g><circle cx='12' cy='12' r='1.4' fill='%23bcd4e8'/></svg>");
}
.season-winter .env-petal { filter: drop-shadow(0 0 4px rgba(170, 195, 220, .7)); }
.season-winter .env-depth.back .env-petal { filter: blur(1.5px) drop-shadow(0 0 4px rgba(170, 195, 220, .7)); }
/* The soft blush the page background wears (red corner glows + a warm
   gold breath), repeated INSIDE the invitation paper so the letter
   and the page behind it share the same colouring. */
:root {
  --paper-wash:
    radial-gradient(760px 340px at 88% -6%, rgba(196, 30, 58, .07), transparent 58%),
    radial-gradient(620px 300px at -6% 8%, rgba(196, 30, 58, .05), transparent 52%),
    radial-gradient(520px 380px at 34% 30%, rgba(201, 162, 75, .09), transparent 62%);
}
/* The same artwork, whisper-faint, on the invitation paper and the
   page surface below - the season carries through the whole letter. */
.season-sakura .letter-main, .season-sakura .env-letter {
  background-image: var(--paper-wash), url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='260' height='220'><g transform='translate(34 42) rotate(20)' fill='%23c41e3a' fill-opacity='.06'><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(72 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(144 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(216 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(288 12 12)'/></g><g transform='translate(178 138) rotate(-35) scale(.85)' fill='%23c41e3a' fill-opacity='.05'><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(72 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(144 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(216 12 12)'/><path d='M12 12 C10 9 9.5 6 10.5 4 C11 3 12 3.6 12 4.6 C12 3.6 13 3 13.5 4 C14.5 6 14 9 12 12 Z' transform='rotate(288 12 12)'/></g></svg>");
}
.season-summer .letter-main, .season-summer .env-letter {
  background-image: var(--paper-wash), url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='260' height='220'><g transform='translate(34 42) rotate(38)'><path d='M12 2 C19 7 19 17 12 22 C5 17 5 7 12 2 Z' fill='%235a8f4e' fill-opacity='.055'/></g><g transform='translate(178 138) rotate(-30) scale(.9)'><path d='M12 2 C19 7 19 17 12 22 C5 17 5 7 12 2 Z' fill='%234a7d5c' fill-opacity='.05'/></g></svg>");
}
.season-autumn .letter-main, .season-autumn .env-letter {
  background-image: var(--paper-wash), url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='260' height='220'><g transform='translate(34 42) rotate(18)'><path d='M8.8 13.5 L5.8 12.5 L8.6 12 L4.9 8.4 L9.6 10.5 L7.1 4 L11.1 9.7 L12 1.8 L12.9 9.7 L16.9 4 L14.4 10.5 L19.1 8.4 L15.4 12 L18.2 12.5 L15.2 13.5 L12 14.6 Z M12 14.6 C11.9 16.8 11.5 19.4 11 21.8 L11.9 22 C12.3 19.5 12.6 17 12.7 14.7 Z' fill='%23c65f2e' fill-opacity='.07'/></g><g transform='translate(178 138) rotate(-58) scale(.85)'><path d='M8.8 13.5 L5.8 12.5 L8.6 12 L4.9 8.4 L9.6 10.5 L7.1 4 L11.1 9.7 L12 1.8 L12.9 9.7 L16.9 4 L14.4 10.5 L19.1 8.4 L15.4 12 L18.2 12.5 L15.2 13.5 L12 14.6 Z M12 14.6 C11.9 16.8 11.5 19.4 11 21.8 L11.9 22 C12.3 19.5 12.6 17 12.7 14.7 Z' fill='%23b3413f' fill-opacity='.06'/></g></svg>");
}
.season-winter .letter-main, .season-winter .env-letter {
  background-image: var(--paper-wash), url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='260' height='220'><g transform='translate(34 42)' stroke='%23aac3dc' stroke-opacity='.14' stroke-width='1.4' stroke-linecap='round' fill='none'><path d='M12 2 V22 M2 12 H22 M4.9 4.9 L19.1 19.1 M19.1 4.9 L4.9 19.1'/></g><g transform='translate(178 138) scale(.8)' stroke='%23aac3dc' stroke-opacity='.12' stroke-width='1.4' stroke-linecap='round' fill='none'><path d='M12 2 V22 M2 12 H22 M4.9 4.9 L19.1 19.1 M19.1 4.9 L4.9 19.1'/></g></svg>");
}

/* ---------- in-app lightbox (v5) ---------- */
.lightbox {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(30, 10, 14, .82); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  cursor: zoom-out; padding: 24px;
}
.lightbox img {
  max-width: 94vw; max-height: 90vh; max-height: 90dvh;
  object-fit: contain; border-radius: 4px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .5);
  background: #fff; padding: 6px;
}
.lightbox-close {
  position: absolute; top: 14px; right: 16px;
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .5);
  background: rgba(0, 0, 0, .35); color: #fff;
  font-size: 22px; line-height: 1; cursor: pointer;
}
.lightbox-close:hover { background: rgba(0, 0, 0, .55); }
/* The prints/photos invite the tap. */
.mood-fig img, .gallery-strip .gallery-item img { cursor: zoom-in; }

/* ---------- face-position adjuster (v5) ----------
   Modal overlay opened from a guest row's photo picker: the admin
   drags/zooms the photo so the face lands inside the 5:4 frame the
   relationship chart uses. */
.photo-pick-face-badge {
  font-size: 11px; color: var(--muted); letter-spacing: .06em;
  text-align: center;
}
.face-adjust {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(30, 10, 14, .82); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.face-adjust-card {
  position: relative;
  background: #fff; width: 100%; max-width: 380px;
  max-height: 92vh; max-height: 92dvh; overflow-y: auto;
  padding: 18px 18px 16px;
  border: 1px solid var(--border); border-radius: 16px;
  box-shadow: var(--shadow);
}
.face-adjust-card h3 { margin: 0 0 4px; text-align: center; letter-spacing: .12em; }
.face-adjust-card > .note { text-align: center; margin: 0 0 10px; }
.face-adjust-stage {
  position: relative; overflow: hidden;
  width: 100%; aspect-ratio: 5 / 4;
  background: #222; border-radius: 8px;
  touch-action: none; cursor: grab;
}
.face-adjust-stage:active { cursor: grabbing; }
.face-adjust-img {
  position: absolute; top: 0; left: 0;
  transform-origin: 0 0; max-width: none;
  user-select: none; -webkit-user-drag: none;
  visibility: hidden;
}
.face-adjust-img.ready { visibility: visible; }
/* The crop frame: everything outside it is dimmed by a huge
   box-shadow, so only the 5:4 window shows the photo at full
   strength - the same area the chart will display. */
.face-adjust-mask {
  position: absolute; inset: 0; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
}
.face-adjust-frame {
  width: 72%; aspect-ratio: 5 / 4;
  border: 2px solid #fff; border-radius: 10px;
  box-shadow: 0 0 0 999px rgba(20, 8, 10, .55);
}
.face-adjust-zoom-lab {
  display: flex; align-items: center; gap: 10px;
  margin: 12px 0 4px; font-size: 13px; color: var(--muted);
}
.face-adjust-zoom { flex: 1; }
.face-adjust-actions {
  display: flex; gap: 8px; justify-content: center; margin-top: 10px;
}
.face-adjust-close {
  position: absolute; top: 10px; right: 10px;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid var(--border);
  background: #fff; color: inherit;
  font-size: 18px; line-height: 1; cursor: pointer;
}
.face-adjust-close:hover { background: var(--accent); }

/* ---------- gallery comments (v5) ---------- */
.gal-cmt-btn { align-self: flex-start; }
.gal-cmt-panel {
  border-top: 1px dashed var(--gold-soft);
  margin-top: 4px; padding-top: 6px;
  display: flex; flex-direction: column; gap: 6px;
}
.gal-cmt-panel.hidden { display: none; }
.gal-cmt-list {
  max-height: 200px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 6px;
}
.gal-cmt {
  background: var(--accent); border-radius: 6px;
  padding: 5px 8px; font-size: 12px; line-height: 1.5;
  display: flex; flex-direction: column; gap: 1px;
}
.gal-cmt-text { word-break: break-word; white-space: pre-wrap; }
.gal-cmt .meta {
  font-size: 11px;
  display: flex; align-items: center; gap: 6px;
}
.gal-cmt-del {
  border: none; background: none; padding: 0 3px;
  color: var(--danger); font-size: 13px; line-height: 1; cursor: pointer;
}
.gal-cmt-del:hover { color: var(--primary-dark); }
.gal-cmt-form { display: flex; gap: 6px; }
.gal-cmt-input { flex: 1; min-width: 0; font-size: 12px; }

/* ---------- admin tab: clean tool UI (v5) ----------
   The guest-facing pages keep the full "wa" decoration (Noto Sans JP,
   crimson & gold, mizuhiki knots). The admin tab is a working tool,
   so inside #view-admin ONLY we switch to a plain utilitarian look:
   system fonts, light grey surface, flat white cards, one accent
   colour (the existing --primary crimson) and grey everything else.
   Every selector is prefixed with #view-admin so no other tab can be
   affected. helpers.js (waTitle/waSec/mizuhiki) is untouched - the
   decorations are neutralised purely in CSS. */

#view-admin {
  /* Grey work surface. The negative margins cancel out <main>'s
     padding so the grey fills the whole content column; the padding
     puts the breathing room back inside the grey. */
  background: #f5f5f5;
  margin: -24px -18px -70px;
  padding: 24px 18px 48px;
  letter-spacing: normal;
}
#view-admin,
#view-admin h1, #view-admin h2, #view-admin h3, #view-admin h4, #view-admin h5,
#view-admin button, #view-admin input, #view-admin select,
#view-admin textarea, #view-admin summary {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Noto Sans JP", sans-serif;
}

/* Decorations off: no mizuhiki knots, headings become plain labels. */
#view-admin .mizu { display: none; }
#view-admin .wa-title {
  align-items: flex-start;
  gap: 0;
  margin: 0 0 18px;
}
#view-admin .wa-title h2 {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: normal;
  color: #363636;
}
#view-admin .wa-sec {
  justify-content: flex-start;
  gap: 0;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: normal;
  color: #4a4a4a;
  margin: 0 0 10px;
}
#view-admin .view h3, #view-admin h4 {
  letter-spacing: normal;
  color: #4a4a4a;
}

/* Flat white cards. */
#view-admin .card {
  background: #fff;
  border: 1px solid #e4e4e4;
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .05);
  padding: 20px;
  margin-bottom: 18px;
  transition: none;
}
#view-admin .card:hover { transform: none; }

/* Buttons: white + hairline border; primary is the one flat accent. */
#view-admin .btn {
  background: #fff;
  border: 1px solid #dbdbdb;
  color: #363636;
  border-radius: 6px;
  letter-spacing: normal;
  box-shadow: none;
}
#view-admin .btn:hover { background: #f7f7f7; border-color: #c9c9c9; }
#view-admin .btn.primary {
  background: var(--primary);
  border: 1px solid var(--primary);
  color: #fff;
  font-weight: 600;
}
#view-admin .btn.primary:hover {
  filter: none;
  background: var(--primary-dark);
  border-color: var(--primary-dark);
}
/* Danger keeps its current treatment (restated because the scoped
   .btn rule above outweighs the global .btn.danger). */
#view-admin .btn.danger {
  color: var(--danger);
  border: 1px solid rgba(181, 68, 44, .45);
  background: #fff;
}
#view-admin .btn.danger:hover { background: #faf0ec; }

/* Inputs: white, grey hairline, thin crimson focus ring. Checkbox /
   radio / range / file keep their native rendering. */
#view-admin input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
#view-admin select,
#view-admin textarea {
  background: #fff;
  border: 1px solid #dbdbdb;
  border-radius: 6px;
  padding: 10px 12px;
  font-size: 14px;
  color: #363636;
}
#view-admin input:focus,
#view-admin select:focus,
#view-admin textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(196, 30, 58, .15);
}
#view-admin label { color: #5a5a5a; }

/* Secondary text: one grey, one size (dark enough for 4.5:1 on white). */
#view-admin .note, #view-admin .meta {
  font-size: 13px;
  color: #6e6e6e;
}
#view-admin #ga-result code, #view-admin .acct-url {
  background: #f5f5f5;
  color: #4a4a4a;
  border-radius: 4px;
}

/* Collapsibles (settings-style .admin-box and guest-registry
   .ppl-fold): flat white rows, ▸ marker, 44px tap target. */
#view-admin .admin-box {
  background: #fff;
  border: 1px solid #e4e4e4;
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .05);
  padding: 0 16px;
  margin-bottom: 16px;
}
#view-admin .admin-box[open] { padding-bottom: 14px; }
#view-admin .admin-box summary {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  font-size: 14px;
  font-weight: 600;
  color: #363636;
  list-style: none;
  cursor: pointer;
}
#view-admin .admin-box summary::-webkit-details-marker { display: none; }
#view-admin .admin-box summary::before {
  content: "▸";
  color: #7a7a7a;
  font-weight: 400;
  transition: transform .15s ease;
}
#view-admin .admin-box[open] summary::before { transform: rotate(90deg); }
#view-admin .rsvp-fold {
  border: 1px solid #e4e4e4;
  border-radius: 8px;
  background: #fff;
  margin: 0 0 10px;
}
#view-admin .rsvp-fold summary {
  min-height: 44px;
  padding: 8px 14px;
  font-weight: 600;
  color: #363636;
}
#view-admin .rsvp-fold summary::before { color: #7a7a7a; }

/* Rows and separators inside cards: grey hairlines, no dashes. */
#view-admin .ppl-row {
  background: #fafafa;
  border: 1px solid #ededed;
  border-radius: 8px;
}
#view-admin .grp-row, #view-admin .acct-row {
  border-bottom: 1px solid #f0f0f0;
}
#view-admin .grp-row:last-child, #view-admin .acct-row:last-child {
  border-bottom: none;
}
#view-admin .q-item { border-top: 1px solid #f0f0f0; }

/* Groom/bride side switch: quiet segmented control, crimson active. */
#view-admin .side-toggle {
  border: 1px solid #dbdbdb;
  border-radius: 8px;
}
#view-admin .side-btn {
  font-family: inherit;
  font-size: 14px;
  letter-spacing: normal;
  color: #4a4a4a;
  padding: 10px 16px;
}
#view-admin .side-btn + .side-btn { border-left: 1px solid #dbdbdb; }
#view-admin .side-btn.active {
  background: var(--primary);
  color: #fff;
}


/* ===== merged from _css-board.css ===== */
/* ================================================================
   board.js additions (to be merged into styles.css)
   Contact directory (連絡先一覧) under the announcements.
   ================================================================ */

/* ---- Guest display: cards in a responsive grid ------------------
   1 column on phones, 2 columns from 640px. Each card: name (+ category
   tag) then label/value rows; empty fields are not rendered at all. */
.contacts-sec { margin-top: 28px; }
.contacts-grid {
  display: grid; grid-template-columns: 1fr; gap: 14px;
}
@media (min-width: 640px) {
  .contacts-grid { grid-template-columns: 1fr 1fr; }
}
.contact-item { margin: 0; min-width: 0; }
.contact-item:hover { transform: none; }
.contact-item-head {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px;
  padding-bottom: 8px; margin-bottom: 8px;
  border-bottom: 1px solid var(--hairline);
}
.contact-name { font-size: 17px; font-weight: 700; overflow-wrap: anywhere; }
.contact-tag {
  display: inline-block; font-size: 13px; line-height: 1.2;
  padding: 3px 10px; border-radius: 999px;
  color: var(--primary-dark); background: var(--tint);
  border: 1px solid var(--border);
}
.contact-rows { margin: 0; display: grid; gap: 6px; }
.contact-row {
  display: grid; grid-template-columns: 7.5em 1fr; gap: 0 10px;
  align-items: baseline;
}
.contact-row dt {
  font-size: 15px; color: var(--muted); margin: 0;
}
.contact-row dd {
  font-size: 17px; margin: 0; line-height: 1.5; min-width: 0;
  overflow-wrap: anywhere;
}
.contact-row dd a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 400px) {
  /* Very narrow phones: label above value. */
  .contact-row { grid-template-columns: 1fr; gap: 0; }
}

/* ---- Admin editor: one card per contact, one input per line ------- */
#contacts-edit-list { display: grid; gap: 12px; margin: 8px 0; }
.contact-edit-row {
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 12px 14px; background: var(--card);
}
.contact-edit-row label { display: block; margin: 6px 0; font-size: 15px; }
.contact-edit-row label input,
.contact-edit-row label textarea {
  display: block; width: 100%; box-sizing: border-box; min-height: 44px;
  font-size: 17px; margin-top: 4px;
}
.contact-edit-row label textarea { min-height: 60px; }
.contact-req { color: var(--primary); font-size: 13px; }
.contact-edit-bar {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding-bottom: 8px; margin-bottom: 4px;
  border-bottom: 1px solid var(--hairline);
}
.contact-edit-bar .contact-edit-title { flex: 1 1 auto; min-width: 0; font-weight: 600; }
.contact-edit-bar .btn { margin-top: 0; min-width: 44px; }
.contacts-edit-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.contacts-edit-actions .btn { margin-top: 0; }
@media (max-width: 640px) {
  .contacts-edit-actions .btn { flex: 1 1 auto; }
}


/* ===== merged from _css-cal.css ===== */
/* ---------- calendar: 今日の居場所 - compact location chips + popover ----------
   Replaces the stacked details.loc-frame boxes with a wrapping row of
   small pills (place ×N). Names open in a popover anchored to the chip:
   hover on desktop, tap on touch; one open at a time. Clamped to the
   viewport by calendar.js (openLocPop sets .loc-pop left). The old
   .loc-frame / .loc-count rules can stay for any other caller. */
.loc-chips {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start;
  margin: 6px 0 2px;
}
.loc-chip-wrap { position: relative; display: inline-block; max-width: 100%; }
.loc-chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 32px; max-width: 100%;
  padding: 4px 12px 4px 14px;
  border: 1.5px solid var(--border); border-radius: 999px;
  background: var(--card); color: var(--text);
  font-family: inherit; font-size: 14px; line-height: 1.2;
  cursor: pointer; text-align: left;
  transition: background .15s, border-color .15s, transform .15s, box-shadow .15s;
}
.loc-chip:hover { box-shadow: 0 1px 4px rgba(60, 50, 30, .14); }
.loc-chip:active { transform: scale(.97); }
.loc-chip:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.loc-chip-wrap.open > .loc-chip { box-shadow: 0 0 0 3px rgba(196, 30, 58, .12); }
.loc-chip-name {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 60vw;
}
.loc-chip-n {
  flex: 0 0 auto; font-size: 12px; font-weight: 700; color: var(--primary-dark);
  padding-left: 6px; border-left: 1px solid var(--hairline);
}
.loc-chip.stay { border-color: #b8c99c; background: #f6f8ee; }
.loc-chip.move { border-color: #dcb49b; background: #faf2ea; }
.loc-chip.home { border-color: #d8d0ba; background: #f8f5ec; }
.loc-chip.stay .loc-chip-n { color: #4c6b38; }
.loc-chip.move .loc-chip-n { color: #8a4b22; }

.loc-pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  width: max-content; min-width: 200px;
  max-width: min(360px, calc(100vw - 16px));
  max-height: 60vh; overflow-y: auto;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 12px; padding: 8px 10px;
  box-shadow: 0 8px 24px rgba(60, 30, 30, .16), 0 1px 3px rgba(0, 0, 0, .08);
  display: flex; flex-direction: column; gap: 4px;
}
.loc-pop[hidden] { display: none; }
.loc-pop-row {
  display: flex; flex-direction: column; gap: 1px;
  padding: 6px 8px; border-radius: 8px;
  border: 1px solid var(--border);
}
.loc-pop-row .where-name { font-size: 14px; }
.loc-pop-row .meta { font-size: 13px; }
.loc-pop-row.stay { background: #eef2e4; border-color: #cdd8b8; }
.loc-pop-row.move { background: #f8ece4; border-color: #e5c9b8; }
.loc-pop-row.home { background: #f4f1e8; }

.home-list .loc-chips { margin-top: 4px; }

/* ---------- calendar: trip list - "pick who to edit" select ---------- */
.trip-edit-pick {
  min-height: 36px; padding: 6px 10px; font-size: 14px; font-family: inherit;
  border: 1px solid var(--border); border-radius: 10px; background: #fff;
  color: var(--primary-dark); max-width: 100%;
}
.trip-persons { display: inline; }

/* ---------- seating: unseated chips (to-do) / seated chips (collapsed) ---------- */
.seat-chips-todo { min-height: 32px; }
.seat-chips-done { margin-top: 10px; }
.seat-chips-done > summary {
  cursor: pointer; font-size: 14px; color: var(--muted);
  display: flex; align-items: center; gap: 8px; list-style: none; user-select: none;
}
.seat-chips-done > summary::-webkit-details-marker { display: none; }
.seat-chips-done > summary::before { content: "▸"; font-size: 12px; color: var(--muted); }
.seat-chips-done[open] > summary::before { content: "▾"; }
.seat-chips-done[open] > summary { margin-bottom: 8px; }
.seat-chips-n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 7px; border-radius: 999px;
  background: #eef6e6; color: #4c6b38; font-size: 12px; font-weight: 700;
}

@media (max-width: 640px) {
  .loc-chip-name { max-width: 55vw; }
  .loc-pop { min-width: 180px; }
}


/* ===== merged from _css-family.css ===== */
/* ---------- family chart: admin toolbar in the person sheet (v5) ----------
   Replaces the per-person edit rows (.fam-rows / .fam-row, now removed
   from views/family.js - their CSS blocks can be dropped on merge). */
.ps-fam-tools {
  display: grid; gap: 10px;
  padding: 12px; margin: 14px 0 12px;
  border: 1px solid var(--border); border-radius: 10px;
  background: #faf7f2;
}
.ps-fam-tools .note { margin: 0; }
.ps-fam-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.ps-fam-nick { display: grid; gap: 4px; font-size: 15px; }
.ps-fam-nick input { margin: 0; }
.ps-fam-shownick {
  display: flex; align-items: center; gap: 8px; font-size: 15px;
}
.ps-fam-shownick input { margin: 0; width: auto; min-height: 0; }


/* ===== merged from _css-gallery.css ===== */
/* ================================================================
   Gallery additions (to be merged into styles.css)
   - album strip: mandatory centre snap (no "two half photos")
   - gallery lightbox: ‹ › / swipe navigation + comments below
   - deferred reorder / bulk-select bottom bars
   - bulk-select checkbox overlays
   ================================================================ */

/* ---------- (1) album filmstrip: always one centred photo ---------- */
.gallery-strip {
  scroll-snap-type: x mandatory;
  /* Centre the snapped card inside the strip's own box. */
  scroll-padding-inline: calc((100% - min(74vw, 340px)) / 2);
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  /* Spacer so the first/last card can also rest in the centre. */
  padding-left: calc((100% - min(74vw, 340px)) / 2);
  padding-right: calc((100% - min(74vw, 340px)) / 2);
  scrollbar-width: thin;
}
.gallery-strip .gallery-item {
  scroll-snap-align: center;
  scroll-snap-stop: always;
  position: relative;
}
@media (min-width: 900px) {
  /* Desktop: the strip is wide enough for several cards; keep snapping
     but let it start flush left so the row does not look half-empty. */
  .gallery-strip {
    scroll-snap-type: x proximity;
    scroll-padding-inline: 2px;
    padding-left: 2px; padding-right: 2px;
  }
  .gallery-strip .gallery-item { scroll-snap-align: start; scroll-snap-stop: normal; }
}

/* ---------- (2) gallery lightbox ---------- */
/* The overlay itself never scrolls (so the × stays put); only the
   caption/comments area below the image does. */
.lightbox.gal-lb {
  padding: 60px 12px 12px; /* top room for the × on phones */
  align-items: flex-start;
}
@media (min-width: 640px) { .lightbox.gal-lb { padding: 24px; align-items: center; } }
.gal-lb-inner {
  cursor: default;
  width: min(100%, 720px);
  max-height: calc(100vh - 72px); max-height: calc(100dvh - 72px);
  display: flex; flex-direction: column;
  background: #fff; border-radius: 12px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .5);
  overflow: hidden;
  margin: 0 auto;
}
@media (min-width: 640px) {
  .gal-lb-inner { max-height: calc(100vh - 48px); max-height: calc(100dvh - 48px); }
}
.gal-lb-stage {
  position: relative; flex: 0 0 auto;
  background: #1c1b18;
  display: flex; align-items: center; justify-content: center;
  min-height: 160px;
  touch-action: pan-y; /* horizontal drag = swipe; vertical stays native */
  user-select: none; -webkit-user-select: none;
}
/* Override the shared .lightbox img sizing (white frame, 94vw). */
.lightbox.gal-lb .gal-lb-img {
  max-width: 100%; width: auto; height: auto;
  max-height: 60vh; max-height: 60dvh;
  object-fit: contain; padding: 0; border-radius: 0;
  background: transparent; box-shadow: none; animation: none;
  -webkit-user-drag: none;
}
.gal-lb-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .5);
  background: rgba(0, 0, 0, .35); color: #fff;
  font-size: 28px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  padding: 0 0 3px;
}
.gal-lb-nav:hover { background: rgba(0, 0, 0, .55); }
.gal-lb-nav:disabled { opacity: .25; cursor: default; }
.gal-lb-prev { left: 8px; }
.gal-lb-next { right: 8px; }
.gal-lb-pos {
  position: absolute; left: 50%; bottom: 8px; transform: translateX(-50%);
  font-size: 13px; color: #fff; background: rgba(0, 0, 0, .4);
  padding: 2px 10px; border-radius: 999px; pointer-events: none;
}
.gal-lb-below {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: 10px 14px 14px;
  display: flex; flex-direction: column; gap: 6px;
}
.gal-lb-cap { margin: 0; font-size: 15px; display: flex; flex-direction: column; gap: 2px; }
.gal-lb-cap .meta { font-size: 13px; }
.gal-lb-below .gal-cmt-panel { border-top: 1px dashed var(--gold-soft); padding-top: 8px; }
.gal-lb-below .gal-cmt-list { max-height: none; }
.gal-lb-below .gal-cmt { font-size: 15px; }
.gal-lb-below .gal-cmt-input { font-size: 16px; min-height: 44px; }

/* ---------- (3)(4) bottom action bars ---------- */
.gal-bar {
  position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 92;
  max-width: 720px; margin: 0 auto;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 10px 14px;
  background: rgba(255, 255, 255, .96); backdrop-filter: blur(6px);
  border: 1px solid var(--border); border-radius: 14px;
  box-shadow: 0 8px 28px rgba(80, 30, 40, .18);
}
.gal-bar-label { flex: 1 1 auto; font-size: 15px; font-weight: 600; color: var(--primary-dark); }
.gal-bar .btn { min-height: 44px; }
.gal-bar select { min-height: 44px; font-size: 16px; max-width: 100%; }
/* Keep the last strip/grid row reachable above the bar. */
#view-gallery.gal-has-bar { padding-bottom: 120px; }
@media (max-width: 640px) {
  .gal-bar { left: 8px; right: 8px; bottom: 8px; padding: 10px 12px; }
  .gal-bar-label { flex-basis: 100%; }
  .gal-bar .btn { flex: 1 1 auto; }
  .gal-bar select { flex: 1 1 100%; }
}

/* ---------- (4) bulk-select overlays ---------- */
.gal-sel-box {
  display: none;            /* only in selection mode */
  position: absolute; top: 8px; left: 8px; z-index: 2;
  margin: 0; width: 44px; height: 44px;
  align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .9); border-radius: 50%;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .25);
  cursor: pointer;
}
.gallery-strip.gal-selecting .gal-sel-box { display: flex; }
.gal-sel-ck { width: 24px; height: 24px; margin: 0; accent-color: var(--primary); cursor: pointer; }
.gallery-strip.gal-selecting .gallery-item img { cursor: pointer; }
.gallery-item.gal-selected { outline: 3px solid var(--primary); outline-offset: -3px; }
.gallery-item.gal-selected img, .gallery-item.gal-selected video { filter: brightness(.85); }


/* ===== merged from _css-home.css ===== */
/* ================================================================
   home.js additions (to be merged into styles.css)
   ================================================================ */

/* ---- Couple intro: equal-height cards --------------------------
   Groom and bride sit side by side (desktop AND phones). When one
   name wraps to two lines the grid row stretches both cards to the
   taller one; the card is a flex column so photo / name / bio stay
   aligned from the top. */
.hosts { align-items: stretch; }
.hosts .host-heart { align-self: center; }
.host-card {
  height: 100%;
  box-sizing: border-box;
  display: flex; flex-direction: column;
  min-width: 0;
}
.host-card img, .host-photo { flex: 0 0 auto; }
.host-card strong { flex: 0 0 auto; }

/* ---- Admin: invitation times (挙式 / 披露宴 / 二次会) ------------
   One row per time: label + hour select : minute select. */
.inv-times { display: grid; gap: 8px; margin: 4px 0 12px; }
.inv-time-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px;
}
.inv-time-label {
  flex: 0 0 5.5em; min-width: 4.5em;
  font-size: 15px; color: var(--muted);
}
.inv-time-sels { display: inline-flex; align-items: center; gap: 4px; }
.inv-time-sels select {
  width: auto; min-width: 4.6em; min-height: 44px;
  font-size: 17px; text-align: center;
}
.inv-time-colon { font-size: 17px; color: var(--muted); }
.inv-time-toggle { margin-top: 2px; }
#inv-aft-wrap { margin-left: 0; }
@media (max-width: 640px) {
  .inv-time-label { flex-basis: 100%; }
  .inv-time-sels select { flex: 1 1 auto; }
}


/* ===== header: gear menu on phones, inline controls on desktop ===== */
.hdr-menu-btn {
  display: none; /* desktop: controls are inline */
  width: 44px; height: 44px; padding: 0; margin-left: auto;
  border: none; border-radius: 50%; background: transparent;
  color: var(--primary-dark); cursor: pointer;
  align-items: center; justify-content: center;
}
.hdr-menu-btn:hover { background: var(--accent); }
.hdr-menu-btn[aria-expanded="true"] { background: rgba(196, 30, 58, .10); }
@media (max-width: 640px) {
  header { flex-wrap: wrap; align-items: center; }
  /* The event title is the biggest thing in the bar. */
  .brand {
    font-size: 19px; letter-spacing: .08em; padding-left: 10px;
    flex: 1 1 auto; order: 1; line-height: 1.3;
  }
  .hub-back { order: 0; }
  .hdr-menu-btn { display: inline-flex; order: 2; flex: 0 0 auto; }
  #main-nav { order: 3; flex-basis: 100%; }
  /* Popover under the gear: hidden until opened. */
  .header-right {
    display: none; position: absolute; right: 10px; top: calc(100% - 4px);
    flex-direction: column; align-items: stretch; gap: 8px;
    padding: 12px; min-width: 180px;
    background: #fff; border: 1px solid var(--border); border-radius: 14px;
    box-shadow: 0 10px 30px rgba(60, 30, 30, .18);
    margin-left: 0; z-index: 20;
  }
  .header-right.open { display: flex; }
  .header-right .lang-select, .header-right .btn {
    min-height: 44px; font-size: 16px; width: 100%; margin: 0;
  }
  .header-right .user-name { display: block; font-size: 13px; text-align: center; }
}

/* ===== global loading indicator ===== */
.load-bar {
  position: fixed; left: 0; right: 0; top: 0; height: 3px; z-index: 200;
  background: transparent; overflow: hidden; pointer-events: none;
}
.load-bar[hidden] { display: none; }
.load-bar span {
  position: absolute; top: 0; bottom: 0; left: -40%; width: 40%;
  background: linear-gradient(90deg, transparent, var(--primary), var(--gold), transparent);
  animation: load-slide 1.1s ease-in-out infinite;
}
@keyframes load-slide { to { left: 100%; } }
.load-note {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 200;
  max-width: calc(100vw - 32px);
  padding: 10px 16px; border-radius: 999px;
  background: rgba(255, 255, 255, .95); border: 1px solid var(--border);
  box-shadow: 0 6px 20px rgba(60, 30, 30, .15);
  font-size: 15px; color: var(--primary-dark); text-align: center;
  display: flex; align-items: center; gap: 10px;
}
.load-note[hidden] { display: none; }
.load-note::before {
  content: ""; width: 14px; height: 14px; border-radius: 50%; flex: 0 0 auto;
  border: 2px solid var(--border); border-top-color: var(--primary);
  animation: load-spin .9s linear infinite;
}
@keyframes load-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .load-bar span, .load-note::before { animation: none; }
  .load-bar span { left: 0; width: 100%; }
}


/* ===== admin: document-style TOC + collapsible sections ===== */
#view-admin .adm-layout { display: block; }
#view-admin .adm-toc {
  position: sticky; top: 104px; z-index: 6;
  display: flex; gap: 6px; align-items: center;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  padding: 8px 0 10px; margin: 0 0 10px;
  background: #f5f5f5;
  scrollbar-width: none;
}
#view-admin .adm-toc::-webkit-scrollbar { display: none; }
#view-admin .adm-toc-title { display: none; }
#view-admin .adm-toc-link {
  flex: 0 0 auto; margin: 0; cursor: pointer;
  border: 1px solid #dbdbdb; background: #fff; color: #363636;
  border-radius: 999px; padding: 7px 12px; font-size: 13px; font-weight: 600;
  min-height: 36px; line-height: 1.2;
}
#view-admin .adm-toc-link.on,
#view-admin .adm-toc-link:hover { background: #363636; color: #fff; border-color: #363636; }
@media (min-width: 900px) {
  #view-admin .adm-layout {
    display: grid;
    grid-template-columns: 168px minmax(0, 1fr);
    gap: 22px;
    align-items: start;
  }
  #view-admin .adm-toc {
    flex-direction: column; align-items: stretch; overflow: auto;
    top: 72px; max-height: calc(100vh - 88px);
    padding: 12px 10px; margin: 0;
    background: #fff; border: 1px solid #e4e4e4; border-radius: 12px;
  }
  #view-admin .adm-toc-title {
    display: block; margin: 0 0 6px; font-size: 11px; font-weight: 700;
    letter-spacing: .08em; color: #888;
  }
  #view-admin .adm-toc-link {
    width: 100%; border-radius: 8px; text-align: left; padding: 8px 10px;
  }
}
#view-admin .adm-fold-bar { display: flex; gap: 8px; margin: 0 0 12px; flex-wrap: wrap; }
#view-admin .adm-sec { margin: 0 0 14px; border: none; background: transparent; padding: 0; }
#view-admin .adm-sec-sum {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: 12px; min-height: 44px;
  background: #fff; border: 1px solid var(--border);
}
#view-admin .adm-sec-sum::-webkit-details-marker { display: none; }
#view-admin .adm-sec-sum::before {
  content: "▸"; font-size: 14px; color: var(--muted); flex: 0 0 auto;
  transition: transform .15s;
}
#view-admin .adm-sec[open] > .adm-sec-sum::before { transform: rotate(90deg); }
#view-admin .adm-sec-sum h3, #view-admin .adm-sec-sum .wa-sec { margin: 0; flex: 1 1 auto; }
#view-admin .adm-sec[open] > .adm-sec-sum { border-radius: 12px 12px 0 0; border-bottom-color: transparent; }
#view-admin .adm-sec-body { padding-top: 10px; }
#view-admin .adm-sec-body > .card:first-child { margin-top: 0; }

/* ===== admin: room overview as compact rows (no 7-column table) ===== */
.ov-rows { display: grid; gap: 8px; }
.ov-row { border: 1px solid var(--border); border-radius: 12px; padding: 10px 12px; background: #fff; }
.ov-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ov-status {
  font-size: 13px; font-weight: 700; padding: 3px 10px; border-radius: 999px;
  background: #f1f1f1; color: #555; white-space: nowrap;
}
.ov-status.ok { background: #eef6e6; color: #4c6b38; }
.ov-status.warn { background: #fff4e0; color: #8a5a12; }
.ov-status.bad { background: #fde8ea; color: var(--primary-dark); }
.ov-nums { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 4px; }
.ov-unassigned { margin-top: 4px; overflow-wrap: anywhere; }

/* ===== admin: unified "needs a room" pool ===== */
.lodging-pool { display: block; }
.lodge-pool-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.lodge-chip {
  display: flex; flex-direction: column; gap: 6px; align-items: stretch;
  width: 100%; margin: 6px 0; padding: 10px 12px;
  border-radius: 12px; border: 1px solid var(--border); background: #fff;
  /* .rm-chip is a dark pill with near-white text; this card is white,
     so the inherited text colour made the name almost invisible. */
  color: var(--text); font-size: 15px; font-weight: 400;
}
.lodge-chip strong { font-size: 16px; color: var(--text); }
.lodge-chip.st-none { border-left: 4px solid var(--primary); }
.lodge-chip.st-partial { border-left: 4px solid #d99a2b; }
.lodge-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.lodge-st {
  font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 999px;
  background: #fde8ea; color: var(--primary-dark);
}
.st-partial .lodge-st { background: #fff4e0; color: #8a5a12; }
.lodge-missing { overflow-wrap: anywhere; }
.lodge-chip .rm-assign { width: 100%; min-height: 44px; font-size: 16px; }
.lodge-done { margin: 8px 0 14px; }
.lodge-done > summary { cursor: pointer; font-size: 15px; color: var(--muted); min-height: 32px; }
.lodge-done-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.lodge-done-list .rm-chip .meta { font-size: 12px; margin-left: 4px; }

/* ===== admin: lodging nights in the guest row (several stretches) ===== */
.ppl-lodge-dates { display: grid; gap: 6px; }
.ppl-lodge-ranges { display: grid; gap: 6px; }
.ppl-lodge-range { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ppl-lodge-range input[type="date"] { flex: 1 1 120px; min-width: 0; min-height: 44px; }
.ppl-lodge-sep { color: var(--muted); flex: 0 0 auto; }
.ppl-lodge-del { flex: 0 0 auto; min-width: 36px; }
.ppl-lodge-tools { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ppl-lodge-tools .btn { margin: 0; }
.ppl-lodge-copy { min-height: 36px; font-size: 14px; max-width: 100%; }
.ppl-fold-tools { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; margin-top: 6px; }
.ppl-group-lodge {
  flex: 1 1 100%; border: 1px dashed var(--border); border-radius: 10px; padding: 8px 12px; background: #fafafa;
}
.ppl-group-lodge > summary { cursor: pointer; font-size: 14px; color: var(--muted); min-height: 32px; }
.ppl-group-lodge[open] > summary { margin-bottom: 6px; }
.ppl-group-lodge .ppl-lodge-ranges { margin-bottom: 6px; }
@media (max-width: 640px) {
  .ppl-lodge-range input[type="date"] { flex-basis: 100%; }
  .ppl-lodge-sep { display: none; }
}


/* ===== admin: registry toolbar + "lodging only" display mode ===== */
.ppl-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-bottom: 8px; }
.ppl-toolbar .side-toggle { margin: 0; }
#ppl-lodge-mode.active { background: rgba(196, 30, 58, .10); color: var(--primary-dark); border-color: var(--primary); }
/* Hide everything but name + lodging; the fields stay in the DOM so
   the save handler still reads them unchanged. */
.ppl-lodge-mode .ppl-row .photo-pick,
.ppl-lodge-mode .ppl-row .ppl-kana,
.ppl-lodge-mode .ppl-row .ppl-group,
.ppl-lodge-mode .ppl-row .ppl-home,
.ppl-lodge-mode .ppl-row .ppl-side-btn,
.ppl-lodge-mode .ppl-row .ppl-rel,
.ppl-lodge-mode .ppl-row .ppl-rel-org,
.ppl-lodge-mode .ppl-row .ppl-rel-wrap,
.ppl-lodge-mode .ppl-row .ppl-inlaw-lab,
.ppl-lodge-mode .ppl-row .ppl-childof-lab,
.ppl-lodge-mode .ppl-row .ppl-bio,
.ppl-lodge-mode .ppl-row .ppl-absent-lab,
.ppl-lodge-mode .ppl-row .ppl-del,
.ppl-lodge-mode #ppl-rows-extra,
.ppl-lodge-mode #ppl-add { display: none !important; }
.ppl-lodge-mode .ppl-row { grid-template-columns: 1fr; padding: 8px 10px; }
.ppl-lodge-mode .ppl-fields { display: grid; grid-template-columns: minmax(120px, 1fr) auto; gap: 6px 12px; align-items: center; }
.ppl-lodge-mode .ppl-fields .ppl-name { font-weight: 700; background: transparent; border-color: transparent; padding-left: 0; }
.ppl-lodge-mode .ppl-fields .ppl-lodge-dates { grid-column: 1 / -1; }
@media (max-width: 640px) {
  .ppl-lodge-mode .ppl-fields { grid-template-columns: 1fr; }
}

/* ===== unsaved-changes bar (sticky, bottom) ===== */
.dirty-bar {
  position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 92;
  max-width: 720px; margin: 0 auto;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 14px;
  background: #fff8e6; border: 1px solid #e3c98a; border-radius: 14px;
  box-shadow: 0 8px 28px rgba(80, 50, 10, .18);
}
.dirty-bar.hidden { display: none; }
.dirty-bar-label { flex: 1 1 auto; font-weight: 700; color: #7a5a12; font-size: 15px; }
.dirty-bar .btn { margin: 0; min-height: 44px; }
#view-admin.has-dirty-bar { padding-bottom: 110px; }

/* ===== admin: room card group fill + date copy ===== */
.rm-add-group { margin-top: 4px; max-width: 100%; min-height: 36px; font-size: 14px; }
#rm-copy { max-width: 100%; }

/* ===== admin: night-by-night lodging grid ===== */
.lodge-grid-box { margin: 10px 0 16px; }
.lodge-grid-box > summary { cursor: pointer; font-size: 15px; color: var(--primary-dark); min-height: 36px; font-weight: 600; }
.lodge-grid-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.lodge-grid { border-collapse: separate; border-spacing: 2px; font-size: 13px; min-width: 100%; }
.lodge-grid th { font-weight: 600; color: var(--muted); padding: 4px 6px; white-space: nowrap; text-align: center; }
.lodge-grid th.lg-name { text-align: left; position: sticky; left: 0; background: #fff; z-index: 1; color: var(--text); }
.lodge-grid td { padding: 4px 6px; text-align: center; border-radius: 6px; white-space: nowrap; min-width: 44px; background: #f6f6f6; color: #999; }
.lodge-grid td.ok { background: #eef6e6; color: #4c6b38; font-weight: 600; }
.lodge-grid td.open { background: #fde8ea; color: var(--primary-dark); font-weight: 700; }
.lodge-grid td.extra { background: #fff; border: 1px dashed var(--border); color: #888; }


/* ===== contacts editor: hours picker + closed-day chips ===== */
.contact-edit-row label .ct-hours,
.contact-edit-row label .ct-closed { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; }
.ct-hours select { min-height: 44px; font-size: 17px; flex: 0 0 auto; width: auto; }
.ct-h-sep { color: var(--muted); }
.contact-edit-row label .ct-hours .ct-h-other,
.contact-edit-row label .ct-closed .ct-closed-other { flex: 1 1 160px; min-height: 44px; margin-top: 0; width: auto; }
.ct-day-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ct-day {
  display: inline-flex; align-items: center; gap: 4px;
  min-height: 36px; padding: 0 10px; border-radius: 999px;
  border: 1px solid var(--border); background: #fff; font-size: 15px; cursor: pointer;
  user-select: none;
}
.ct-day input { width: 16px; height: 16px; min-height: 0; margin: 0; accent-color: var(--primary); }
.ct-day:has(input:checked) { background: rgba(196, 30, 58, .10); border-color: var(--primary); color: var(--primary-dark); font-weight: 600; }


/* ===== shared hour:minute picker (helpers.js timeSelectHtml) ===== */
.time-sel { display: inline-flex; align-items: center; gap: 4px; }
.time-sel select { width: auto; min-width: 4.4em; min-height: 44px; font-size: 17px; text-align: center; }
.time-sel-colon { color: var(--muted); font-size: 17px; }

/* ===== audience picker: virtual side/family options ===== */
.aud-item.aud-virtual { background: rgba(196, 160, 106, .12); border-radius: 999px; padding: 2px 10px 2px 6px; }
.aud-sep { flex-basis: 100%; height: 0; }


/* ===== merged from _css-cal.css ===== */
/* ================================================================
   calendar.js follow-ups (to be merged into styles.css)
   - month grid never widens (long chips are truncated)
   - phones: 2 chips per day cell + "+N"
   - trip form: people picker always open, read-only targets on edit
   - trip list: date heading rows
   - room add form: type / count fields
   ================================================================ */

/* ---------- month grid: fixed 7 columns, cells clip their content ---------- */
.cal-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.cal-grid > .cal-cell, .cal-grid > .cal-wd { min-width: 0; overflow: hidden; }
.cal-cell { box-sizing: border-box; }
.cal-cell .chip {
  display: block; max-width: 100%; box-sizing: border-box;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-cell .cal-more {
  display: block; font-size: 11px; color: var(--primary-dark, #6b4a3a);
  font-weight: 600; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cal-cell.cal-has-items { cursor: pointer; }
.cal-cell.cal-open { outline: 2px solid var(--primary, #8a6a4a); outline-offset: -2px; }
.cal-day-pop {
  position: fixed; z-index: 40;
  width: max-content; min-width: 200px;
  max-width: min(320px, calc(100vw - 16px));
  max-height: min(50vh, 360px);
  overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--card, #fffdf7);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(60, 30, 30, .16), 0 1px 3px rgba(0, 0, 0, .08);
}
.cal-day-pop[hidden] { display: none; }
.cal-day-pop-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 8px 8px 12px;
  border-bottom: 1px solid var(--border);
}
.cal-day-pop-h { margin: 0; flex: 1; font-size: 15px; font-weight: 700; }
.cal-day-pop-x {
  flex: 0 0 auto; width: 32px; height: 32px; padding: 0;
  border: 0; border-radius: 8px; background: transparent;
  color: var(--text); font-size: 20px; line-height: 1; cursor: pointer;
}
.cal-day-pop-list {
  overflow-y: auto; padding: 8px 10px 10px;
  display: flex; flex-direction: column; gap: 4px;
}
.cal-day-pop-list .chip {
  white-space: normal; overflow: visible; text-overflow: unset;
  margin: 0;
}
/* PC: up to 4 chips, the phone-only "+N" is hidden. */
.cal-cell .cal-more.sp-only { display: none; }
@media (max-width: 640px) {
  .cal-cell { padding: 4px 3px; }
  .cal-cell .chip.sp-hide { display: none; }
  .cal-cell .cal-more.pc-only { display: none; }
  .cal-cell .cal-more.sp-only { display: block; font-size: 10px; }
}

/* ---------- trip form: people picker (always open, required) ---------- */
.bulk-pick { grid-column: 1 / -1; margin: 4px 0 10px; }
.bulk-pick-title { margin: 0 0 2px; font-size: 15px; font-weight: 600; color: var(--primary-dark, inherit); }
.bulk-pick .note { margin: 0 0 6px; }
.bulk-pick .aud-item.bulk-self { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-weight: 600; }
.bulk-pick .aud-item input[type="checkbox"] { width: 22px; height: 22px; }
.bulk-group .aud-item { min-height: 36px; }
/* Edit mode: whose plan it is, as text instead of the picker. */
.tr-edit-people {
  grid-column: 1 / -1; margin: 4px 0 10px; padding: 10px 12px;
  background: var(--accent); border-radius: 10px; font-size: 15px;
  overflow-wrap: anywhere;
}

/* ---------- trip list: date heading rows ---------- */
.trip-table .trip-date-row th {
  background: #f4efe3; color: var(--primary-dark, inherit);
  font-size: 15px; font-weight: 700; padding: 8px 12px;
  border-top: 1px solid var(--border);
}
.trip-table tr:first-child + .trip-date-row th { border-top: none; }

/* ---------- room add form ---------- */
.room-add #rm-count, .room-add #rm-cap { max-width: 120px; }
@media (max-width: 640px) {
  .room-add { grid-template-columns: 1fr; }
  .room-add #rm-count, .room-add #rm-cap { max-width: none; }
  .room-add label { margin: 6px 0; }
}


/* ===== merged from _css-prog.css ===== */
/* ---------- program (当日の流れ): add/edit form ---------- */
/* Hour/minute picker sits on its own line under the label text, like
   the other inputs in the form (label text above, control below). */
#pg-form-box .pg-time-label .time-sel { display: flex; margin-top: 5px; }
#pg-form-box .pg-time-label .time-sel select { flex: 0 0 auto; }
/* Legacy free-text time note (shown only while editing such an item). */
#pg-form-box .pg-time-legacy { display: block; margin: 6px 0 0; font-size: 13px; }

.time-sel-wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.time-presets { display: flex; flex-wrap: wrap; gap: 6px; }
.time-preset {
  min-height: 36px; padding: 0 10px; border-radius: 999px;
  border: 1px solid var(--border); background: #fff; font-size: 14px; cursor: pointer;
}
.time-preset:hover, .time-preset:focus { border-color: var(--primary); color: var(--primary-dark); }
.inv-time-row .time-presets { flex-basis: 100%; margin-top: 4px; }
.tr-edit-one-wrap { display: block; margin-top: 8px; font-size: 14px; }
.tr-edit-one-wrap .btn { margin: 4px 4px 0 0; }
.rm-type-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0;
}
.rm-type-row input { width: auto; min-width: 0; }
.rm-type-row .rm-batch-type { flex: 1 1 8em; }
.rm-type-row .rm-batch-count, .rm-type-row .rm-batch-cap { width: 4.5em; }
.rm-type-h { margin: 12px 0 6px; font-size: 14px; }
.rm-type-sum { margin: 0 0 10px; font-size: 14px; color: var(--ink); }
.room-dates { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 6px 0; }
.room-dates input[type="date"] { width: auto; min-height: 36px; font-size: 15px; }
.rg-rename-lab { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; flex: 1 1 12em; min-width: 0; }
.rg-rename { min-height: 36px; font-size: 16px; font-weight: 600; flex: 1 1 10em; min-width: 8em; max-width: none; }
.couple-lodge-box { margin: 0 0 16px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: #fffdf7; }
.couple-lodge-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0; }
.rm-vacant-lab, .rm-bf-lab { margin: 8px 0; }

@media (max-width: 640px) {
  /* One input per line; the two selects share the row equally. */
  #pg-form-box .pg-form-grid { grid-template-columns: 1fr; }
  #pg-form-box .pg-time-label .time-sel select { flex: 1 1 auto; min-width: 0; }
}
