/* ---------------------------------------------------------------- tokens - */
/*
 * Tabi - design language.
 *
 * Editorial calm with one loud thing: the data. Warm paper and sumi ink,
 * Geist for every word and figure, Instrument Serif only for page names.
 * Colour is spent where it carries meaning:
 *   - six category hues (validated for colour-blind separation, in this
 *     order, on these surfaces - do not re-order or re-tint them),
 *   - aizome indigo for anything you can press,
 *   - green and red only for under and over, always with a word and a sign.
 * No gradients on surfaces, no glow, no glass. Depth comes from paper on
 * paper: raised cards with a hairline and one soft shadow.
 */
@font-face {
  font-family: "Geist"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url(/fonts/geist.woff2) format("woff2");
}
@font-face {
  font-family: "Instrument Serif"; font-style: normal; font-weight: 400; font-display: swap;
  src: url(/fonts/instrument-serif.woff2) format("woff2");
}
@font-face {
  font-family: "Instrument Serif"; font-style: italic; font-weight: 400; font-display: swap;
  src: url(/fonts/instrument-serif-italic.woff2) format("woff2");
}

:root {
  --font: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Instrument Serif", "Iowan Old Style", "Palatino Linotype", Georgia, serif;

  --bg:        #f2efe8;   /* washi paper */
  --bg-raised: #fffefb;   /* the cards sitting on it */
  --bg-sunken: #e9e5dc;
  --line:      #e0dbd0;
  --line-soft: #ece8df;
  --text:      #17150f;   /* sumi ink */
  --text-dim:  #58534a;
  --text-faint:#6b655b;   /* 4.8:1 on the page, 5.6:1 on cards */

  --ink:       #17150f;   /* primary buttons: ink on paper */
  --ink-on:    #fffefb;
  --accent:      #2a5ca8; /* aizome indigo: anything pressable */
  --accent-ink:  #ffffff;
  --accent-soft: rgba(42, 92, 168, .09);
  --good:        #17804d;
  --good-soft:   rgba(23, 128, 77, .10);
  --good-ink:    #0e6a3d; /* green words on a green tint, 4.5:1 */
  --warn:        #9a6200;
  --warn-strong: #9a5800;
  --warn-ink:    #ffffff;
  --warn-soft:   rgba(154, 88, 0, .11);
  --bad:         #b3261e;
  --badge-bg:    #b3261e; /* a count badge: white on it reads at 4.5:1 */
  --bad-soft:    rgba(179, 38, 30, .09);
  --info:        #2a5ca8;
  --shadow-card: 0 1px 0 rgba(23, 21, 15, .03), 0 8px 24px -12px rgba(23, 21, 15, .14);
  --seg-on:    #fffefb;   /* the chosen option in a segmented control */

  /* Older names still used by the trip screens, mapped onto the palette. */
  --leather:     #b8a58c;
  --tan:         #ebe2d2;
  --sticker-red: #b3261e;
  --sticker-blue:#2a5ca8;

  --k-sight:  #2a5ca8;
  --k-food:   #b3261e;
  --k-travel: #6d5bb0;
  --k-hotel:  #17804d;
  --k-shop:   #9a6200;
  --k-onsen:  #1f8a8a;
  --k-event:  #a3457a;
  --k-other:  #8b857a;

  /* Budget categories, validated as a set (light surface #fffefb):
     Flights, Stays, Getting around, Food, Activities, Extras. */
  --cat-1: #2a78d6;
  --cat-2: #eb6834;
  --cat-3: #1baf7a;
  --cat-4: #eda100;
  --cat-5: #e87ba4;
  --cat-6: #008300;

  --page: 720px;
  --gutter: 16px;

  --radius: 16px;
  --radius-sm: 10px;
  --stroke: 1px;
  --shadow: none;
  --tap: 44px;            /* Apple and Google both ask for 44-48px targets */
  --tabbar-h: 58px;
  --ease: cubic-bezier(.2, .8, .2, 1);

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
}

/* Dark: its own values, chosen for the dark surface - not an inversion. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:        #0d0d0c;
    --bg-raised: #1a1a18;
    --bg-sunken: #242421;
    --line:      #302f2b;
    --line-soft: #262522;
    --text:      #f3f1eb;
    --text-dim:  #b8b3a8;
    --text-faint:#8f8a7f;
    --ink:       #f3f1eb;
    --ink-on:    #121210;
    --accent:      #86a9eb;
    --accent-ink:  #0c1628;
    --accent-soft: rgba(134, 169, 235, .13);
    --good:        #4cc38a;
    --good-soft:   rgba(76, 195, 138, .13);
  --good-ink:    #4cc38a;
    --good-ink:    #4cc38a;
    --warn:        #e0a64a;
    --warn-strong: #eab05a;
    --warn-ink:    #1c1304;
    --warn-soft:   rgba(234, 176, 90, .14);
    --bad:         #ff7b70;
  --badge-bg:    #c9372c;
    --badge-bg:    #c9372c;
    --bad-soft:    rgba(255, 123, 112, .13);
    --info:        #86a9eb;
    --shadow-card: 0 1px 0 rgba(255, 255, 255, .03), 0 10px 30px -14px rgba(0, 0, 0, .7);
    --seg-on:    #3b3a36;   /* lighter than the track, so the choice reads as raised */
    --leather:     #4a4640;
    --tan:         #2a2826;
    --k-sight: #86a9eb; --k-food: #ff7b70; --k-hotel: #4cc38a; --k-shop: #e0a64a;
    /* Same six hues, stepped for the dark surface #1a1a18 and validated there. */
    --cat-1: #3987e5; --cat-2: #d95926; --cat-3: #199e70; --cat-4: #c98500; --cat-5: #d55181; --cat-6: #008300;
  }
}
/* The same, when the app asks for dark (Home Screen on iPhone). */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg:        #0d0d0c;
  --bg-raised: #1a1a18;
  --bg-sunken: #242421;
  --line:      #302f2b;
  --line-soft: #262522;
  --text:      #f3f1eb;
  --text-dim:  #b8b3a8;
  --text-faint:#8f8a7f;
  --ink:       #f3f1eb;
  --ink-on:    #121210;
  --accent:      #86a9eb;
  --accent-ink:  #0c1628;
  --accent-soft: rgba(134, 169, 235, .13);
  --good:        #4cc38a;
  --good-soft:   rgba(76, 195, 138, .13);
  --warn:        #e0a64a;
  --warn-strong: #eab05a;
  --warn-ink:    #1c1304;
  --warn-soft:   rgba(234, 176, 90, .14);
  --bad:         #ff7b70;
  --bad-soft:    rgba(255, 123, 112, .13);
  --info:        #86a9eb;
  --shadow-card: 0 1px 0 rgba(255, 255, 255, .03), 0 10px 30px -14px rgba(0, 0, 0, .7);
  --seg-on:    #3b3a36;   /* lighter than the track, so the choice reads as raised */
  --leather:     #4a4640;
  --tan:         #2a2826;
  --k-sight: #86a9eb; --k-food: #ff7b70; --k-hotel: #4cc38a; --k-shop: #e0a64a;
  /* Same six hues, stepped for the dark surface #1a1a18 and validated there. */
  --cat-1: #3987e5; --cat-2: #d95926; --cat-3: #199e70; --cat-4: #c98500; --cat-5: #d55181; --cat-6: #008300;
}


* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  color-scheme: light dark;
  font: 16px/1.45 var(--font);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  overscroll-behavior-y: none;
}

h1, h2, h3, h4 { margin: 0; font-weight: 650; letter-spacing: -.01em; }
h1 { font-size: 1.05rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: .98rem; }

button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--info); }

.muted  { color: var(--text-dim); }
.faint  { color: var(--text-faint); }
.tiny   { font-size: .78rem; }
.small  { font-size: .86rem; }
.nowrap { white-space: nowrap; }
.row    { display: flex; gap: 8px; align-items: center; }
.row.wrap { flex-wrap: wrap; }
.spread { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.grow   { flex: 1; min-width: 0; }
.stack  { display: flex; flex-direction: column; gap: 10px; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
[hidden] { display: none !important; }

/* --------------------------------------------------------------- buttons - */
button {
  background: none; border: 0; cursor: pointer; color: inherit;
  border-radius: var(--radius-sm);
}
.primary, .secondary, .ghost, .danger {
  min-height: var(--tap);
  padding: 0 16px;
  border-radius: var(--radius-sm);
  font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border: var(--stroke) solid transparent;
  transition: background .12s, border-color .12s, opacity .12s;
}
.primary   {
  background: var(--accent); color: var(--accent-ink);
  border-color: color-mix(in srgb, var(--accent) 70%, var(--accent-ink));
}
.primary:hover  { background: color-mix(in srgb, var(--accent) 82%, #fff); }
.secondary { background: var(--bg-raised); border-color: var(--line); }
.secondary:hover { border-color: var(--tan); }
.ghost     { background: transparent; color: var(--text-dim); }
.ghost:hover { color: var(--text); background: var(--bg-raised); }
.danger    { background: transparent; color: var(--bad); border-color: color-mix(in srgb, var(--bad) 40%, transparent); }
.danger:hover { background: color-mix(in srgb, var(--bad) 12%, transparent); }
.block     { width: 100%; }
button:disabled { opacity: .5; cursor: not-allowed; }
.xs { min-height: 32px; padding: 0 10px; font-size: .82rem; border-radius: 6px; }

/* ----------------------------------------------------------------- gate -- */
.gate {
  min-height: 100dvh;
  display: grid; place-items: center;
  padding: calc(24px + var(--safe-top)) 16px calc(24px + var(--safe-bottom));
  background:
    radial-gradient(900px 520px at 50% -8%, color-mix(in srgb, var(--leather) 28%, transparent), transparent 64%),
    radial-gradient(520px 380px at 85% 110%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 58%),
    var(--bg);
}
.gate-card {
  width: 100%; max-width: 400px;
  background: var(--bg-raised);
  border: var(--stroke) solid var(--line);
  border-radius: 16px;
  padding: 26px 22px;
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--tan) 22%, transparent),
    0 3px 0 color-mix(in srgb, var(--leather) 40%, var(--bg-sunken)),
    var(--shadow);
}
.gate-brand { text-align: center; margin-bottom: 20px; }
.gate-brand h1 { font-size: 1.4rem; margin: 10px 0 3px; }
.brand-mark {
  display: inline-block; width: 96px; height: 96px; border-radius: 22px; vertical-align: middle;
  box-shadow: 0 14px 28px -14px rgba(10, 24, 50, .55), 0 0 0 1px rgba(255, 255, 255, .12);
}

/* The Tabi seal as the loader: it stamps in once, then breathes, with a
   thin wave running underneath so a slow load still reads as working. */
.tabi-loader { --size: 40px; display: inline-grid; justify-items: center; gap: 10px; flex: none; }
.tabi-loader.lg { --size: 68px; }
.tabi-loader[hidden] { display: none; }
.tabi-loader img { width: var(--size); height: var(--size); display: block; animation: seal-breathe 1.8s ease-in-out infinite; }
.tabi-loader.is-stamp img { animation: seal-stamp .45s cubic-bezier(.3, 1.4, .5, 1) both, seal-breathe 1.8s ease-in-out .6s infinite; }
.tabi-loader-wave {
  width: calc(var(--size) * 1.1); height: 3px; border-radius: 999px; overflow: hidden;
  background: color-mix(in srgb, var(--accent) 18%, transparent); position: relative;
}
.tabi-loader-wave::after {
  content: ""; position: absolute; inset: 0; width: 40%; border-radius: inherit; background: var(--accent);
  animation: seal-wave 1.4s ease-in-out infinite;
}
@keyframes seal-stamp { from { transform: scale(1.35) rotate(-12deg); opacity: 0; } 60% { opacity: 1; } to { transform: scale(1) rotate(-4deg); } }
@keyframes seal-breathe { 0%, 100% { transform: rotate(-4deg) scale(1); } 50% { transform: rotate(-4deg) scale(.95); opacity: .85; } }
@keyframes seal-wave { from { transform: translateX(-100%); } to { transform: translateX(250%); } }

.splash {
  min-height: 100dvh;
  display: grid; place-items: center;
  background: var(--bg);
}
.splash-inner { display: grid; justify-items: center; gap: 14px; }
.splash-word { margin: 0; font-family: var(--font-display); font-size: 2.2rem; line-height: 1; color: var(--text); letter-spacing: -.01em; }
.splash[hidden] { display: none !important; }
.loading-slot {
  display: grid; place-items: center;
  min-height: 120px;
  padding: 24px 0;
}

.tabs-mini {
  display: flex; gap: 4px; background: var(--bg-sunken); padding: 4px;
  border-radius: 12px; margin-bottom: 18px;
  border: var(--stroke) solid var(--line);
}
.mini { flex: 1; min-height: 36px; font-size: .88rem; font-weight: 600; color: var(--text-dim); border-radius: 8px; }
.mini.active { background: var(--accent); color: var(--accent-ink); box-shadow: none; }

.gate-form { display: flex; flex-direction: column; gap: 14px; }
.gate-foot { text-align: center; margin: 18px 0 0; font-size: .78rem; }

label { display: flex; flex-direction: column; gap: 5px; font-size: .85rem; color: var(--text-dim); font-weight: 600; }
input, select, textarea {
  background: var(--bg-sunken);
  border: var(--stroke) solid var(--line);
  border-radius: var(--radius-sm);
  padding: 11px 12px;
  min-height: var(--tap);
  color: var(--text);
  width: 100%;
  font-weight: 400;
}
textarea { min-height: 76px; resize: vertical; line-height: 1.45; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
label small { font-weight: 400; }

.form-error {
  margin: 0; padding: 10px 12px; font-size: .85rem;
  background: color-mix(in srgb, var(--bad) 12%, transparent); border: var(--stroke) solid color-mix(in srgb, var(--bad) 40%, transparent); border-radius: var(--radius-sm); color: #ff9b9b;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .form-error { color: #a32020; }
}

/* An error under the field it is about; the field keeps what was typed. */
.field-error { display: block; margin-top: 4px; font-size: .82rem; font-weight: 550; color: var(--bad); }
[aria-invalid="true"] { border-color: var(--bad); }
.modal .form-error { margin-top: 2px; }
/* A button whose save is on its way: still readable, plainly busy. */
button[aria-busy="true"] { position: relative; opacity: .75; cursor: progress; }
button[aria-busy="true"]::after {
  content: ""; display: inline-block; width: .9em; height: .9em; margin-left: 8px; vertical-align: -2px;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: busy-spin .8s linear infinite;
}
@keyframes busy-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { button[aria-busy="true"]::after { animation: none; border-right-color: currentColor; opacity: .5; } }

/* --------------------------------------------------------------- topbar -- */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: calc(10px + var(--safe-top)) var(--gutter) 10px;
  max-width: var(--page); margin: 0 auto;
  background: var(--bg);
  border-bottom: var(--stroke) solid var(--line);
}
.topbar-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.topbar-left > div { min-width: 0; }
/* A long trip name must not push the header into two lines on a phone. */
.topbar-left h1 {
  line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar-right { display: flex; align-items: center; gap: 8px; flex: none; }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  height: 34px; padding: 0 11px;
  white-space: nowrap; flex: none;
  border: var(--stroke) solid var(--line); border-radius: 999px;
  background: var(--bg-raised); font-size: .78rem; font-weight: 600; color: var(--text-dim);
}
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--text-faint); flex: none; }
.pill .dot.on  { background: var(--good); box-shadow: 0 0 0 3px var(--accent-soft); animation: pulse 2.4s infinite; }
.pill .dot.off { background: var(--text-faint); }
.pill.active { color: var(--text); border-color: color-mix(in srgb, var(--good) 55%, transparent); }
@keyframes pulse { 0%,100% { opacity: 1 } 50% { opacity: .45 } }

.icon-btn {
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--bg-raised); border: var(--stroke) solid var(--line);
  font-size: .76rem; font-weight: 700; color: var(--text-dim);
  display: grid; place-items: center; flex: none;
}

/* ----------------------------------------------------------------- tabs -- */
.tabs-wrap {
  position: sticky; top: calc(55px + var(--safe-top)); z-index: 35;
  background: var(--bg);
  border-bottom: var(--stroke) solid var(--line);
}
/* A fade on the right edge is the only hint that more tabs exist off-screen;
   without it people simply do not find the last ones on a narrow phone. */
.tabs-wrap::after {
  content: ''; position: absolute; top: 0; right: 0; bottom: 1px; width: 28px;
  background: linear-gradient(to right, transparent, var(--bg));
  pointer-events: none; opacity: var(--tabs-fade, 0); transition: opacity .2s;
}
.tabs {
  display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none;
  padding: 8px var(--gutter); scroll-behavior: smooth;
  max-width: var(--page); margin: 0 auto;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  flex: none; padding: 8px 13px; border-radius: 999px;
  font-size: .87rem; font-weight: 600; color: var(--text-dim); white-space: nowrap;
  min-height: 36px;
  border: var(--stroke) solid transparent;
}
.tab.active {
  background: var(--accent); color: var(--accent-ink);
  border-color: color-mix(in srgb, var(--accent) 70%, var(--accent-ink));
}

main {
  padding: 14px var(--gutter) calc(40px + var(--safe-bottom));
  max-width: var(--page); margin: 0 auto;
}
.panel { display: none; }
.panel.active { display: block; animation: fade .18s ease; }
@keyframes fade { from { opacity: 0; transform: translateY(3px) } to { opacity: 1; transform: none } }

/* ---------------------------------------------------------------- cards -- */
.card {
  background: var(--bg-raised);
  border: var(--stroke) solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 10px;
}
.card.tight { padding: 11px 13px; }
.card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 8px; }

.section-head {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  margin: 20px 0 10px;
}
.section-head:first-child { margin-top: 4px; }

.empty {
  text-align: center; padding: 34px 18px; color: var(--text-dim);
  border: var(--stroke) dashed var(--line); border-radius: var(--radius); background: var(--bg-sunken);
}
.empty p { margin: 0 0 12px; }

.banner {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 11px 13px; border-radius: var(--radius-sm);
  font-size: .85rem; margin-bottom: 12px;
  background: var(--bg-sunken); border: var(--stroke) solid var(--line);
}
.banner.warn { background: color-mix(in srgb, var(--warn) 12%, transparent); border-color: color-mix(in srgb, var(--warn) 40%, transparent); }
.banner.info { background: color-mix(in srgb, var(--info) 12%, transparent); border-color: color-mix(in srgb, var(--info) 40%, transparent); }
.banner.good { background: color-mix(in srgb, var(--good) 12%, transparent); border-color: color-mix(in srgb, var(--good) 40%, transparent); }
.banner.bad  { background: color-mix(in srgb, var(--bad) 12%, transparent); border-color: color-mix(in srgb, var(--bad) 40%, transparent); }

/* --------------------------------------------------------------- badges -- */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 999px;
  font-size: .72rem; font-weight: 700; letter-spacing: .02em;
  background: var(--bg-sunken); color: var(--text-dim); border: var(--stroke) solid var(--line);
  white-space: nowrap;
}
.badge.good { color: var(--good); border-color: color-mix(in srgb, var(--good) 50%, transparent); background: color-mix(in srgb, var(--good) 12%, transparent); }
.badge.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 50%, transparent); background: color-mix(in srgb, var(--warn) 12%, transparent); }
.badge.bad  { color: var(--bad);  border-color: color-mix(in srgb, var(--bad) 50%, transparent); background: color-mix(in srgb, var(--bad) 12%, transparent); }
.badge.accent { color: var(--sticker-red); border-color: color-mix(in srgb, var(--sticker-red) 50%, transparent); background: color-mix(in srgb, var(--sticker-red) 12%, transparent); }

.kind-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }

/* -------------------------------------------------------------- day nav -- */
.daybar { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding: 2px 0 10px; scroll-behavior: smooth; }
.daybar::-webkit-scrollbar { display: none; }
.daychip {
  flex: none; min-width: 58px; padding: 7px 10px; border-radius: 10px;
  background: var(--bg-raised); border: var(--stroke) solid var(--line);
  text-align: center; line-height: 1.25;
}
.daychip .dow { font-size: .68rem; color: var(--text-faint); text-transform: uppercase; letter-spacing: .05em; }
.daychip .dnum { font-size: 1.02rem; font-weight: 700; }
.daychip .dcount { font-size: .64rem; color: var(--text-faint); }
.daychip.active { background: var(--accent); border-color: color-mix(in srgb, var(--accent) 70%, var(--accent-ink)); color: var(--accent-ink); }
.daychip.active .dow, .daychip.active .dcount { color: color-mix(in srgb, var(--accent-ink) 75%, transparent); }
.daychip.is-today { border-color: var(--accent); }

/* -------------------------------------------------------------- timeline - */
.timeline { position: relative; padding-left: 20px; }
.timeline::before {
  content: ''; position: absolute; left: 5px; top: 8px; bottom: 8px;
  width: 2px; background: var(--line);
}
.tl-item { position: relative; margin-bottom: 9px; }
.tl-item.is-next { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }

/* Home "what's next" — compact strip above the day's plan. */
.whats-next {
  display: flex; flex-direction: column; text-align: left;
  width: 100%; padding: 12px 13px; margin-bottom: 12px;
  border-radius: var(--radius);
  background: var(--accent-soft);
  border: var(--stroke) solid color-mix(in srgb, var(--accent) 32%, var(--line));
  color: inherit;
}
/* The tappable half. It is its own button because the card now carries links,
   and a button inside a button is not valid and does not work. */
.whats-next-tap {
  display: flex; gap: 12px; align-items: flex-start; text-align: left;
  width: 100%; padding: 0; margin: 0; min-height: 0;
  background: none; border: 0; color: inherit; cursor: pointer; font: inherit;
}
.whats-next:hover { border-color: var(--accent); }
.whats-next-tap:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.whats-next.is-empty {
  background: var(--bg-sunken); border-color: var(--line); cursor: default;
}
.whats-next-kicker {
  font-size: .68rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--accent);
}
.whats-next.is-empty .whats-next-kicker { color: var(--text-faint); }
.whats-next-time {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: 1.05rem;
  min-width: 48px; padding-top: 14px; color: var(--text);
}
.whats-next-title { font-weight: 700; margin: 2px 0 0; }
.whats-next-meta { font-size: .8rem; color: var(--text-dim); margin-top: 3px; }
.whats-next-tip {
  font-size: .84rem; color: var(--text-dim); margin: 7px 0 0;
  padding-left: 9px; border-left: 2px solid var(--accent);
}

/* Twin / triple rates and rooms-for-N on hotel cards. */
.rate-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 11px;
}
.rate-card {
  background: var(--bg-sunken); border-radius: var(--radius-sm);
  padding: 8px 10px; border: 1px solid transparent;
}
.rate-card.is-stay { border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); }
.rate-card dt {
  font-size: .7rem; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .05em;
}
.rate-card dd { margin: 2px 0 0; font-weight: 600; font-size: .88rem; }
.rate-card .rate-sub { font-size: .76rem; color: var(--text-dim); font-weight: 500; margin-top: 2px; }
.rooms-preview {
  margin-top: 8px; font-size: .84rem; color: var(--text-dim);
}
.rooms-for { gap: 8px; flex-wrap: wrap; }
.rooms-for .people-count { font-variant-numeric: tabular-nums; min-width: 1.2em; text-align: center; }
.tl-item::before {
  content: ''; position: absolute; left: -19px; top: 17px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--bg); border: 2px solid var(--kind, var(--text-faint));
}
.tl-time {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: .84rem;
  color: var(--text-dim); min-width: 44px;
}
.tl-body { flex: 1; min-width: 0; }
.tl-title { font-weight: 600; }
.tl-meta { font-size: .8rem; color: var(--text-dim); margin-top: 2px; }
.tl-notes {
  font-size: .84rem; color: var(--text-dim); margin-top: 7px;
  padding-left: 9px; border-left: 2px solid var(--line); white-space: pre-wrap;
}
.tl-actions { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 9px; }

/* ----------------------------------------------------------------- maps -- */
.map {
  height: clamp(260px, 42vh, 460px); border-radius: var(--radius);
  border: var(--stroke) solid var(--line); overflow: hidden; margin-bottom: 12px;
  background: var(--bg-sunken);
  z-index: 1;
}
.map.tall { height: 62dvh; min-height: 360px; }
.leaflet-container { background: var(--bg-sunken); font: inherit; }
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
  background: var(--bg-raised); color: var(--text);
  border: var(--stroke) solid var(--line); box-shadow: var(--shadow);
}
.leaflet-popup-content { margin: 11px 13px; font-size: .86rem; line-height: 1.45; }
.leaflet-popup-content b { display: block; margin-bottom: 3px; }
.leaflet-popup-close-button { color: var(--text-dim) !important; }
.leaflet-control-attribution {
  background: color-mix(in srgb, var(--bg) 82%, transparent) !important;
  color: var(--text-faint) !important; font-size: .64rem !important;
}
.leaflet-control-attribution a { color: var(--text-dim) !important; text-decoration: underline !important; }
.leaflet-bar a {
  background: var(--bg-raised) !important; color: var(--text) !important;
  border-color: var(--line) !important;
}

/* English place names drawn beside pins (Leaflet tooltip, not a tile overlay). */
.leaflet-tooltip.map-pin-label {
  background: var(--bg-raised);
  color: var(--text);
  border: var(--stroke) solid var(--line);
  border-radius: 6px;
  box-shadow: 0 1px 4px rgba(22, 10, 4, .28);
  font-size: .7rem;
  font-weight: 650;
  letter-spacing: -.01em;
  line-height: 1.2;
  padding: 3px 7px;
  white-space: nowrap;
  max-width: 14rem;
  overflow: hidden;
  text-overflow: ellipsis;
}
.leaflet-tooltip.map-pin-label::before { display: none; }

/* numbered stop markers */
.stop-pin {
  display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: 50% 50% 50% 2px;
  transform: rotate(-45deg);
  border: 2px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,.45);
  font-size: .72rem; font-weight: 800; color: #fff;
}
.stop-pin span { transform: rotate(45deg); }
.train-pin {
  width: 15px; height: 15px; border-radius: 4px; border: 2px solid #fff;
  box-shadow: 0 1px 5px rgba(0,0,0,.5);
}
.person-pin {
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: .68rem; font-weight: 800; color: #fff;
  border: 2px solid #fff; box-shadow: 0 2px 8px rgba(0,0,0,.5);
  background: var(--info);
}
.person-pin.stale { opacity: .45; filter: grayscale(1); }

/* ----------------------------------------------------------------- list -- */
.list-row {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 11px 0; border-bottom: 1px solid var(--line-soft);
}
.list-row:last-child { border-bottom: 0; }
.list-row .grow { min-width: 0; }

.meta-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: 9px; margin-top: 11px;
}
.meta-grid div { background: var(--bg-sunken); border-radius: var(--radius-sm); padding: 8px 10px; }
.meta-grid dt { font-size: .7rem; color: var(--text-faint); text-transform: uppercase; letter-spacing: .05em; }
.meta-grid dd { margin: 2px 0 0; font-weight: 600; font-size: .88rem; }

.filters { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding-bottom: 10px; }
.filters::-webkit-scrollbar { display: none; }
.chip {
  flex: none; padding: 6px 12px; border-radius: 999px; font-size: .82rem; font-weight: 600;
  background: var(--bg-raised); border: var(--stroke) solid var(--line); color: var(--text-dim);
}
.chip.on { background: var(--accent); border-color: color-mix(in srgb, var(--accent) 70%, var(--accent-ink)); color: var(--accent-ink); }

/* ---------------------------------------------------------------- modal -- */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(16, 10, 6, .72);
  display: grid; place-items: end center;
  animation: fade .15s ease;
}
@media (min-width: 640px) { .modal-backdrop { place-items: center; } }
.modal {
  width: 100%; max-width: 520px; max-height: 92dvh; overflow-y: auto;
  background: var(--bg-raised);
  border: var(--stroke) solid var(--line);
  border-radius: 16px 16px 0 0;
  padding: 18px 16px calc(18px + var(--safe-bottom));
  box-shadow: var(--shadow);
  animation: slideup .2s cubic-bezier(.2,.8,.3,1);
}
@media (min-width: 640px) { .modal { border-radius: 16px; padding-bottom: 18px; } }
@keyframes slideup { from { transform: translateY(18px); opacity: .6 } to { transform: none; opacity: 1 } }
.modal h2 { margin-bottom: 14px; }
.modal-form { display: flex; flex-direction: column; gap: 13px; }
.modal-actions { display: flex; gap: 8px; margin-top: 6px; }
.modal-actions .primary { flex: 1; }
.field-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ---------------------------------------------------------------- toast -- */
.toast {
  position: fixed; left: 50%; bottom: calc(22px + var(--safe-bottom));
  transform: translateX(-50%);
  z-index: 200; max-width: min(92vw, 420px);
  padding: 12px 16px; border-radius: 10px;
  background: var(--bg-raised); border: var(--stroke) solid var(--line);
  box-shadow: var(--shadow); font-size: .87rem;
  animation: slideup .2s ease;
}
.toast.bad  { border-color: color-mix(in srgb, var(--bad) 55%, transparent); }
.toast.good { border-color: color-mix(in srgb, var(--good) 55%, transparent); }

/* ------------------------------------------------------------ utilities -- */
.code-box {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.12rem; letter-spacing: .1em; text-align: center; font-weight: 700;
  padding: 15px; background: var(--bg-sunken);
  border: 1px dashed var(--leather); border-radius: var(--radius-sm);
  user-select: all; word-break: break-all;
}
.skeleton {
  height: 74px; border-radius: var(--radius); margin-bottom: 10px;
  background: linear-gradient(90deg, var(--bg-raised) 25%, var(--bg-sunken) 50%, var(--bg-raised) 75%);
  background-size: 200% 100%; animation: shimmer 1.3s infinite;
}
@keyframes shimmer { from { background-position: 200% 0 } to { background-position: -200% 0 } }

.drag-handle { cursor: grab; color: var(--text-faint); padding: 4px; touch-action: none; }
.tl-item.dragging { opacity: .4; }
.tl-item.drop-target { border-top: 2px solid var(--accent); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  .tabi-loader img { animation: none !important; transform: rotate(-4deg); }
  .tabi-loader-wave::after { animation: none !important; width: 100%; opacity: .5; }
}

/* -------------------------------------------------------------- weather -- */
.weather {
  background: var(--bg-raised);
  border: var(--stroke) solid var(--line);
  border-radius: var(--radius);
  padding: 11px 13px;
  margin-bottom: 10px;
}
.weather-main { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.weather-temps { display: flex; align-items: baseline; gap: 6px; flex: none; }
.temp-high { font-size: 1.45rem; font-weight: 700; letter-spacing: -.02em; }
.temp-low  { font-size: 1rem; font-weight: 600; color: var(--text-dim); }
.weather-facts {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
  font-size: .84rem; color: var(--text-dim);
}
.weather-fact { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.weather-icon { opacity: .75; font-size: .82rem; }
.weather-foot {
  display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-soft);
}
.weather-hint { color: var(--warn); font-weight: 600; }
.weather-loading { padding: 2px 0; }

/* ------------------------------------------------------ attractions ---- */
.attr-areas, .attr-cats { flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
/* Area chips carry the dates you are there, so a city that appears twice
   on the trip reads as one place with two visits. */
.attr-areas .chip { display: inline-flex; flex-direction: column; align-items: flex-start;
  line-height: 1.15; padding-top: 5px; padding-bottom: 5px; }
.chip-sub { font-size: .66rem; font-weight: 500; opacity: .75; }
.attr-status { margin: 8px 0 10px; }
.attr-card .card-head { align-items: flex-start; gap: 10px; }
/* Matches the numbered pin on the map, so card and pin can be paired. */
.attr-num {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center; margin-top: 2px;
  color: #fff; font-size: .72rem; font-weight: 800;
}
.attr-badges { gap: 5px; }
.attr-badges .badge { font-size: .66rem; }

/* --------------------------------------------- what's around here ------ */
/* Suggestions sit under the plan, visually as well as in z-order: a place you
   might go must never read as loudly as a place you are going. */
.nearby-control {
  margin: -6px 0 12px; padding: 10px 12px;
  border: var(--stroke) solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-sunken);
}
.nearby-chips { margin: 0; gap: 6px; flex-wrap: wrap; }
.nearby-chips .chip { font-size: .76rem; }

/* A button that reads as a link, for use inside a sentence where a real
   button would break the line and a real link has no href to go to. */
.linkish {
  background: none; border: 0; padding: 0; min-height: 0;
  font: inherit; color: var(--accent); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.linkish:hover { color: var(--text); }
/* Smaller and softer than a numbered plan pin, so the day still reads at a
   glance with two dozen suggestions on the map. */
.nearby-pin {
  width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.45);
  opacity: .9;
}

/* ------------------------------------------------- where to go next ---- */
/* The footer of the What's next card: how far the stop is from where you are
   standing, and the way to get there. Folded into that card rather than sitting
   under it, so the stop is not announced twice under two headings. */
.whats-next-nav {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  margin-top: 10px; padding-top: 9px;
  border-top: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
}
.whats-next-distance {
  font-size: .78rem; color: var(--text-dim); min-width: 0;
  overflow-wrap: anywhere;
}
.whats-next-actions { display: flex; gap: 6px; flex: none; flex-wrap: wrap; }

/* ------------------------------------------------------- route legs ---- */
/* The hop between two stops, drawn between their cards so a day reads as a
   route. The rule is the visual thread; the text carries the meaning, so it
   still reads with the rule invisible. */
.tl-leg {
  display: flex; align-items: center; gap: 9px;
  padding: 4px 0 4px 52px;
  font-size: .75rem; color: var(--text-faint);
}
.tl-leg-rule {
  width: 2px; height: 18px; flex: none; border-radius: 1px;
  background: repeating-linear-gradient(
    to bottom, var(--line) 0 3px, transparent 3px 6px);
}
.tl-leg.is-walk .tl-leg-rule {
  background: repeating-linear-gradient(to bottom,
    color-mix(in srgb, var(--good) 55%, transparent) 0 3px, transparent 3px 6px);
}
.tl-leg-text { flex: 1 1 auto; min-width: 0; }
.tl-leg a { flex: none; }

@media (max-width: 430px) {
  /* The time gutter narrows on a phone, so the leg loses most of its indent. */
  .tl-leg { padding-left: 8px; }
  .tl-leg a { font-size: .72rem; }
}

/* --------------------------------------------------------------- budget -- */
.budget-glance { display: flex; flex-direction: column; gap: 8px; margin-bottom: 4px; }
.budget-glance > .card { margin-bottom: 0; }
.budget-block-title { margin-bottom: 10px; }
.budget-block-hint { margin: 2px 0 10px; }
.budget-toggle { margin-top: 10px; }
/*
 * The headline pair - each person, whole trip - answers the question the tab
 * is opened with, so it is the loudest thing on it. The target and the
 * locked-in meter are a size down: useful, but not the question.
 */
.budget-headline { gap: 8px; margin-bottom: 8px; }
.budget-headline .stat-tile {
  border-color: var(--line);
  background: var(--bg-raised);
}
.budget-headline .stat-value { font-size: 1.85rem; }
/* Each person leads: it is the figure people cannot work out in their head. */
.budget-headline .stat-tile:first-child {
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent-soft);
}

.budget-context { gap: 8px; margin-bottom: 0; }
.budget-context .stat-value { font-size: 1.12rem; }
.budget-context .stat-tile { padding: 11px 12px; }

/* The chips belong to the charts they restyle, not to the headline. */
.breakdown-view {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; margin: 0 0 10px;
}
.breakdown-view .budget-toggle { margin-top: 0; }
.stat-each {
  font-size: .72rem; color: var(--text-faint); margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.stat-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
/* Group total, per person, A$7–8k headroom, locked-in % — 2×2 on a phone. */
.stat-row.budget-hero {
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 0;
}
.stat-tile {
  background: var(--bg-raised); border: var(--stroke) solid var(--line);
  border-radius: var(--radius); padding: 13px 14px;
}
.stat-tile .meter { margin-top: 8px; }
.stat-label {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-faint); font-weight: 700;
}
.stat-value {
  font-size: 1.5rem; font-weight: 750; letter-spacing: -.02em;
  margin-top: 3px; font-variant-numeric: tabular-nums; line-height: 1.15;
}
.stat-sub { font-size: .76rem; color: var(--text-dim); margin-top: 2px; overflow-wrap: anywhere; }
.money-yen {
  font-size: .84rem; font-weight: 650; color: var(--text-dim);
  font-variant-numeric: tabular-nums; line-height: 1.35; margin-top: 2px;
  overflow-wrap: anywhere;
}
.fx-note {
  margin: 6px 0 0; color: var(--text-faint); font-size: .75rem; line-height: 1.4;
  overflow-wrap: anywhere;
}

/* Home, before the trip starts or after it ends: the group total. */
.home-totals {
  display: block; width: 100%; text-align: left; color: inherit;
  padding: 12px 14px; margin: 0 0 12px;
  border-radius: var(--radius);
  background: var(--bg-raised); border: 1px solid var(--line);
  min-width: 0;
}
button.home-totals { cursor: pointer; touch-action: manipulation; }
button.home-totals:hover { border-color: var(--text-faint); }
.home-totals-kicker {
  font-size: .68rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-faint);
}
.home-totals .stat-value { font-size: 1.35rem; margin-top: 2px; overflow-wrap: anywhere; }
.home-totals .fx-note { margin-top: 6px; }
.skeleton.home-totals-pending { height: 112px; margin-bottom: 12px; }

.meter {
  height: 8px; border-radius: 999px; overflow: hidden;
  background: var(--bg-sunken); border: 1px solid var(--line-soft);
}
.meter-fill { height: 100%; border-radius: 999px; transition: width .3s ease; }

.bars { display: flex; flex-direction: column; gap: 11px; }
.bar-row { display: flex; flex-direction: column; gap: 5px; }
.bar-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: .86rem; }
.bar-label { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; min-width: 0; }
.bar-swatch { width: 9px; height: 9px; border-radius: 3px; flex: none; }
.bar-value { font-variant-numeric: tabular-nums; font-weight: 650; white-space: nowrap; }
.bar-share { color: var(--text-faint); font-weight: 500; font-size: .8em; }
/* Thin mark, rounded data-end, anchored to the baseline. */
.bar-track { height: 9px; background: var(--bg-sunken); border-radius: 999px; overflow: hidden; }
.bar-fill { height: 100%; border-radius: 0 4px 4px 0; transition: width .3s ease; }

.budget-table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: .85rem; }
.budget-table th, .budget-table td { padding: 7px 8px; border-bottom: 1px solid var(--line-soft); }
.budget-table th {
  text-align: left; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-faint);
}
.budget-table td:not(:first-child), .budget-table th:not(:first-child) {
  text-align: right; font-variant-numeric: tabular-nums;
}
.budget-table tr:last-child td { border-bottom: 0; }

.band-track {
  position: relative; height: 12px;
  background: var(--bg-sunken); border: 1px solid var(--line-soft);
  border-radius: 999px; overflow: hidden;
}
.band-span {
  position: absolute; top: 0; bottom: 0;
  background: color-mix(in srgb, var(--good) 38%, transparent);
}
.band-fill {
  position: absolute; top: 0; bottom: 0; left: 0;
  background: color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 0 4px 4px 0;
}
.band-now {
  position: absolute; top: -1px; bottom: -1px; width: 2px;
  background: var(--text); border-radius: 1px; transform: translateX(-1px);
}
.target-copy.good { color: var(--good); font-weight: 600; }
.target-copy.info { color: var(--text-dim); }
.target-copy.over { color: var(--text-dim); }
/* Past the ceiling the fill stops reading as progress and starts reading as
   overshoot, so it takes the warning hue rather than the accent. */
.budget-target.is-over .band-fill {
  background: color-mix(in srgb, var(--warn) 45%, transparent);
}

.budget-fold {
  background: var(--bg-raised);
  border: var(--stroke) solid var(--line);
  border-radius: var(--radius);
  padding: 4px 14px 10px;
  margin: 10px 0;
}
.budget-fold-summary {
  cursor: pointer;
  font-weight: 650;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  list-style: none;
}
.budget-fold-summary::-webkit-details-marker { display: none; }
.budget-fold-summary::before {
  content: '';
  width: 0.45em; height: 0.45em;
  border-right: 2px solid var(--text-dim);
  border-bottom: 2px solid var(--text-dim);
  transform: rotate(-45deg);
  margin-right: 10px;
  flex: none;
}
.budget-fold[open] > .budget-fold-summary::before { transform: rotate(45deg); }
.budget-fold .card {
  background: transparent; border: 0; border-radius: 0;
  padding: 12px 0; margin-bottom: 0;
  border-bottom: 1px solid var(--line-soft);
}
.budget-fold .card:last-child { border-bottom: 0; }
.home-landing { display: flex; flex-direction: column; gap: 14px; max-width: 36rem; }
.home-trip-name { font-size: 1.35rem; letter-spacing: -.02em; }
.home-countdown .stat-value { font-size: 1.65rem; }
.home-itinerary-link {
  align-self: flex-start;
  min-height: var(--tap);
  padding: 0 4px;
  color: var(--text-dim);
  font-weight: 600;
}
.home-budget-strip {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 12px;
  width: 100%;
  text-align: left;
  padding: 14px 16px;
  min-height: var(--tap);
  min-width: 0;
  background: var(--bg-raised);
  border: var(--stroke) solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  color: inherit;
}
.home-budget-strip .stat-value { font-size: 1.45rem; margin-top: 2px; overflow-wrap: anywhere; }
.home-budget-strip .fx-note { flex: 1 0 100%; margin-top: 2px; }
.home-budget-note {
  flex: 1 0 100%;
  margin: 0;
  color: var(--text-dim);
  font-size: .78rem;
  line-height: 1.4;
  overflow-wrap: anywhere;
}
.home-budget-band { text-align: right; flex: none; }
.home-budget-status {
  font-weight: 700;
  font-size: 1.05rem;
  margin-top: 2px;
  text-transform: lowercase;
}
.home-budget-strip.is-under .home-budget-status,
.home-budget-strip.is-in_band .home-budget-status { color: var(--good); }
.home-budget-strip.is-over .home-budget-status { color: var(--warn); }

.soft-landing { margin-bottom: 12px; }
.soft-landing-tip {
  font-size: .92rem;
  color: var(--text-dim);
  margin: 0 0 14px;
  padding: 8px 0 8px 11px;
  border-left: 2px solid var(--accent);
}
.soft-landing-actions { gap: 8px; margin-top: 8px; }

/* ---------------------------------------------------------------- guest -- */
.guest-badge {
  margin-top: 3px;
  color: var(--sticker-blue);
  border-color: color-mix(in srgb, var(--sticker-blue) 45%, transparent);
  background: color-mix(in srgb, var(--sticker-blue) 12%, transparent);
}
/* A guest should never see an affordance for something the server will refuse. */
body.is-guest .primary[data-edit], body.is-guest .drag-handle { display: none; }

/* --------------------------------------------------------------- flights -- */
.leg {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 10px;
  align-items: center; margin: 14px 0 4px;
}
.leg-end { min-width: 0; }
.leg-end:last-child { text-align: right; }
.leg-time {
  font-size: 1.32rem; font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; line-height: 1.1;
}
.leg-offset { font-size: .6em; color: var(--accent); font-weight: 700; margin-left: 2px; }
.leg-code { font-size: .92rem; font-weight: 650; color: var(--text-dim); margin-top: 1px; }
.leg-name { margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leg-terminal { color: var(--accent); font-weight: 600; margin-top: 2px; }
.leg-mid { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 74px; }
.leg-line {
  position: relative; width: 100%; height: 1px; background: var(--line);
  display: flex; align-items: center; justify-content: center;
}
.leg-plane {
  position: absolute; background: var(--bg-raised); padding: 0 5px;
  color: var(--text-faint); font-size: .82rem;
}
.leg-duration { font-size: .7rem; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.flight-card .meta-grid { margin-top: 14px; }

/* --------------------------------------------------------------- preview -- */
.preview-bar {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  gap: 10px; flex-wrap: wrap;
  padding: calc(7px + var(--safe-top)) 14px 7px;
  background: var(--info); color: #fff;
  font-size: .8rem; font-weight: 600; text-align: center;
}
.preview-exit {
  background: rgba(255,255,255,.2); color: #fff;
  border: 1px solid rgba(255,255,255,.45);
  padding: 3px 10px; border-radius: 999px;
  font-size: .76rem; font-weight: 700;
}
.preview-exit:hover { background: rgba(255,255,255,.32); }
/* The sticky topbar sits under the banner rather than over it. */
.preview-bar ~ #app .topbar { top: 0; }

/* The day view's DOM order is plan-then-map, which is what the desktop grid
   wants. Stacked on a phone the map and weather belong at the top, where they
   were before the split - so reorder rather than reshuffle the markup. */
.day-layout { display: flex; flex-direction: column; }
.day-aside { order: -1; }

/* ====================================================================== */
/*  Responsive layout                                                      */
/*                                                                         */
/*  Three sizes, each doing something different rather than just scaling:  */
/*    phone   - one column, compact chrome, thumb-sized targets            */
/*    tablet  - card lists become two columns, maps get taller             */
/*    desktop - the day view splits, with the map parked beside the plan   */
/* ====================================================================== */

/* ----------------------------------------------------- phones (<=430px) - */
@media (max-width: 430px) {
  :root { --gutter: 14px; }

  /* The trip name, the dates and the sharing pill cannot all fit. The pill
     loses its label rather than wrapping onto a second line and pushing the
     header to twice its height. */
  #share-pill .pill-label { display: none; }
  #share-pill { padding: 0 10px; width: 34px; justify-content: center; }
  #share-pill .dot { margin: 0; }

  .topbar h1 { font-size: 1rem; }
  .tab { padding: 7px 11px; font-size: .84rem; }
  .stat-row { grid-template-columns: 1fr; }
  .stat-row.budget-hero { grid-template-columns: 1fr 1fr; }
  /* Yen and the rate footnote stay inside the tile on a narrow phone. */
  .stat-tile, .home-budget-strip, .home-landing { min-width: 0; }
  .budget-head { margin-bottom: 8px !important; }
  .budget-hero .stat-tile { padding: 10px 12px; }
  .budget-hero .stat-value { font-size: 1.22rem; }
  /* Both headline figures stay side by side on a phone and stay large -
     stacking them is what buried per person in the first place. */
  .budget-headline { grid-template-columns: 1fr 1fr; }
  .budget-headline .stat-tile { padding: 11px 12px; }
  .budget-headline .stat-value { font-size: 1.4rem; }
  .budget-context { grid-template-columns: 1fr 1fr; }
  .budget-target, .budget-locked { padding: 9px 12px; }
  .budget-locked > p.muted { display: none; }
  .budget-toggle { margin-top: 6px; padding-bottom: 6px; }
  .budget-toggle .chip { min-height: var(--tap); }
  .budget-breakdown .card { padding: 10px 12px; margin-bottom: 8px; }
  .budget-breakdown .bars { gap: 7px; }
  .budget-breakdown .bar-track { height: 6px; }
  .budget-breakdown .bar-head { font-size: .82rem; }
  .budget-block-title { margin-bottom: 6px; }
  .budget-block-hint { margin: 0 0 6px; }
  .budget-breakdown .list-row { padding: 8px 0; }
  .field-2 { grid-template-columns: 1fr; }
  .leg-time { font-size: 1.15rem; }
  .meta-grid { grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); }
}

/* Very narrow phones: keep the day chips and buttons usable. */
@media (max-width: 360px) {
  .daychip { min-width: 52px; padding: 6px 8px; }
  .tl-time { min-width: 38px; font-size: .8rem; }
}

/* ---------------------------------------------------- tablet (>=720px) - */
@media (min-width: 720px) {
  main { padding-top: 20px; }

  /* Card lists read better as a grid once there is room for two. */
  .cards-2 {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px; align-items: start;
  }
  .cards-2 > .card { margin-bottom: 0; }

  /* Cards of uneven height leave ragged holes in a grid. Where the rows are
     read as pairs - the day-by-day list - stretching them to match is tidier
     than the gaps, and costs only a little padding inside the shorter one. */
  .cards-2.stretch { align-items: stretch; }
  .cards-2.stretch > .card { display: flex; flex-direction: column; }

  .modal { max-width: 560px; }
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  .stat-row.budget-hero { grid-template-columns: repeat(2, 1fr); }
  .budget-fold > .budget-fold-summary {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0);
  }
  /* Charts always show from tablet up. Drop the fold's extra shell so the
     inner cards carry the suitcase border themselves. */
  .budget-fold {
    padding: 0;
    border: 0;
    background: transparent;
  }
  .budget-fold > *:not(summary) { display: block !important; }
  .budget-fold .card {
    background: var(--bg-raised);
    border: var(--stroke) solid var(--line);
    border-radius: var(--radius);
    padding: 14px;
    margin-bottom: 10px;
  }
  .budget-fold .card:last-child {
    margin-bottom: 0;
    border-bottom: var(--stroke) solid var(--line);
  }
}

/* --------------------------------------------------- desktop (>=1040px) - */
@media (min-width: 1040px) {
  :root { --gutter: 24px; }

  /* The day view splits: the plan on the left, the map and weather parked on
     the right where they stay visible while the timeline scrolls. */
  .day-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(340px, 0.85fr);
    gap: 22px; align-items: start;
  }
  /* Side by side, the aside sits on the right where the grid places it. */
  .day-aside { order: 0; }
  .day-aside {
    position: sticky;
    top: calc(112px + var(--safe-top));
    max-height: calc(100dvh - 130px);
    overflow: auto; scrollbar-width: thin;
  }
  .day-aside .map { height: clamp(320px, 46vh, 520px); }

  .stat-row.budget-hero { grid-template-columns: repeat(4, 1fr); }

  /* Hotels, flights and food all render a flat list of cards; two columns
     uses the width without stretching each card to an unreadable line. */
  #panel-hotels .card:not(.tight),
  #panel-flights .flight-card { max-width: none; }

  .map.tall { height: 70dvh; }
  main { padding-bottom: 60px; }

  /* Wide screens have room for the detail grid to breathe. */
  .meta-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}

/* ------------------------------------------------ large desktop (>=1400px) */
@media (min-width: 1400px) {
  .cards-3 {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px; align-items: start;
  }
  .cards-3 > .card { margin-bottom: 0; }
}

/* A pointer device does not need 44px targets, and tighter rows show more. */
@media (hover: hover) and (pointer: fine) {
  .xs { min-height: 30px; }
  .list-row { padding: 9px 0; }
}

/* An inline caution inside a form: the paste box uses it to say a link will
   not work before you press the button and find out. */
.warn-text { color: var(--warn); }

/* ======================================================================= */
/*  Design system                                                           */
/*                                                                          */
/*  Everything below replaces the older component look: pill tabs, thick    */
/*  bordered cards, uppercase micro-labels. It comes last so it wins over   */
/*  the older rules above without rewriting every screen at once.           */
/* ======================================================================= */

html { -webkit-tap-highlight-color: transparent; }
body { min-height: 100dvh; }
button, a, input, select, textarea, [role="button"] { touch-action: manipulation; }
/* iOS zooms the page into any field under 16px. Never let it. */
input, select, textarea { font-size: 16px; }
.money, .cell-value, .bx-amount, .sec-total, .stat-value { font-variant-numeric: tabular-nums; }

/* ----------------------------------------------------------- app bar ---- */
.appbar {
  position: sticky; top: 0; z-index: 900;
  display: flex; align-items: center; gap: 10px;
  padding: calc(8px + var(--safe-top)) calc(var(--gutter) + var(--safe-right)) 8px calc(var(--gutter) + var(--safe-left));
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.appbar-inner { flex: 1; min-width: 0; max-width: var(--page); margin: 0 auto; display: flex; align-items: center; gap: 10px; }
.appbar-titles { flex: 1; min-width: 0; }
.appbar-title {
  margin: 0; font-size: 1rem; font-weight: 650; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.appbar-sub { margin: 1px 0 0; font-size: .8rem; color: var(--text-dim); }
.appbar-back {
  display: inline-flex; align-items: center; gap: 2px;
  min-height: var(--tap); padding: 0 6px 0 0; margin-left: -4px;
  background: none; border: 0; color: var(--accent); font-weight: 500; cursor: pointer;
}
.appbar-back[hidden] { display: none; }
.appbar-account {
  flex: none; width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--bg-sunken); border: 1px solid var(--line); color: var(--text-dim);
  font-size: .78rem; font-weight: 650; cursor: pointer;
}

/* ----------------------------------------------------------- tab bar ---- */
/* Bottom navigation: where the thumb is, as on both iOS and Android. */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
  display: flex; justify-content: center;
  padding: 0 var(--safe-right) var(--safe-bottom) var(--safe-left);
  background: var(--bg-raised);
  border-top: 1px solid var(--line);
}
.tabbar-inner { display: flex; width: 100%; max-width: var(--page); }
.tabbar .tab {
  flex: 1; min-width: 0; height: var(--tabbar-h);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: 0; margin: 0; background: none; border: 0; border-radius: 0;
  color: var(--text-faint); font-size: .7rem; font-weight: 550; letter-spacing: 0;
  cursor: pointer; box-shadow: none;
}
.tabbar .tab svg { width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.tabbar .tab.active { color: var(--accent); background: none; }
.tabbar .tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }

main {
  max-width: var(--page); margin: 0 auto;
  padding: 16px calc(var(--gutter) + var(--safe-right)) calc(var(--tabbar-h) + var(--safe-bottom) + 28px) calc(var(--gutter) + var(--safe-left));
}

/* ------------------------------------------------------ grouped lists --- */
/* The native list idiom on both platforms: rows on a rounded sheet,
   separated by hairlines rather than each boxed on its own. */
.sec-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 10px;
  margin: 26px 4px 8px;
}
.sec-head:first-child { margin-top: 4px; }
.sec-title { margin: 0; font-size: 1.02rem; font-weight: 650; }
.sec-total { font-size: .92rem; font-weight: 600; color: var(--text-dim); white-space: nowrap; }
.sec-note { margin: 8px 4px 0; font-size: .8rem; color: var(--text-faint); }
.sec-head .sec-note { margin: 0; }

.group {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.cell {
  display: flex; align-items: center; gap: 12px;
  width: 100%; min-height: 54px; padding: 10px 14px;
  background: none; border: 0; border-radius: 0; margin: 0;
  color: inherit; text-align: left; font: inherit;
}
.cell + .cell, .cell + .cell-add, .cell-add + .cell-add, .cell-add + .cell { border-top: 1px solid var(--line-soft); }
button.cell { cursor: pointer; }
button.cell:active { background: var(--bg-sunken); }
@media (hover: hover) { button.cell:hover { background: color-mix(in srgb, var(--bg-sunken) 55%, transparent); } }
.cell-main { flex: 1; min-width: 0; }
.cell-title { font-weight: 550; line-height: 1.3; overflow-wrap: anywhere; }
.cell-sub { margin-top: 2px; font-size: .82rem; color: var(--text-dim); line-height: 1.35; }
.cell-value { flex: none; text-align: right; font-weight: 600; white-space: nowrap; }
.cell-value small { display: block; font-size: .76rem; font-weight: 450; color: var(--text-faint); }
.cell-chev { flex: none; width: 8px; height: 8px; margin-left: -2px;
  border-right: 1.6px solid var(--text-faint); border-top: 1.6px solid var(--text-faint); transform: rotate(45deg); }
.cell.is-muted .cell-title, .cell.is-muted .cell-value { color: var(--text-faint); }
.cell-add {
  display: flex; align-items: center; gap: 8px;
  width: 100%; min-height: 48px; padding: 0 14px;
  background: none; border: 0; color: var(--accent); font: inherit; font-weight: 550;
  text-align: left; cursor: pointer;
}
.cell-add:active { background: var(--bg-sunken); }
.tag {
  display: inline-block; padding: 1px 6px; margin-left: 6px; vertical-align: 1px;
  border-radius: 5px; background: var(--bg-sunken); color: var(--text-dim);
  font-size: .7rem; font-weight: 600;
}
.tag.good { background: var(--good-soft); color: var(--good-ink); }
.tag.bad  { background: var(--bad-soft);  color: var(--bad); }
.tag.accent { background: var(--accent-soft); color: var(--accent); }

/* A thin magnitude bar under a row: one hue, because it compares sizes,
   not identities. */
.track { height: 4px; margin-top: 7px; border-radius: 2px; background: var(--bg-sunken); overflow: hidden; }
.track-fill { height: 100%; border-radius: 2px; background: var(--accent); }
.track-fill.over { background: var(--bad); }
.track-fill.ok   { background: var(--good); }

/* Segmented control, the native way to switch a view in place. */
.seg {
  display: inline-flex; padding: 2px; gap: 2px;
  background: var(--bg-sunken); border-radius: 9px;
}
.seg button {
  min-height: 30px; padding: 0 12px; border: 0; border-radius: 7px;
  background: none; color: var(--text-dim); font: inherit; font-size: .82rem; font-weight: 550; cursor: pointer;
}
.seg button[aria-pressed="true"] { background: var(--bg-raised); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.12); }

/* ------------------------------------------------------------ budget ---- */
.bx-hero { padding: 6px 4px 18px; }
.bx-kicker { font-size: .85rem; color: var(--text-dim); }
.bx-amount { margin: 2px 0 0; font-size: 2.6rem; font-weight: 700; letter-spacing: -.025em; line-height: 1.05; }
.bx-meta { margin: 8px 0 0; font-size: .9rem; color: var(--text-dim); }
.bx-meta button {
  padding: 0; border: 0; background: none; font: inherit; color: var(--accent); cursor: pointer;
  min-height: 0; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px;
}
.bx-yen { margin: 2px 0 0; font-size: .82rem; color: var(--text-faint); }
.status-over { color: var(--bad); }
.status-ok { color: var(--good); }

/* ------------------------------------------------------------ notices --- */
.notice {
  display: block; width: 100%; margin-top: 12px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg-raised); color: inherit; font: inherit; text-align: left;
}
button.notice { cursor: pointer; }
.notice strong { display: block; font-weight: 600; }
.notice span { display: block; margin-top: 2px; font-size: .84rem; color: var(--text-dim); }
.notice.warn { border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); }

/* --------------------------------------------------- older primitives --- */
/* Calmer versions of the shared pieces the trip screens still use. */
.card { border-width: 1px; border-radius: var(--radius); box-shadow: none; }
.chip {
  border-radius: 8px; border-width: 1px; box-shadow: none;
  font-weight: 550; min-height: 34px;
}
.chip.on { background: var(--accent-soft); color: var(--accent); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.badge { border-radius: 6px; font-weight: 600; text-transform: none; letter-spacing: 0; }
.stat-label { text-transform: none; letter-spacing: 0; font-size: .82rem; font-weight: 550; }
h2 { font-size: 1.3rem; font-weight: 700; letter-spacing: -.015em; }

button.primary, a.primary {
  background: var(--accent); color: var(--accent-ink); border: 1px solid var(--accent);
  border-radius: 10px; box-shadow: none; font-weight: 600;
}
button.secondary, a.secondary {
  background: var(--bg-raised); color: var(--text); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: none; font-weight: 550;
}
button.ghost, a.ghost { border-radius: 10px; box-shadow: none; }
button.danger { border-radius: 10px; box-shadow: none; }

input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea {
  min-height: var(--tap); border-radius: 10px; border: 1px solid var(--line);
  background: var(--bg-raised); padding: 10px 12px;
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent); outline-offset: 0; border-color: var(--accent);
}

/* ------------------------------------------------------- bottom sheets -- */
/* On a phone every editor slides up from the bottom, clear of the notch and
   the home indicator. On a wide screen it stays a centred dialog. */
@media (max-width: 719px) {
  .modal-backdrop { align-items: flex-end; padding: 0; }
  .modal {
    width: 100%; max-width: none; max-height: calc(100dvh - var(--safe-top) - 24px);
    margin: 0; overflow-y: auto; overscroll-behavior: contain;
    border-radius: 16px 16px 0 0; border-width: 1px 0 0;
    padding-bottom: calc(16px + var(--safe-bottom));
    animation: sheet-up .22s ease-out;
  }
  .modal::before {
    content: ""; display: block; width: 36px; height: 5px; border-radius: 3px;
    margin: -4px auto 12px; background: var(--line);
  }
  .modal-actions { position: sticky; bottom: calc(-16px - var(--safe-bottom)); background: var(--bg-raised); padding-bottom: 4px; }
  .modal-actions button { flex: 1; min-height: var(--tap); }
}
@keyframes sheet-up { from { transform: translateY(24px); opacity: .6; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .modal { animation: none; } }

.stepper { display: inline-flex; align-items: center; gap: 0; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.stepper button { width: 48px; min-height: var(--tap); border: 0; background: var(--bg-sunken); font-size: 1.3rem; color: var(--text); cursor: pointer; }
.stepper input { width: 72px; text-align: center; border: 0 !important; border-radius: 0 !important; font-weight: 650; }

/* The old toast sat where the tab bar now is. */
.toast { bottom: calc(var(--tabbar-h) + var(--safe-bottom) + 12px) !important; }

@media (hover: hover) and (pointer: fine) {
  .cell { min-height: 48px; }
}

/* A checkbox with its label, sized for a thumb. */
.check-row { display: flex !important; flex-direction: row !important; align-items: flex-start; gap: 12px; min-height: var(--tap); cursor: pointer; }
.check-row input { width: 22px; height: 22px; margin: 1px 0 0; flex: none; accent-color: var(--accent); }
.check-row small { display: block; font-size: .8rem; color: var(--text-faint); font-weight: 400; }
.plan-all { margin: 0 0 6px -2px; min-height: 36px; }

/* Layers, lowest to highest: page, app bar and tab bar, sheets, toasts.
   A sheet must cover the tab bar - otherwise the bar sits over the sheet's
   own buttons at the bottom of the screen, exactly where the thumb goes. */
.modal-backdrop { z-index: 1000; }
.toast { z-index: 1100; }

/* ----------------------------------------------- touch-size targets ---- */
.seg button { min-height: 36px; padding: 0 14px; }
.bx-meta button { display: inline-block; padding: 8px 2px; margin: -8px -2px; }
/* On a touchscreen the older compact buttons grow to thumb size; a mouse
   keeps them compact. */
@media (pointer: coarse) {
  .xs, button.xs, a.xs { min-height: 40px; padding-left: 14px; padding-right: 14px; }
  .leaflet-bar a, .leaflet-touch .leaflet-bar a { width: 40px !important; height: 40px !important; line-height: 40px !important; }
  .stepper button { width: 52px; }
  .chip { min-height: 40px; }
}
@media (prefers-reduced-motion: reduce) { .panel.active { animation: none; } }
/* Caption for a button-based control; looks like a label, isn't one. */
.field { display: flex; flex-direction: column; gap: 5px; }
.field-caption { font-size: .85rem; color: var(--text-dim); font-weight: 600; }

/* ======================================================================= */
/*  Signature layer                                                         */
/*                                                                          */
/*  Type, cards, charts and motion for the budget screens. Last in the file */
/*  so it settles every earlier rule it touches.                            */
/* ======================================================================= */

.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* A table grows to fit its rows whatever height it is given, so a hidden
   one (the chart's text version) stretched the page far below the last
   card. As a block it keeps to 1px. */
table.sr-only { display: block; }

/* ------------------------------------------------------------- type ---- */
.page-head { margin: 6px 4px 18px; }
.eyebrow {
  margin: 0 0 6px; font-size: .72rem; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text-faint);
}
.page-title {
  margin: 0; font-family: var(--font-display); font-weight: 400;
  font-size: clamp(2.2rem, 9vw, 2.8rem); line-height: 1; letter-spacing: -.012em;
}
.sec-title { font-size: 1.04rem; font-weight: 620; letter-spacing: -.01em; display: flex; align-items: center; gap: 9px; }
.sec-head { margin: 30px 4px 10px; }
.sec-note { line-height: 1.45; }
.modal h2 { font-family: var(--font-display); font-weight: 400; font-size: 1.75rem; letter-spacing: -.01em; margin-bottom: 14px; }

/* Figures: proportional for the one big number, tabular wherever numbers stack. */
.bx-amount { font-variant-numeric: proportional-nums; font-feature-settings: "tnum" 0; }
.cell-value, .legend-value, .sec-total, .dayaxis, .viz-tip { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- cards --- */
.group, .viz-card, .hero-card, .notice, .pay-card {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}
.hero-card { padding: 22px 20px 8px; margin-bottom: 14px; border-radius: 22px; }
.viz-card { padding: 16px 16px 12px; }
.hero-card .bx-hero { padding: 0; }
.bx-kicker { font-size: .8rem; font-weight: 550; color: var(--text-dim); letter-spacing: .01em; }
.bx-amount {
  margin: 4px 0 0; font-size: clamp(2.7rem, 12.5vw, 3.6rem); font-weight: 620;
  letter-spacing: -.034em; line-height: .98;
}
.bx-meta { margin-top: 10px; font-size: .92rem; }
.bx-yen { margin-top: 3px; }

/* ----------------------------------------------------- status pill ---- */
.status-pill {
  display: inline-flex; align-items: center; gap: 8px;
  margin: 16px 0 0; padding: 6px 13px 6px 7px; border-radius: 999px;
  font-size: .9rem; font-weight: 620; letter-spacing: -.005em;
}
.status-pill.is-over { background: var(--bad-soft); color: var(--bad); }
.status-pill.is-ok   { background: var(--good-soft); color: var(--good-ink); }
.status-icon {
  display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  font-size: .78rem; font-weight: 800; line-height: 1; color: var(--bg-raised);
}
.status-pill.is-over .status-icon { background: var(--bad); }
.status-pill.is-ok .status-icon { background: var(--good); }

/* -------------------------------------------------- allocation bar ---- */
.alloc { position: relative; margin: 20px 0 6px; padding-top: 30px; }
.alloc-track { position: relative; height: 16px; border-radius: 8px; background: var(--bg-sunken); touch-action: pan-y; cursor: crosshair; }
.alloc-bar { display: flex; gap: 2px; height: 100%; border-radius: 8px; overflow: hidden; }
.alloc-seg {
  height: 100%; min-width: 3px; flex: none;
  transform-origin: left center; animation: grow-x .8s var(--ease) both;
  transition: opacity .18s ease;
}
.alloc-seg.is-dim { opacity: .28; }
.alloc-over {
  position: absolute; top: 0; bottom: 0; border-radius: 0 8px 8px 0; pointer-events: none;
  background: repeating-linear-gradient(135deg,
    transparent 0 3px, color-mix(in srgb, var(--bg-raised) 70%, transparent) 3px 5.5px);
}
.alloc-mark {
  position: absolute; top: -30px; bottom: -6px; width: 0; pointer-events: none;
  border-left: 2px solid var(--ink);
}
.alloc-mark span {
  position: absolute; top: 0; left: 7px; white-space: nowrap;
  font-size: .74rem; font-weight: 620; color: var(--text); font-variant-numeric: tabular-nums;
}
.alloc-mark.is-right span { left: auto; right: 7px; }
@keyframes grow-x { from { transform: scaleX(0); } to { transform: none; } }

/* The bar's legend doubles as the list of categories. */
.legend { margin-top: 20px; border-top: 1px solid var(--line-soft); }
.legend-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 10px; padding: 16px 0 6px; }
.legend-row {
  display: grid; grid-template-columns: 10px minmax(0, 1fr) 5.8rem 8px; align-items: center; gap: 12px;
  width: 100%; min-height: 56px; padding: 8px 2px; margin: 0;
  background: none; border: 0; border-radius: 0; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.legend-row + .legend-row { border-top: 1px solid var(--line-soft); }
.legend-row:active { background: var(--bg-sunken); }
@media (hover: hover) { .legend-row:hover .legend-name { color: var(--accent); } }
.legend-name { font-weight: 560; min-width: 0; }
.legend-track { display: block; height: 4px; margin-top: 8px; border-radius: 2px; background: var(--bg-sunken); overflow: hidden; }
.legend-fill { display: block; height: 100%; border-radius: 2px; transform-origin: left; animation: grow-x .8s var(--ease) both; animation-delay: .15s; }
.legend-value { text-align: right; font-weight: 620; white-space: nowrap; }
.legend-value small { display: block; font-size: .74rem; font-weight: 450; color: var(--text-faint); }

.swatch { display: inline-block; flex: none; width: 10px; height: 10px; border-radius: 3px; }

/* ---------------------------------------------------------- tooltip ---- */
.viz-tip {
  position: absolute; top: -4px; z-index: 5; pointer-events: none;
  padding: 7px 10px; border-radius: 10px;
  background: var(--ink); color: var(--ink-on);
  font-size: .78rem; line-height: 1.3; white-space: nowrap;
  box-shadow: 0 8px 20px -8px rgba(0, 0, 0, .35);
  animation: tip-in .14s ease-out;
}
.viz-tip strong { display: block; font-weight: 650; }
.viz-tip span { opacity: .8; }
@keyframes tip-in { from { opacity: 0; transform: translateY(3px); } }

/* ------------------------------------------------------- day chart ---- */
.daychart { position: relative; margin: 0; }
.daycols {
  display: flex; align-items: stretch; gap: 2px; height: 148px; padding-top: 26px;
  border-bottom: 1px solid var(--line); touch-action: pan-y; cursor: crosshair;
}
.daycol { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; }
.daycol-bar {
  width: 100%; max-width: 22px; border-radius: 4px 4px 0 0; background: var(--accent);
  transform-origin: bottom; animation: grow-y .7s var(--ease) both; transition: opacity .15s ease;
}
.daycol.is-today .daycol-bar { background: var(--ink); }
.daycols.is-reading .daycol:not(.is-read) .daycol-bar { opacity: .3; }
.daycol-peak {
  flex: none; margin-bottom: 5px; white-space: nowrap;
  font-size: .72rem; font-weight: 620; color: var(--text-dim); font-variant-numeric: tabular-nums;
}
.dayaxis { display: flex; justify-content: space-between; margin-top: 7px; font-size: .72rem; color: var(--text-faint); }
@keyframes grow-y { from { transform: scaleY(0); } to { transform: none; } }

/* ------------------------------------------------------------ ring ----- */
.hero-mine { display: flex; flex-direction: column; align-items: center; text-align: center; padding-bottom: 18px; }
.ring { position: relative; width: min(236px, 66vw); aspect-ratio: 1; margin: 2px auto 0; }
.ring-svg { width: 100%; height: 100%; display: block; }
.ring-track { stroke: var(--bg-sunken); }
.ring-arc { animation: ring-draw 1s var(--ease) both; }
.ring-tick { stroke: var(--ink); stroke-width: 3; stroke-linecap: round; }
@keyframes ring-draw { from { stroke-dasharray: 0 2000; } }
.ring-center { position: absolute; inset: 0; display: grid; place-content: center; gap: 2px; }
.ring-center .bx-amount { font-size: clamp(2rem, 9vw, 2.45rem); letter-spacing: -.04em; margin: 2px 0; }
.ring-sub { margin: 0; font-size: .84rem; color: var(--text-faint); }
.hero-mine .status-pill { margin-top: 10px; }
.ring-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px; margin: 14px 0 0; font-size: .84rem; color: var(--text-dim); }
.ring-legend span { display: inline-flex; align-items: center; gap: 7px; }
.ring-legend b { color: var(--text); font-weight: 620; font-variant-numeric: tabular-nums; }

/* ------------------------------------------------ lists, refined ------ */
.cell { min-height: 56px; padding: 11px 16px; }
.cell .swatch { margin-right: -2px; }
.cell-title { font-weight: 560; }
.cell-value { font-weight: 620; }
.cell-add { min-height: 52px; padding: 0 16px; }
.cell-add { border-radius: 0; }
.cell-add.is-new::before {
  content: "+"; display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent); font-weight: 700; line-height: 1;
}
.track { height: 5px; border-radius: 3px; }
.track-fill { border-radius: 3px; transform-origin: left; animation: grow-x .8s var(--ease) both; }
.seg { border-radius: 11px; padding: 3px; }
.seg button { border-radius: 8px; font-weight: 600; }
.seg button[aria-pressed="true"] { background: var(--seg-on); box-shadow: 0 1px 2px rgba(0,0,0,.10), 0 2px 8px -4px rgba(0,0,0,.18); }
.mini.active { background: var(--seg-on); }

/* ------------------------------------------------------- buttons ------ */
button.primary, a.primary {
  background: var(--ink); color: var(--ink-on); border: 1px solid var(--ink);
  border-radius: 12px; font-weight: 620; letter-spacing: -.005em;
}
button.secondary, a.secondary { border-radius: 12px; }
button.primary, button.secondary, button.danger, .cell, .legend-row, .tabbar .tab {
  transition: transform .12s var(--ease), background-color .15s ease, opacity .15s ease;
}
button.primary:active, button.secondary:active, button.danger:active { transform: scale(.97); }
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select, textarea { border-radius: 12px; }

/* ---------------------------------------------------- app chrome ------ */
.appbar { background: var(--bg); }
.appbar-title { font-weight: 620; letter-spacing: -.01em; }
.appbar-account { background: var(--ink); color: var(--ink-on); border: 0; font-weight: 650; }
.tabbar { background: var(--bg-raised); box-shadow: 0 -8px 24px -18px rgba(0, 0, 0, .25); }
.tabbar .tab { position: relative; color: var(--text-faint); font-weight: 560; }
.tabbar .tab.active { color: var(--ink); font-weight: 650; }
.tabbar .tab.active svg { stroke-width: 2.1; }
.tabbar .tab.active::before {
  content: ""; position: absolute; top: 0; left: 50%; width: 26px; height: 3px; margin-left: -13px;
  border-radius: 0 0 3px 3px; background: var(--ink);
}
.tabbar .tab:active svg { transform: scale(.9); }
.tabbar .tab svg { transition: transform .12s var(--ease); }

/* ---------------------------------------------------------- sheets ---- */
@media (max-width: 719px) {
  .modal { border-radius: 24px 24px 0 0; padding-left: 20px; padding-right: 20px; }
  .modal-actions button { min-height: 50px; border-radius: 14px; }
}
.modal-backdrop { background: rgba(15, 14, 10, .42); }

/* ---------------------------------------------------------- notices --- */
.notice { padding: 14px 16px; }
.notice strong { font-weight: 620; }

/* ---------------------------------------------------------- sign in --- */
/* Sign-in: the card sits over an indigo seigaiha band, the same waves as
   the trip's pass, so the first screen already looks like the product. */
.gate { position: relative; background: var(--bg); isolation: isolate; }
.gate::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 320px; z-index: 0; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(29, 61, 112, 0) 55%, var(--bg)),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='24' viewBox='0 0 48 24'%3E%3Cg stroke='rgba%28255%2C255%2C255%2C.16%29' stroke-width='1.3'%3E%3Ccircle cx='24' cy='0' r='24' fill='%231d3d70'/%3E%3Ccircle cx='24' cy='0' r='24' fill='none'/%3E%3Ccircle cx='24' cy='0' r='18' fill='none'/%3E%3Ccircle cx='24' cy='0' r='12' fill='none'/%3E%3Ccircle cx='24' cy='0' r='6' fill='none'/%3E%3Ccircle cx='0' cy='12' r='24' fill='%231d3d70'/%3E%3Ccircle cx='0' cy='12' r='24' fill='none'/%3E%3Ccircle cx='0' cy='12' r='18' fill='none'/%3E%3Ccircle cx='0' cy='12' r='12' fill='none'/%3E%3Ccircle cx='0' cy='12' r='6' fill='none'/%3E%3Ccircle cx='48' cy='12' r='24' fill='%231d3d70'/%3E%3Ccircle cx='48' cy='12' r='24' fill='none'/%3E%3Ccircle cx='48' cy='12' r='18' fill='none'/%3E%3Ccircle cx='48' cy='12' r='12' fill='none'/%3E%3Ccircle cx='48' cy='12' r='6' fill='none'/%3E%3Ccircle cx='24' cy='24' r='24' fill='%231d3d70'/%3E%3Ccircle cx='24' cy='24' r='24' fill='none'/%3E%3Ccircle cx='24' cy='24' r='18' fill='none'/%3E%3Ccircle cx='24' cy='24' r='12' fill='none'/%3E%3Ccircle cx='24' cy='24' r='6' fill='none'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 48px 24px;
}
.gate-card { position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
  .pass, .bell-count, .approve-count { animation: none; }
  .hub-next .hub-kicker::before { animation: none; }
}
.gate-card { border-radius: 24px; box-shadow: var(--shadow-card); border: 1px solid var(--line); background: var(--bg-raised); }
.gate-brand h1 { font-family: var(--font-display); font-weight: 400; font-size: 2.5rem; letter-spacing: -.01em; line-height: 1; margin: 14px 0 6px; }
.tabs-mini { background: var(--bg-sunken); border: 0; border-radius: 12px; padding: 3px; gap: 3px; }
.mini { border-radius: 9px; color: var(--text-dim); }
.mini.active { background: var(--bg-raised); color: var(--text); box-shadow: 0 1px 2px rgba(0,0,0,.1), 0 2px 8px -4px rgba(0,0,0,.18); }

/* ---------------------------------------------------------- motion ---- */
@media (prefers-reduced-motion: reduce) {
  .alloc-seg, .legend-fill, .track-fill, .daycol-bar, .ring-arc, .viz-tip { animation: none !important; }
  button.primary:active, button.secondary:active, button.danger:active { transform: none; }
}

/* "From the group" is all six categories at once. */
.swatch-multi {
  background: conic-gradient(var(--cat-1) 0 60deg, var(--cat-2) 0 120deg, var(--cat-3) 0 180deg,
    var(--cat-4) 0 240deg, var(--cat-5) 0 300deg, var(--cat-6) 0 360deg);
  border-radius: 50%;
}

/* Inline text buttons still get a thumb-sized hit area on a touchscreen. */
@media (pointer: coarse) {
  .linkish { display: inline-flex; align-items: center; min-height: 40px; padding: 0 6px; margin: -11px -6px; }
}

/* ======================================================================= */
/*  Trip screens                                                            */
/*                                                                          */
/*  Plan, Stays, Flights, Attractions, Food, Trains, People and the         */
/*  account sheet, brought into the same language as the budget: display    */
/*  titles, raised cards, sentence-case labels, ink for the chosen option.  */
/* ======================================================================= */

/* ------------------------------------------------------------ heading --- */
.screen-head { margin-bottom: 20px; }
.page-sub { margin: 8px 0 0; font-size: .92rem; color: var(--text-dim); }
.screen-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.screen-actions .row { gap: 8px !important; flex-wrap: wrap; }
.screen-actions button.xs, .screen-actions a.xs {
  min-height: 42px; padding: 0 18px; border-radius: 999px; font-size: .9rem;
}

/* -------------------------------------------------------------- cards --- */
.card {
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-card);
  padding: 16px; margin-bottom: 12px;
}
.card.tight { padding: 12px 14px; }
.card-head { gap: 12px; margin-bottom: 10px; }
.card-head h3, .card h3 { font-size: 1.06rem; font-weight: 620; letter-spacing: -.01em; }
.xs, button.xs, a.xs { border-radius: 10px; font-weight: 560; }

/* Action rows inside cards: one quiet pill style, the main action in ink. */
.tl-actions { gap: 8px; margin-top: 12px; }
.tl-actions button.xs, .tl-actions a.xs,
.tl-actions button.ghost, .tl-actions a.ghost,
.tl-actions button.secondary, .tl-actions a.secondary {
  min-height: 36px; padding: 0 14px; border-radius: 999px;
  display: inline-flex; align-items: center;
  background: var(--bg-sunken); border: 1px solid transparent; color: var(--text);
  text-decoration: none; font-size: .86rem; font-weight: 560; box-shadow: none;
}
.tl-actions button.primary, .tl-actions a.primary {
  min-height: 36px; padding: 0 16px; border-radius: 999px; font-size: .86rem;
  display: inline-flex; align-items: center; text-decoration: none;
}
.tl-actions .linkish { text-decoration: none; }
.tl-notes { border-left-color: var(--line); color: var(--text-dim); }

/* -------------------------------------------------------------- chips --- */
.filters { gap: 8px; padding: 2px 2px 14px; }
.chip {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 38px; padding: 0 15px; border-radius: 999px;
  background: var(--bg-raised); border: 1px solid var(--line); color: var(--text);
  font-weight: 560; font-size: .88rem; box-shadow: none; white-space: nowrap;
}
.chip.on { background: var(--ink); border-color: var(--ink); color: var(--ink-on); }
.attr-areas .chip { border-radius: 14px; padding: 7px 14px; }
.chip-sub { font-weight: 450; opacity: .72; }

.daychip { border-radius: 14px; min-width: 60px; box-shadow: none; }
.daychip .dow { text-transform: none; letter-spacing: 0; font-size: .7rem; }
.daychip.active { background: var(--ink); border-color: var(--ink); color: var(--ink-on); }
.daychip.active .dow, .daychip.active .dcount { color: color-mix(in srgb, var(--ink-on) 72%, transparent); }
.daychip.is-today:not(.active) { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }

/* ------------------------------------------------------------- badges --- */
.badge {
  border: 0; padding: 3px 9px; border-radius: 999px;
  background: var(--bg-sunken); color: var(--text-dim);
  font-size: .72rem; font-weight: 600; letter-spacing: 0;
}
.badge.good   { background: var(--good-soft); color: var(--good-ink); border: 0; }
.badge.warn   { background: color-mix(in srgb, var(--warn) 12%, transparent); color: var(--warn); border: 0; }
.badge.bad    { background: var(--bad-soft); color: var(--bad); border: 0; }
/* "In 183 days" and similar: information, never alarm. */
.badge.accent { background: var(--accent-soft); color: var(--accent); border: 0; }

/* ------------------------------------------------------------ banners --- */
.banner {
  gap: 12px; padding: 14px 16px; border-radius: 14px; font-size: .88rem; line-height: 1.45;
  background: var(--bg-raised); border: 1px solid var(--line); box-shadow: var(--shadow-card);
}
.banner::before {
  content: ""; flex: none; width: 8px; height: 8px; margin-top: 7px; border-radius: 50%;
  background: var(--text-faint);
}
.banner.warn { background: color-mix(in srgb, var(--warn) 6%, var(--bg-raised)); border-color: color-mix(in srgb, var(--warn) 28%, var(--line)); }
.banner.warn::before { background: var(--warn); }
.banner.info { background: color-mix(in srgb, var(--accent) 5%, var(--bg-raised)); border-color: color-mix(in srgb, var(--accent) 24%, var(--line)); }
.banner.info::before { background: var(--accent); }
.banner.good { background: color-mix(in srgb, var(--good) 6%, var(--bg-raised)); border-color: color-mix(in srgb, var(--good) 26%, var(--line)); }
.banner.good::before { background: var(--good); }
.banner.bad  { background: color-mix(in srgb, var(--bad) 5%, var(--bg-raised)); border-color: color-mix(in srgb, var(--bad) 26%, var(--line)); }
.banner.bad::before  { background: var(--bad); }
.banner strong { font-weight: 620; }

/* ------------------------------------------------------ facts (grids) --- */
/* Gate, fare, check-in, nights: a hairline table, not grey boxes. */
.meta-grid {
  gap: 1px; background: var(--line-soft); border: 1px solid var(--line-soft);
  border-radius: 12px; overflow: hidden;
}
.meta-grid div { background: var(--bg-raised); border-radius: 0; padding: 10px 12px; }
.meta-grid dt, .rate-card dt {
  text-transform: none; letter-spacing: 0; font-size: .76rem; font-weight: 500; color: var(--text-faint);
}
.meta-grid dd, .rate-card dd { font-size: .96rem; font-weight: 620; }
.rate-grid { gap: 8px; }
.rate-card { background: var(--bg); border: 1px solid var(--line-soft); border-radius: 12px; padding: 10px 12px; }
.rate-card.is-stay { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }

/* ------------------------------------------------------------ flights --- */
.leg-time { font-size: 1.6rem; font-weight: 620; letter-spacing: -.03em; }
.leg-code { color: var(--text); font-weight: 650; }
.leg-offset { color: var(--text-faint); }
.leg-terminal { color: var(--text-dim); }
.leg-line { height: 1.5px; background: var(--line); }

/* ----------------------------------------------------------- timeline --- */
.timeline::before { width: 1.5px; background: var(--line); }
.tl-time { color: var(--text); font-weight: 620; }
.tl-item::before { background: var(--bg-raised); }

/* Plan's "what's next": the one card that talks about right now. */
.whats-next {
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: 18px; box-shadow: var(--shadow-card); padding: 16px;
}
.whats-next-kicker {
  font-size: .72rem; font-weight: 600; letter-spacing: .09em; text-transform: uppercase; color: var(--accent);
}
.whats-next-title { font-size: 1.1rem; font-weight: 620; letter-spacing: -.01em; }

/* -------------------------------------------------------------- maps ---- */
.map { border-radius: 18px; border: 1px solid var(--line); box-shadow: var(--shadow-card); margin-bottom: 14px; }
.leaflet-bar, .leaflet-touch .leaflet-bar {
  border: 0 !important; border-radius: 12px !important; overflow: hidden;
  box-shadow: 0 1px 2px rgba(0,0,0,.12), 0 6px 16px -8px rgba(0,0,0,.3) !important;
}
.leaflet-bar a, .leaflet-bar a:hover { background: var(--bg-raised); color: var(--text); border-bottom-color: var(--line-soft); }
.leaflet-popup-content-wrapper { border-radius: 14px; box-shadow: var(--shadow-card); }

/* ------------------------------------------------------ lists & empty --- */
.list-row { padding: 12px 2px; border-bottom-color: var(--line-soft); }
.empty {
  background: transparent; border: 1.5px dashed var(--line); border-radius: 18px;
  padding: 36px 20px; color: var(--text-dim);
}
.empty p:first-child { font-weight: 560; color: var(--text); }

/* -------------------------------------------------------- attractions --- */
.attr-num { background: var(--ink) !important; color: var(--ink-on); font-weight: 700; }
.attr-badges .badge { font-size: .7rem; }

/* ------------------------------------------------------ account sheet --- */
.account-sheet { display: flex; flex-direction: column; gap: 14px; }
.account-id { display: flex; align-items: center; gap: 12px; padding: 2px 2px 4px; }
.account-id strong { font-size: 1.02rem; font-weight: 620; }
.account-avatar {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ink); color: var(--ink-on); font-weight: 650;
}
.account-sheet .group { box-shadow: none; }
.account-sheet .danger { min-height: var(--tap); }

/* Fact grid cells hold nested text boxes; only the cell itself is padded. */
.meta-grid div div { padding: 0; background: none; }

/* Stays: how many people the rooms are for, as a proper stepper card. */
.rooms-for-card {
  display: flex; align-items: center; gap: 14px; margin: 0 0 14px; padding: 12px 14px 12px 16px;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-card);
}
.rooms-for-title { font-weight: 600; }
.rooms-stepper { display: flex; align-items: center; gap: 6px; flex: none; }
.rooms-stepper button {
  width: 40px; height: 40px; border-radius: 50%; border: 0; padding: 0;
  background: var(--bg-sunken); color: var(--text); font-size: 1.2rem; font-weight: 500; cursor: pointer;
}
.rooms-stepper button:active { transform: scale(.94); }
.rooms-count { display: flex; flex-direction: column; align-items: center; min-width: 48px; line-height: 1.1; }
.rooms-count .people-count { font-size: 1.15rem; font-weight: 650; font-variant-numeric: tabular-nums; }
.rooms-count .muted { font-size: .72rem; }

.account-signout { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.account-signout button { min-height: var(--tap); padding: 0 10px; white-space: nowrap; font-size: .92rem; }

/* Plan, one day: the date is the page's name. */
.day-title { font-size: clamp(2rem, 8.5vw, 2.5rem); }
.day-head { align-items: flex-end !important; }
.day-head .primary.xs { min-height: 42px; padding: 0 18px; border-radius: 999px; font-size: .9rem; }
.soft-landing .day-title { margin-top: 4px; }

/* "What's around here" sits on the page like every other card. */
.nearby-control {
  margin: 0 0 14px; padding: 14px 16px;
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-card);
}
.nearby-control > .spread strong { font-size: 1rem; font-weight: 620; }
.nearby-chips { gap: 8px; }
.nearby-chips .chip { font-size: .84rem; }

/* ======================================================================= */
/*  The route                                                               */
/*                                                                          */
/*  The trip as one path, stay by stay. Stays and Plan draw it the same     */
/*  way: a line down the left, a node for each place you sleep, and the     */
/*  nights with no bed on a dashed stretch so they cannot be missed.        */
/* ======================================================================= */

.route { list-style: none; margin: 0; padding: 0; position: relative; }
.route-leg { position: relative; padding-left: 28px; }
/* The line between nodes; dashed where there is no bed. */
.route-leg::before {
  content: ""; position: absolute; left: 7px; top: 0; bottom: 0; width: 2px;
  background: var(--line);
}
.route-leg:first-child::before { top: 18px; }
.route-leg:last-child::before { bottom: calc(100% - 18px); }
.route-leg.is-gap::before, .route-leg.is-arrive::before, .route-leg.is-home::before, .route-leg.is-plane::before {
  background: repeating-linear-gradient(to bottom, var(--line) 0 4px, transparent 4px 8px);
}
.route-node {
  position: absolute; left: 0; top: 11px; width: 16px; height: 16px; border-radius: 50%;
  background: var(--bg-raised); border: 2px solid var(--ink); z-index: 1;
}
.route-leg.is-stay .route-node { background: var(--ink); box-shadow: inset 0 0 0 3px var(--bg-raised); }
.route-leg.is-gap .route-node { border-color: var(--warn); border-style: dashed; }
.route-leg.is-arrive .route-node, .route-leg.is-home .route-node, .route-leg.is-plane .route-node { border-color: var(--text-faint); }

.route-hit {
  display: block; width: 100%; padding: 8px 4px 12px; margin: 0; text-align: left;
  background: none; border: 0; border-radius: 10px; color: inherit; font: inherit;
}
button.route-hit { cursor: pointer; }
button.route-hit:active { background: var(--bg-sunken); }
.route-hit > .route-node { left: -28px; }
.route-hit { position: relative; }
.route-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.route-title { font-weight: 620; font-size: 1.02rem; letter-spacing: -.01em; }
.route-value { font-weight: 620; font-variant-numeric: tabular-nums; white-space: nowrap; }
.route-act { font-size: .84rem; font-weight: 600; color: var(--accent); white-space: nowrap; }
.route-sub { margin: 2px 0 0; font-size: .84rem; color: var(--text-dim); }
.route-hotel { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
/* Names run from "Dai-ichi Takimotokan" to "Stay SAKURA Kyoto Station
   Shichijo": a long one wraps to a second line rather than being cut, and
   the status sits at the right edge whatever the name's length. */
.route-hotel-name {
  flex: 1; min-width: 0; padding-top: 2px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere;
}
.route-hotel .badge { flex: none; margin-left: auto; }
.route-leg.is-gap .route-title { color: var(--warn); }
.route-leg.is-arrive .route-title, .route-leg.is-home .route-title, .route-leg.is-plane .route-title { color: var(--text-dim); }

.route-card { padding: 16px 14px 8px 16px; }
.route-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 0 2px 10px 0; }
.route-foot {
  display: flex; justify-content: space-between; align-items: baseline;
  margin: 2px 0 6px; padding: 12px 4px 4px 28px; border-top: 1px solid var(--line-soft);
  font-size: .92rem; color: var(--text-dim);
}
.route-foot strong { color: var(--text); font-weight: 650; font-variant-numeric: tabular-nums; }

/* Stays: a card the route jumped to glows briefly. */
.hotel-card { scroll-margin-top: calc(76px + var(--safe-top)); }
.hotel-card.is-flash { animation: card-flash 1.4s ease-out; }
@keyframes card-flash { 0%, 30% { box-shadow: 0 0 0 3px var(--accent), var(--shadow-card); } 100% { box-shadow: var(--shadow-card); } }
.hotel-card .eyebrow { letter-spacing: .06em; }
.hotel-card .card-head .badge { flex: none; }
.hotel-name { overflow-wrap: anywhere; }
.hotel-actions { margin-top: 12px; }
/* Side by side, every stay card is the same height: the name keeps two
   lines whether it needs them or not, and the buttons sit at the bottom. */
@media (min-width: 720px) {
  .hotel-card .eyebrow { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .hotel-name {
    min-height: calc(2 * 1.3em); line-height: 1.3;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .cards-2.stretch > .hotel-card .hotel-actions { margin-top: auto; padding-top: 12px; }
  .cards-2.stretch > .hotel-card .notes-wrap { margin-bottom: 4px; }
}
.notes-wrap { margin-top: 12px; }
.tl-notes.is-folded { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.notes-more { margin-top: 4px; font-size: .84rem; font-weight: 600; color: var(--accent); }

/* ------------------------------------------------------------ Plan ------ */
.plan-route .route-leg { padding-bottom: 18px; }
.plan-route .route-leg::before { bottom: -2px; }
.plan-route .route-leg:last-child::before { bottom: auto; height: 18px; }
.plan-route .route-node { top: 6px; }
.leg-head { padding: 2px 0 10px; }
.leg-title { margin: 0; font-family: var(--font-display); font-weight: 400; font-size: 1.7rem; line-height: 1.05; letter-spacing: -.01em; }
.route-leg.is-arrive .leg-title, .route-leg.is-home .leg-title, .route-leg.is-plane .leg-title { color: var(--text-dim); }
.leg-days {
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-card); overflow: hidden;
}
.day-row {
  display: grid; grid-template-columns: 46px minmax(0, 1fr) auto; gap: 12px; align-items: start;
  width: 100%; padding: 12px 14px; margin: 0; background: none; border: 0; border-radius: 0;
  color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.day-row + .day-row { border-top: 1px solid var(--line-soft); }
.day-row:active { background: var(--bg-sunken); }
@media (hover: hover) { .day-row:hover { background: color-mix(in srgb, var(--bg-sunken) 50%, transparent); } }
.day-date { display: flex; flex-direction: column; align-items: center; line-height: 1.05; padding-top: 1px; }
.day-dow { font-size: .7rem; font-weight: 600; color: var(--text-faint); }
.day-num { font-size: 1.35rem; font-weight: 650; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.day-mon { font-size: .7rem; color: var(--text-faint); }
.day-row.is-today .day-dow { color: var(--accent); }
.day-row.is-today .day-num { color: var(--accent); }
.day-main { min-width: 0; display: flex; flex-direction: column; gap: 4px; padding-top: 2px; }
.day-stop { display: flex; align-items: center; gap: 8px; font-size: .88rem; min-width: 0; }
.day-stop.is-empty { color: var(--text-faint); }
.day-stop-main { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.day-stop-cost { font-size: .76rem; font-variant-numeric: tabular-nums; color: var(--text-dim); white-space: nowrap; }
.day-stop-cost-state { color: var(--text-faint); }
.day-spent { margin-top: 4px; font-size: .78rem; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text); }
.day-spent-label, .day-spent-n { font-weight: 450; color: var(--text-dim); }
.day-spends { margin-top: 14px; }
.day-spends-title { margin: 0; font-size: .95rem; }
.day-spends-total { font-variant-numeric: tabular-nums; }
.day-stop-cost.is-paid .day-stop-cost-state { color: var(--good-ink); }
.day-time { flex: none; width: 40px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-dim); font-size: .82rem; }
.day-more { font-size: .8rem; color: var(--text-faint); padding-left: 48px; }
.day-weather { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.15; font-variant-numeric: tabular-nums; }
.day-weather strong { font-weight: 620; font-size: .92rem; }
.day-weather span { font-size: .78rem; color: var(--text-faint); }

/* ---------------------------------------------------------- budget path - */
.path-summary { margin: 0 0 12px; font-size: .92rem; color: var(--text-dim); }
.path-summary strong { color: var(--text); font-weight: 620; }
.budget-path { position: relative; margin: 0; }
.path-plot { position: relative; height: 170px; margin-right: 58px; touch-action: pan-y; cursor: crosshair; }
.path-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.path-area { fill: var(--accent); opacity: .1; }
.path-line {
  fill: none; stroke: var(--accent); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 1; stroke-dashoffset: 0; animation: path-draw 1.1s var(--ease) both;
}
.path-budget { stroke: var(--ink); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.path-cursor { stroke: var(--text-faint); stroke-width: 1; vector-effect: non-scaling-stroke; }
@keyframes path-draw { from { stroke-dashoffset: 1; } }
.path-overlay { position: absolute; inset: 0; pointer-events: none; }
.path-dot {
  position: absolute; width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 0 2px var(--bg-raised);
}
.path-dot.is-cross { background: var(--bad); }
.path-end-label {
  position: absolute; left: calc(100% + 8px); transform: translateY(-50%);
  font-size: .78rem; font-weight: 650; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.path-budget-label {
  position: absolute; right: 0; transform: translateY(calc(-100% - 3px));
  font-size: .72rem; font-weight: 620; color: var(--text); white-space: nowrap;
  background: color-mix(in srgb, var(--bg-raised) 85%, transparent); padding: 0 3px; border-radius: 3px;
}
.budget-path .dayaxis { margin-right: 58px; }
.viz-tip span { display: block; }
@media (prefers-reduced-motion: reduce) { .path-line, .hotel-card.is-flash { animation: none !important; } }

/* A lone last fact spans the row instead of leaving an empty grey cell. */
.meta-grid > div:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* ======================================================================= */
/*  Journeys                                                                */
/*                                                                          */
/*  Travel reads as travel: a line icon for what carries you, the two ends  */
/*  of the route in bold, and the time it takes - on the plan's day rows,   */
/*  the timeline, and the line under each stay saying how you get there.   */
/* ======================================================================= */

.mode-icon {
  flex: none; width: 16px; height: 16px;
  fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.route-line { display: inline; }
.route-line strong { font-weight: 620; }
.route-arrow { color: var(--text-faint); }
.route-code {
  display: inline-block; margin-right: 7px; padding: 1px 6px; border-radius: 6px;
  background: var(--bg-sunken); color: var(--text-dim);
  font-size: .78em; font-weight: 650; letter-spacing: .02em; vertical-align: 1px;
}
.free-tag {
  display: inline-block; margin-right: 6px; padding: 0 6px; border-radius: 5px;
  background: color-mix(in srgb, var(--good) 12%, transparent); color: var(--good);
  font-size: .72rem; font-weight: 650; vertical-align: 1px;
}

/* Plan day rows: a travel stop leads with its mode icon, in ink. */
.day-stop .mode-icon { color: var(--accent); margin: 0 -1px; }
.day-stop.is-journey .truncate { color: var(--text); }

/* The line under each stay: how you get there. */
.leg-journey {
  display: inline-flex; align-items: center; gap: 7px; margin: 8px 0 0; padding: 5px 11px 5px 9px;
  border-radius: 999px; background: var(--accent-soft); color: var(--accent);
  font-size: .82rem; font-weight: 600; max-width: 100%;
}
.leg-journey span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

/* Timeline: meta pieces separated by a dot, whatever is present. */
.tl-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 0; font-size: .82rem; color: var(--text-dim); margin-top: 3px; }
.tl-meta > .kind-dot { margin-right: 6px; }
.tl-meta > span:not(.kind-dot) + span::before { content: "·"; margin: 0 6px; color: var(--text-faint); }
.tl-mode { display: inline-flex; align-items: center; gap: 5px; font-weight: 600; color: var(--accent); }
.tl-cost { font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }

/* A travel stop in the timeline is a journey card. */
.tl-item.is-journey { border-left: 3px solid var(--accent); }
.tl-item.is-journey .tl-title { font-size: 1.02rem; }
.tl-item.is-free .tl-title { color: var(--text-dim); font-weight: 560; }
/* A stop in a day row may take two lines rather than lose its name. */
.day-stop { align-items: flex-start; }
.day-stop .day-time, .day-stop .mode-icon { margin-top: 1px; }
.day-stop .kind-dot { margin-top: 6px; }
.day-stop .truncate {
  white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* Jump to a town on the Plan: stays in reach under the app bar. */
.town-jump {
  position: sticky; top: 0; z-index: 30;
  display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none;
  margin: 0 calc(-1 * var(--gutter)) 14px; padding: 8px var(--gutter);
  background: var(--bg); border-bottom: 1px solid var(--line-soft);
}
.town-jump::-webkit-scrollbar { display: none; }
.town-chip {
  flex: none; min-height: 40px; padding: 0 14px; border-radius: 99px;
  border: var(--stroke) solid var(--line); background: var(--bg-raised); color: var(--text);
  font: inherit; font-size: .9rem; font-weight: 600; cursor: pointer;
}

/* ------------------------------------------------ Google sign-in ------- */
/* Google's own button colours (light and dark), so it is recognisably
   theirs; the shape matches the app's other buttons. */
.google-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 48px; padding: 0 16px; border-radius: 12px;
  background: #ffffff; color: #1f1f1f; border: 1px solid #747775;
  font: inherit; font-weight: 600; text-decoration: none; cursor: pointer;
  transition: background-color .15s ease, transform .12s var(--ease);
}
.google-btn[hidden] { display: none; }
.google-btn:hover { background: #f7f8f8; }
.google-btn:active { transform: scale(.98); }
.google-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.google-g { width: 20px; height: 20px; flex: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .google-btn { background: #131314; color: #e3e3e3; border-color: #8e918f; }
  :root:not([data-theme="light"]) .google-btn:hover { background: #1b1b1c; }
}
/* The same, when the app asks for dark (Home Screen on iPhone). */
:root[data-theme="dark"] .google-btn { background: #131314; color: #e3e3e3; border-color: #8e918f; }
:root[data-theme="dark"] .google-btn:hover { background: #1b1b1c; }


/* "or" between Google and the email form. */
.gate-or {
  display: flex; align-items: center; gap: 12px; margin: 2px 0;
  font-size: .8rem; color: var(--text-faint);
}
.gate-or[hidden] { display: none; }
.gate-or::before, .gate-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.gate-guest-link { margin-top: 6px; text-align: center; }
.gate-guest-link .linkish { font-size: .86rem; color: var(--accent); }
.tabs-mini[hidden] { display: none; }

/* ----------------------------------------------------- money in / out --- */
/* A bar in parts: paid in full, then deposits (or payments waiting to be
   confirmed), then the rest as the empty track. Same hue, lighter for the
   part that is not settled yet, so it reads as one quantity. */
.track-split { display: flex; }
.track-split .track-fill { flex: none; border-radius: 0; }
.track-split .track-fill:first-child { border-top-left-radius: 3px; border-bottom-left-radius: 3px; }
.track-fill.deposit { background: color-mix(in srgb, var(--good) 45%, transparent); }
.track-fill.pending {
  background: repeating-linear-gradient(135deg,
    color-mix(in srgb, var(--good) 50%, transparent) 0 4px, transparent 4px 7px);
}

.deposit-fields small { display: block; margin-top: 4px; }

/* Payments waiting for an owner: set apart, because they need doing. */
.to-confirm { margin-bottom: 12px; border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); }
.to-confirm .cell-head { background: color-mix(in srgb, var(--warn) 8%, transparent); }
.confirm-row { align-items: center; }
.confirm-actions { display: flex; gap: 6px; flex: none; }

/* Me: pay your share. */
.pay-card { padding: 18px 18px 14px; margin: 14px 0; }
.pay-amount { margin: 2px 0 0; font-size: 2rem; font-weight: 620; letter-spacing: -.03em; line-height: 1.1; }
.pay-sub { margin: 4px 0 0; font-size: .86rem; color: var(--text-dim); }
.pay-note { margin: 10px 0; font-size: .8rem; color: var(--text-faint); }
.pay-warn {
  margin: 12px 0 0; padding: 9px 11px; border-radius: 10px; font-size: .8rem; line-height: 1.4;
  color: var(--warn); background: color-mix(in srgb, var(--warn) 10%, transparent);
}
.copy-list { margin: 14px 0 8px; border-top: 1px solid var(--line-soft); }
.copy-line {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; border-bottom: 1px solid var(--line-soft);
}
.copy-main { flex: 1; min-width: 0; display: grid; gap: 1px; }
.copy-label { font-size: .74rem; font-weight: 550; color: var(--text-faint); }
.copy-value { font-weight: 600; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.copy-hint { margin-top: 2px; font-size: .76rem; color: var(--text-dim); }
.pay-history { margin-top: 12px; }

/* Payment requests: a small heading inside a section, the next deadline,
   and a Pay chip on each row that can be paid. */
.pay-subhead { margin: 14px 4px 6px; font-size: .78rem; font-weight: 600; color: var(--text-dim); }
.pay-card .pay-subhead { margin: 16px 0 6px; }
.pay-next { margin: 12px 0 0; font-size: .86rem; color: var(--text-dim); }
.pay-next strong, .pay-warn strong { color: var(--text); font-weight: 600; }
.pay-warn strong { color: inherit; }
.pay-requests { box-shadow: none; }
.pay-go {
  flex: none; padding: 5px 12px; border-radius: 999px;
  background: var(--accent); color: var(--bg-raised); font-size: .8rem; font-weight: 650;
}

/* iPhone Safari: the Home Screen app is a separate place. */
.ios-tip {
  position: fixed; left: 12px; right: 12px; z-index: 40;
  bottom: calc(var(--tabbar-h, 72px) + env(safe-area-inset-bottom) + 10px);
  display: flex; align-items: center; gap: 10px; padding: 10px 10px 10px 14px;
  border-radius: 14px; background: var(--bg-raised); border: 1px solid var(--line);
  box-shadow: var(--shadow-card); font-size: .82rem; line-height: 1.35; color: var(--text-dim);
}
.ios-tip span { flex: 1; }

/* ------------------------------------------------------------ the tour --- */
/* A spotlight: a clear box over the part being explained, whose huge shadow
   dims everything else - bars included - without touching any stacking. */
.tour-spot {
  position: fixed; z-index: 950; pointer-events: none; border-radius: 14px;
  box-shadow: 0 0 0 3px var(--accent), 0 0 0 9999px rgba(12, 11, 10, .5);
  transition: top .25s var(--ease), left .25s var(--ease), width .25s var(--ease), height .25s var(--ease);
}
.tour-spot.is-empty { box-shadow: 0 0 0 9999px rgba(12, 11, 10, .5); }
.touring .ios-tip { display: none; }
.tour-card {
  position: fixed; left: 12px; right: 12px; z-index: 960; margin: 0 auto; max-width: 440px;
  bottom: calc(var(--tabbar-h) + var(--safe-bottom, 0px) + 14px);
  padding: 16px 16px 14px; border-radius: 18px;
  background: var(--bg-raised); border: 1px solid var(--line); box-shadow: 0 18px 50px rgba(0, 0, 0, .28);
  animation: tour-in .22s var(--ease) both;
}
.tour-card.is-top { bottom: auto; top: calc(64px + var(--safe-top, 0px)); }
.tour-top { display: flex; align-items: center; justify-content: space-between; }
.tour-card.is-waiting .tour-title, .tour-card.is-waiting .tour-text { opacity: .35; transition: opacity .15s; }
.tour-progress { flex: 1; max-width: 160px; height: 4px; border-radius: 2px; background: var(--bg-sunken); overflow: hidden; }
.tour-fill { display: block; height: 100%; border-radius: 2px; background: var(--accent); transition: width .25s var(--ease); }
.tour-skip {
  min-height: 36px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--bg); font: inherit; font-size: .82rem; font-weight: 600; color: var(--text); cursor: pointer;
}
.tour-title { margin: 2px 0 6px; font-size: 1.15rem; font-weight: 650; letter-spacing: -.01em; }
.tour-text { margin: 0 0 14px; font-size: .92rem; line-height: 1.5; color: var(--text-dim); }
.tour-actions { display: flex; gap: 10px; }
.tour-actions button { flex: 1; min-height: 44px; }
.tour-actions button[hidden] { display: none; }
@keyframes tour-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .tour-card { animation: none; } .tour-spot { transition: none; } }

/* Who's coming */
.who-total { margin: 0; font-size: .92rem; color: var(--text-dim); }
.who-total strong { color: var(--text); font-size: 1.05rem; }
.whos-coming .pay-subhead { margin: 10px 2px 4px; }
.who-add { gap: 8px; }
.who-add input { flex: 1; min-width: 0; }
.stepper-sm { display: flex; gap: 6px; flex: none; }
.stepper-sm button { width: 40px; min-height: 40px; border-radius: 10px; border: 1px solid var(--line); background: var(--bg); font: inherit; font-size: 1.1rem; color: var(--text); }
.stepper-sm button:disabled { opacity: .4; }

/* ------------------------------------------------ excluded from a trip -- */
body.is-excluded .tabbar { display: none; }
.excluded-banner {
  max-width: 520px; margin: 24px auto; padding: 22px 20px;
  display: flex; flex-direction: column; gap: 12px;
  background: var(--bg-raised); border: 1px solid color-mix(in srgb, var(--warn) 45%, var(--line));
  border-left: 4px solid var(--warn); border-radius: var(--radius);
}
.excluded-banner .eyebrow { margin: 0; color: var(--warn); }
.excluded-banner .page-title { margin: 0; font-size: 1.7rem; }
.excluded-banner p { margin: 0; line-height: 1.5; }
.badge.warn { background: color-mix(in srgb, var(--warn) 18%, transparent); color: var(--warn); }
.member-card { display: flex; flex-direction: column; gap: 10px; }
.member-head { min-width: 0; }
.member-email { margin: 2px 0 0; overflow-wrap: anywhere; }
.member-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.member-actions select { width: auto; min-width: 110px; margin-right: auto; }

/* Viewing as another role: a chip under the trip dates, which is also the way back. */
.view-as-chip {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 4px;
  padding: 3px 4px 3px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line));
  background: var(--accent-soft); color: var(--text); font: inherit; font-size: .78rem; font-weight: 600;
}
.view-as-back { padding: 2px 8px; border-radius: 999px; background: var(--accent); color: var(--accent-ink); }
.cell.is-current { background: var(--accent-soft); }

/* Food: Tabelog and the food budget. */
.tabelog-card { display: flex; flex-direction: column; gap: 10px; }
.tabelog-card h3, .tabelog-card p { margin: 0; }
.tabelog-open { min-height: 50px; display: flex; align-items: center; justify-content: center; text-decoration: none; }
.tabelog-towns { margin: 18px 0; }
.tabelog-town-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; }
.tabelog-town { min-height: 44px; display: flex; align-items: center; justify-content: center; text-decoration: none; border-radius: 12px; }

/* Before you go */
.checklist { display: flex; flex-direction: column; gap: 4px; }
.checklist-progress { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 2px; }
.checklist-progress-text { font-size: 1.05rem; }
.checklist-bar { height: 8px; border-radius: 99px; background: var(--line-soft); overflow: hidden; }
.checklist-bar span { display: block; height: 100%; background: var(--good); border-radius: inherit; transition: width .25s ease; }
.checklist-note { margin: 4px 0 6px; }
.checklist-items { display: flex; flex-direction: column; gap: 10px; }
.check-item {
  display: grid; grid-template-columns: 44px minmax(0, 1fr); gap: 12px; align-items: start;
  padding: 14px; border: var(--stroke) solid var(--line); border-radius: var(--radius); background: var(--bg-raised);
}
.check-item.done .check-title { color: var(--text-dim); }
.check-tick {
  width: 44px; height: 44px; border-radius: 50%; border: 2px solid var(--line); background: transparent;
  padding: 0; display: grid; place-items: center; cursor: pointer;
}
.check-tick::after { content: ''; width: 12px; height: 20px; border: solid transparent; border-width: 0 3px 3px 0; transform: translateY(-2px) rotate(45deg); }
.check-tick[aria-pressed="true"] { background: var(--good); border-color: var(--good); }
.check-tick[aria-pressed="true"]::after { border-color: var(--ink-on); }
.check-main { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.check-title { margin: 0; font-size: 1rem; line-height: 1.3; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; overflow-wrap: anywhere; }
.check-tag { font-size: .72rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-faint); border: 1px solid var(--line); border-radius: 99px; padding: 1px 8px; }
.check-body { margin: 0; color: var(--text-dim); font-size: .92rem; line-height: 1.45; }
.check-meta { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: .82rem; color: var(--text-faint); }
.check-due.late { color: var(--bad); font-weight: 600; }
.check-link { align-self: flex-start; min-height: 40px; display: inline-flex; align-items: center; text-decoration: none; margin-top: 2px; }

/* No signal: the saved copy is showing. */
.offline-banner {
  padding: 8px calc(var(--gutter) + var(--safe-right)) 8px calc(var(--gutter) + var(--safe-left));
  background: color-mix(in srgb, var(--warn) 14%, var(--bg)); color: var(--text);
  border-bottom: 1px solid var(--line); font-size: .85rem; line-height: 1.35; text-align: center;
}

/* Creating a trip: the towns in order, with the nights in each. */
.new-trip-mode { display: flex; margin-bottom: 4px; }
.new-trip-mode button { flex: 1; }
.field-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }
.town-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.town-row { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto 32px; gap: 8px; align-items: center; }
.town-num { font-weight: 650; color: var(--text-faint); text-align: center; font-variant-numeric: tabular-nums; }
.town-nights { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.town-step { width: 40px; min-height: 44px; border: 0; background: var(--bg-sunken, var(--line-soft)); color: var(--text); font-size: 1.2rem; cursor: pointer; }
.town-nights-label { min-width: 52px; display: flex; flex-direction: column; align-items: center; line-height: 1.05; font-weight: 650; font-variant-numeric: tabular-nums; }
.town-nights-label small { font-size: .68rem; font-weight: 500; color: var(--text-faint); }
.town-remove { width: 32px; height: 32px; border: 0; border-radius: 50%; background: transparent; color: var(--text-faint); font-size: 1.3rem; cursor: pointer; }
.town-add { align-self: flex-start; }
.town-summary { margin: 2px 0 0; line-height: 1.45; }
.new-trip-flights summary { cursor: pointer; font-weight: 600; min-height: 40px; display: flex; align-items: center; }
.flight-fields { border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px 12px; margin: 8px 0 0; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.flight-fields legend { font-weight: 600; padding: 0 4px; }
@media (max-width: 420px) {
  .field-3 { grid-template-columns: 1fr 1fr; }
  .field-3 > :last-child { grid-column: span 2; }
}

.fill-days { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.fill-days h3, .fill-days p { margin: 0; }

.badge.muted-badge { color: var(--text-faint); }

.home-offer { align-items: flex-start; flex-wrap: wrap; }
.home-offer-actions { display: flex; gap: 6px; margin-left: auto; }

/* How to add the trip to the Home Screen: a close-up of each step. */
.hs-guide { display: flex; flex-direction: column; gap: 14px; }
.hs-switch { display: flex; }
.hs-switch button { flex: 1; }
.hs-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 18px; }
.hs-step { display: flex; flex-direction: column; gap: 10px; }
.hs-pic { width: 100%; max-width: 420px; }
.hs-shot { width: 100%; height: auto; display: block; }
.hs-words { display: flex; flex-direction: column; gap: 3px; }
.hs-head { display: flex; align-items: center; gap: 10px; }
.hs-head strong { font-size: 1rem; line-height: 1.3; }
.hs-words p { margin: 0 0 0 34px; color: var(--text-dim); font-size: .9rem; line-height: 1.45; }
.hs-num { flex: none; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent); color: var(--accent-ink); font-size: .78rem; font-weight: 700; font-variant-numeric: tabular-nums; }
/* The drawing: a screen, its bars and rows, and a ring round what to tap. */
.hs-screen { fill: var(--bg); stroke: var(--line); stroke-width: 1; }
.hs-bar { fill: var(--bg-raised); }
.hs-row { fill: var(--bg-raised); stroke: var(--line-soft); stroke-width: 1; }
.hs-row-on { fill: var(--accent-soft); }
.hs-line { fill: var(--line); }
.hs-other { fill: var(--line); }
.hs-icon-line { fill: none; stroke: var(--accent); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.hs-dot { fill: var(--text); }
.hs-ring { fill: none; stroke: var(--accent); stroke-width: 2.5; }
.hs-t { fill: var(--text); font-family: inherit; font-size: 15px; }
.hs-small { font-size: 12.5px; }
.hs-dim { fill: var(--text-dim); }
.hs-strong { font-weight: 650; }
.hs-accent { fill: var(--accent); }
.hs-mid { text-anchor: middle; }
.hs-end { text-anchor: end; }
.hs-app { fill: #111; stroke: var(--line); stroke-width: 1; }
.hs-case { fill: #c8733a; }
.hs-handle { fill: none; stroke: #c8733a; stroke-width: 2; }
.hs-button { fill: var(--accent); }
.hs-on-accent { fill: var(--accent-ink); }


/* Notifications: the phone's question, a sample, and the settings switch. */
.hs-figure { margin: 0; display: flex; flex-direction: column; gap: 6px; }
.hs-figure figcaption { color: var(--text-dim); font-size: .88rem; }
.hs-divider { fill: none; stroke: var(--line); stroke-width: 1; }
.hs-toggle { fill: var(--good); }
.hs-knob { fill: #fff; }
.hs-compact { gap: 10px; }
.hs-compact li { line-height: 1.4; }

/* ------------------------------------------------------------ travel ---- */
/* The button at the right of each bar is a door to the other section, not
   one more tab: set off by a hairline, outlined rather than lit, in plain
   ink with a small swap mark. Only the screen you are on is coloured, so on
   the Travel side there are never two blue things to choose between. */
.tabbar .tab-switch { color: var(--text-dim); }
.tabbar .tab-switch::after {
  content: ""; position: absolute; left: 0; top: 16px; bottom: 16px; width: 1px; background: var(--line);
}
.tab-pill {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  width: 54px; height: 28px; border-radius: 14px;
  background: none; border: 1.5px solid var(--line); color: var(--text);
  transition: background .15s var(--ease), border-color .15s var(--ease);
}
.tabbar .tab-switch .tab-pill svg { width: 20px; height: 20px; }
/* Taller than the other icons: let it overhang so every label sits level. */
.tabbar .tab-switch .tab-pill { margin-block: -2px; }
.tabbar .tab-switch .tab-swap {
  position: absolute; top: -7px; right: -6px; width: 17px; height: 17px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--bg-raised); border: 1px solid var(--line); color: var(--text-dim);
}
.tabbar .tab-switch .tab-swap svg { width: 11px; height: 11px; stroke-width: 2; }
.tabbar .tab-switch.active { color: var(--text-dim); }
.tabbar .tab-switch.active::before { display: none; }
.tabbar .tab-switch:active .tab-pill { transform: scale(.94); background: var(--bg-sunken); }

/* Next up, as a departure board: the one thing to do next, dark in either
   theme, with the kicker in signal amber. */
.hub-next {
  --board: #14171d; --board-ink: #f6f3ec; --board-dim: rgba(246, 243, 236, .66); --board-amber: #f2b650;
  position: relative; display: grid; gap: 4px; margin: 0 0 26px; padding: 18px 18px 16px;
  background:
    repeating-linear-gradient(180deg, rgba(255, 255, 255, .025) 0 1px, transparent 1px 4px),
    linear-gradient(160deg, #1f2430, var(--board));
  color: var(--board-ink); border-radius: 20px; overflow: hidden;
  box-shadow: 0 16px 28px -16px rgba(12, 16, 26, .55), inset 0 0 0 1px rgba(255, 255, 255, .06);
}
.hub-next:empty:not([data-pending]) { min-height: 150px; }
.hub-kicker {
  margin: 0; display: inline-flex; align-items: center; gap: 8px;
  font-size: .7rem; font-weight: 650; letter-spacing: .16em; text-transform: uppercase; color: var(--board-amber, var(--text-faint));
}
.hub-next .hub-kicker::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 25%, transparent);
  animation: board-blink 2.4s ease-in-out infinite;
}
@keyframes board-blink { 50% { opacity: .35; } }
.hub-next-title {
  margin: 6px 0 2px; font-family: var(--font-display); font-size: 2rem; line-height: 1.05;
  text-wrap: balance; overflow-wrap: anywhere;
}
.hub-next-line { margin: 0; color: var(--board-dim); font-variant-numeric: tabular-nums; }
.hub-next .primary.block {
  margin-top: 14px; background: var(--board-ink); color: #14171d; border-color: transparent;
}

/* The route: a line of cities to swipe along. */
.journey { margin: 0 0 26px; }
.journey:empty:not([data-pending]) { display: none; }
.journey .sec-head { margin-top: 0; }
.link-btn {
  margin: 0; padding: 4px 2px; border: 0; background: none; color: var(--accent);
  font: inherit; font-size: .9rem; font-weight: 600; cursor: pointer;
}
/* A text link is small to look at but not to tap: 44px of finger room. */
.link-btn { position: relative; }
.link-btn::after { content: ""; position: absolute; inset: -10px -6px; min-height: 44px; }
.journey-scroll {
  margin: 0 calc(-1 * var(--gutter)); padding: 4px var(--gutter) 10px; overflow-x: auto; cursor: pointer;
  scroll-snap-type: x proximity; scroll-padding-inline: var(--gutter); scrollbar-width: none; -webkit-overflow-scrolling: touch;
  mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent);
}
.journey-scroll::-webkit-scrollbar { display: none; }
.journey-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.journey-list { list-style: none; margin: 0; padding: 0; display: flex; }
.journey-stop {
  position: relative; flex: none; min-width: 108px; padding-right: 18px; display: grid; gap: 6px;
  scroll-snap-align: start;
}
/* The line runs through every node and on to the next stop. */
.journey-stop::before {
  content: ""; position: absolute; left: 6px; right: 0; top: calc(1.1em + 12px); height: 2px;
  background: var(--line);
}
.journey-stop:last-child::before { display: none; }
.journey-when { font-size: .74rem; color: var(--text-faint); font-variant-numeric: tabular-nums; white-space: nowrap; }
.journey-node {
  position: relative; width: 14px; height: 14px; border-radius: 50%;
  background: var(--bg); border: 2px solid var(--text-dim);
}
.journey-city { font-family: var(--font-display); font-size: 1.35rem; line-height: 1.05; white-space: nowrap; }
.journey-nights { font-size: .8rem; color: var(--text-dim); }
.journey-stop.is-past { opacity: .5; }
.journey-stop.is-past .journey-node { background: var(--text-dim); }
.journey-stop.is-here .journey-node {
  background: var(--accent); border-color: var(--accent);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 20%, transparent);
}
.journey-stop.is-here .journey-city { color: var(--accent); }
/* Wide screens have room for the whole route: it wraps onto a second line
   instead of hiding the last cities off the edge. */
@media (min-width: 720px) {
  .journey-scroll { margin: 0; padding: 4px 0 10px; overflow: visible; mask-image: none; }
  .journey-list { flex-wrap: wrap; row-gap: 18px; }
  .journey-stop { min-width: 120px; }
}

/* The sections: calm tiles, a line icon in each section's colour. */
.hub-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 6px 0 26px;
}
@media (min-width: 640px) { .hub-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.hub-tile {
  position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  min-height: 118px; margin: 0; padding: 14px 14px 13px;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: 18px;
  color: var(--text); text-align: left; box-shadow: none; cursor: pointer;
  transition: transform .12s var(--ease), border-color .15s var(--ease), background-color .15s var(--ease);
}
.hub-tile::after {
  content: ""; position: absolute; top: 16px; right: 14px; width: 7px; height: 7px;
  border-top: 1.6px solid var(--text-faint); border-right: 1.6px solid var(--text-faint); transform: rotate(45deg);
}
.hub-tile:active { transform: scale(.97); background: var(--bg-sunken); }
@media (hover: hover) { .hub-tile:hover { border-color: color-mix(in srgb, var(--hub) 45%, var(--line)); } }
.hub-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.hub-icon {
  display: flex; align-items: center; justify-content: flex-start;
  width: 28px; height: 28px; margin-bottom: auto; padding-bottom: 12px; box-sizing: content-box;
  color: var(--hub); background: none;
}
.hub-icon svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.hub-title { font-weight: 650; font-size: 1rem; line-height: 1.2; }
.hub-sub { color: var(--text-dim); font-size: .82rem; line-height: 1.3; overflow-wrap: anywhere; }
.hub-today { --hub: var(--accent); }
.hub-hotels { --hub: var(--k-hotel); }
.hub-flights { --hub: var(--k-travel); }
.hub-checklist { --hub: var(--good); }
.hub-attractions { --hub: var(--k-event); }
.hub-food { --hub: var(--k-food); }
.hub-trains { --hub: var(--k-onsen); }
.hub-people { --hub: var(--k-shop); }
.hub-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--warn); }
.hub-settings { margin-bottom: 8px; }

.bx-plain { margin: 10px 0 16px; font-size: .88rem; line-height: 1.4; color: var(--text-dim); text-wrap: pretty; }
.costs-jump .town-chip { display: inline-flex; align-items: center; gap: 7px; }
.costs-jump .town-chip small { color: var(--text-faint); font-weight: 550; font-variant-numeric: tabular-nums; }
.costs-jump .swatch { width: 9px; height: 9px; border-radius: 50%; }
.costs-key { margin-top: -4px; }

.seg button { white-space: nowrap; }
.legend-head .sec-title { white-space: nowrap; }
.hub-grid + div > .sec-head:first-child { margin-top: 0; }
.hub-todo { margin-bottom: 22px; }
.hub-todo:empty { display: none; }

/* The + in the middle of the bar: a raised disc, the one filled button
   down there, so it reads as "make something" rather than "go somewhere". */
.tabbar-add {
  flex: 1; min-width: 0; height: var(--tabbar-h);
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 3px;
  margin: 0; padding: 0 0 7px; background: none; border: 0; border-radius: 0;
  color: var(--text-dim); font-size: .7rem; font-weight: 600; cursor: pointer; position: relative;
}
.tabbar-add-disc {
  position: absolute; top: -18px; left: 50%; margin-left: -26px;
  display: flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--ink); color: var(--ink-on);
  box-shadow: 0 0 0 4px var(--bg-raised), 0 8px 18px -6px rgba(0, 0, 0, .45);
  transition: transform .12s var(--ease);
}
.tabbar-add-disc svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.tabbar-add:active .tabbar-add-disc { transform: scale(.92); }
.tabbar-add:focus-visible { outline: none; }
.tabbar-add:focus-visible .tabbar-add-disc { outline: 2px solid var(--accent); outline-offset: 4px; }

.add-menu { display: grid; gap: 6px; }
.add-head {
  margin: 10px 2px 2px; font-size: .74rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-faint);
}
.add-menu .add-head:first-child { margin-top: 0; }
.add-note { margin: 0 2px 4px; }
.add-row { gap: 14px; }
.add-icon {
  width: 38px; height: 38px; margin: 0; padding: 0; box-sizing: border-box; border-radius: 11px; flex: none;
  justify-content: center; background: color-mix(in srgb, var(--hub) 13%, transparent);
}
.add-icon svg { width: 22px; height: 22px; }
.hub-stop { --hub: var(--k-sight); }
.hub-extra { --hub: var(--cat-6); }
.hub-mine { --hub: var(--k-shop); }
.hub-invite { --hub: var(--k-onsen); }
.hub-trip { --hub: var(--k-travel); }
.hub-join { --hub: var(--text-dim); }

/* The header is fixed, not sticky. iPhone Safari softens whatever sits at the
   top edge of a scrolling page (so a sticky header's text looked blurred),
   but leaves a fixed bar sharp and tints the status bar to match it. #app
   keeps the header's height free above the page; app.js measures it. */
.appbar { position: fixed; top: 0; left: 0; right: 0; }
#app { padding-top: var(--appbar-h, calc(61px + var(--safe-top))); }

/* ------------------------------------------------------------- paying --- */
.pay-nudge {
  display: flex; align-items: center; gap: 14px; margin: 0 0 14px; padding: 14px 16px;
  background: var(--bg-raised); border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--line));
  border-radius: var(--radius); box-shadow: var(--shadow-card);
}
.pay-nudge.is-overdue { border-color: color-mix(in srgb, var(--bad) 45%, var(--line)); }
.pay-nudge-main { flex: 1; min-width: 0; }
.pay-nudge-amount { margin: 2px 0 0; font-size: 1.5rem; font-weight: 650; letter-spacing: -.02em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.pay-nudge .primary { flex: none; min-width: 84px; }
.pay-card .pay-now { margin-top: 14px; min-height: 50px; font-size: 1.02rem; }
.pay-progress { margin-top: 14px; }
.pay-progress .pay-sub { margin: 0 0 6px; }
.pay-other { display: block; margin: 12px auto 0; color: var(--accent); }
.hub-pay { --hub: var(--good); }
.hub-spend { --hub: var(--warn-strong); }
.hub-split { --hub: var(--accent); }

.pay-sheet .pay-by { display: flex; }
.pay-sheet .pay-by button { flex: 1; }
.pay-steps { list-style: none; margin: 0; padding: 0; counter-reset: pay; display: grid; gap: 2px; }
.pay-step {
  counter-increment: pay; position: relative; padding: 8px 0 10px 40px;
  border-bottom: 1px solid var(--line-soft);
}
.pay-step:last-child { border-bottom: 0; }
.pay-step::before {
  content: counter(pay); position: absolute; left: 0; top: 10px;
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--ink); color: var(--ink-on); font-size: .8rem; font-weight: 700;
}
.pay-step-text { margin: 12px 0 0; line-height: 1.4; }
.pay-step-warn { margin: 4px 0 0; font-size: .82rem; color: var(--warn); line-height: 1.35; }
.pay-step .copy-line { padding: 6px 0; border: 0; }
.copy-btn { min-width: 84px; }
.copy-btn.is-copied { color: var(--good); font-weight: 650; }
.confirm-nudge { margin: 0 0 14px; width: 100%; text-align: left; }

/* ---------------------------------------------------- profile pictures --- */
.avatar {
  position: relative; flex: none; display: inline-grid; place-items: center; overflow: hidden;
  border-radius: 50%; color: #fff; font-weight: 700; letter-spacing: .02em; line-height: 1;
}
.avatar img, .appbar-account img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 50%;
}
.appbar-account { position: relative; overflow: hidden; }
.avatar-preview { display: flex; justify-content: center; padding: 6px 0 2px; }
.avatar-preview .avatar { box-shadow: 0 0 0 4px var(--bg-raised), 0 0 0 5px var(--line); }
.account-photo { position: relative; flex: none; padding: 0; border: 0; background: none; border-radius: 50%; cursor: pointer; }
.account-photo-badge {
  position: absolute; right: -2px; bottom: -2px; width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center; background: var(--accent); color: var(--accent-ink);
  box-shadow: 0 0 0 2px var(--bg-raised); font-size: 15px; font-weight: 700; line-height: 1;
}
.person-row-avatar { margin-right: 2px; }
.member-head-pic { display: flex; align-items: center; gap: 12px; }
.member-head-pic .grow { min-width: 0; }
.who-name { display: flex; align-items: center; gap: 8px; }
.avatar.is-faded { opacity: .45; }

/* ------------------------------------------------- paying for a cost --- */
.cost-row { gap: 10px; }
.cost-open {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px;
  margin: 0; padding: 0; background: none; border: 0; border-radius: 0;
  color: inherit; font: inherit; text-align: left; cursor: pointer;
}
div.cost-open { cursor: default; }
.pay-chip {
  flex: none; min-width: 58px; min-height: 34px; padding: 0 14px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  background: transparent; color: var(--accent);
  border: 1.5px solid color-mix(in srgb, var(--accent) 40%, var(--line));
  font: inherit; font-size: .86rem; font-weight: 650; white-space: nowrap; cursor: pointer;
  transition: background-color .15s var(--ease), transform .12s var(--ease);
}
.pay-chip:active { transform: scale(.95); background: var(--accent-soft); }
.pay-chip.is-part { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.pay-chip.is-paid { background: color-mix(in srgb, var(--good) 14%, transparent); color: var(--good); border-color: transparent; }
.cell.is-paid { background: color-mix(in srgb, var(--good) 8%, var(--bg-raised)); box-shadow: inset 3px 0 0 var(--good); }
.cell.is-paid .cell-value { color: var(--good); }
.cost-pay { display: grid; gap: 10px; }
.cost-pay-deposit label { display: grid; gap: 4px; }
/* Just you / For everyone: two kinds of paid, never one button for both. */
.cost-pay-part { display: grid; gap: 8px; padding: 12px; border: 1px solid var(--line); border-radius: 14px; }
.cost-pay-part .muted { margin: 0; }
.cost-pay-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.cost-pay-head h3 { margin: 0; font-size: .78rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--text-dim); }

/* ------------------------------------------------------- iPhone feel --- */
/* The app sits still: no rubber-band bounce when you drag past an end, no
   sideways drift, no double-tap zoom (pinching to zoom still works). */
html, body { overscroll-behavior: none; overflow-x: clip; }
html { touch-action: manipulation; }

/* Opened from the Home Screen, newer iPhones blur a band just under the
   clock and battery, which caught the trip name. Start the header's text
   below that band. */
@media (display-mode: standalone) {
  .appbar { padding-top: calc(24px + var(--safe-top)); }
}
.update-bar { z-index: 1000; }

/* ---------------------------------------------------------- settings --- */
.settings-head {
  margin: 6px 4px -6px; font-size: .74rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-faint);
}
.account-card {
  width: 100%; margin: 0; padding: 14px; text-align: left; cursor: pointer; color: inherit; font: inherit;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius);
}
.account-card .grow { display: grid; gap: 2px; min-width: 0; }
.account-card-sub { font-size: .82rem; color: var(--text-dim); overflow-wrap: anywhere; }
.account-card-action { flex: none; align-self: center; font-size: .82rem; font-weight: 600; color: var(--accent); }
.account-card:active { background: var(--bg-sunken); }
.account-signout-one { margin-top: 4px; }

/* In the Travel section the bar says so: its lit tab is indigo, not ink. */
body[data-section="travel"] .tabbar .tab.active { color: var(--accent); }
body[data-section="travel"] .tabbar .tab.active::before { background: var(--accent); }
.tabbar-inner[data-section] { animation: bar-in .18s var(--ease); }
@keyframes bar-in { from { opacity: .4; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ------------------------------------------------ a compact top bar --- */
/* One line: the trip's name (tap it for all your trips, hence the ▾) and
   your picture. The dates are in each page's heading instead. */
.appbar { padding-top: calc(6px + var(--safe-top)); padding-bottom: 6px; }
.appbar-sub { display: none; }
.appbar-titles { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; cursor: pointer; min-height: 40px; }
.appbar-titles:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 8px; }
/* A block, so a long trip name ends in an ellipsis before the chevron. */
.appbar-title { position: relative; font-size: 1.06rem; display: block; max-width: 100%; padding-right: 15px; }
.appbar-title::after {
  content: ""; position: absolute; right: 2px; top: 50%; width: 7px; height: 7px; margin-top: -6px;
  border-right: 2px solid var(--text-dim); border-bottom: 2px solid var(--text-dim); transform: rotate(45deg);
}
.appbar-titles.is-trips .appbar-title { padding-right: 0; }
@media (display-mode: standalone) {
  /* Since iOS 26 the system blurs a band about 35pt deep at the top of a
     Home Screen app, whatever the status bar style, and nothing in CSS
     turns it off. So the header's own background fills that band and its
     text starts below it. */
  .appbar { padding-top: calc(30px + var(--safe-top)); }
}
main { padding-top: 10px; }
.page-head { margin: 2px 4px 14px; }
.eyebrow { margin-bottom: 4px; }

/* ------------------------------------------------------------- trips --- */
body[data-section="trips"] .tabbar { display: none; }
body[data-section="trips"] main { padding-bottom: calc(28px + var(--safe-bottom)); }
.trips-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.trips-head .screen-head { flex: 1; min-width: 0; }
.trips-add {
  flex: none; width: 46px; height: 46px; margin-top: 18px; border-radius: 50%;
  display: grid; place-items: center; background: var(--ink); color: var(--ink-on); border: 0;
  font-size: 1.7rem; font-weight: 400; line-height: 1; cursor: pointer;
}
/* ---------------------------------------------- the trip as a pass --- */
/* The trip you are in, drawn as a boarding pass: an indigo top with the
   countdown, a perforated tear, and a paper stub with when, who and the
   route. Japan gets seigaiha, the wave pattern on everything from festival
   happi coats to JR tickets; anywhere else gets a quiet dotted chart. */
.pass {
  --pass-ink: #fffdf8;
  --pass-dim: rgba(255, 253, 248, .72);
  --pass-deep: #1d3d70;
  display: grid; grid-template-columns: minmax(0, 1fr); width: 100%; margin: 4px 0 26px; padding: 0; border: 0; text-align: left;
  color: inherit; font: inherit; cursor: pointer; background: none;
  filter: drop-shadow(0 14px 22px rgba(23, 35, 60, .16)) drop-shadow(0 1px 1px rgba(23, 35, 60, .08));
  transition: transform .18s var(--ease);
  animation: pass-in .5s cubic-bezier(.2, .8, .2, 1) backwards;
}
.pass:active { transform: scale(.985); }
.pass:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 22px; }
@keyframes pass-in { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
.pass-art {
  position: relative; display: grid; gap: 6px; padding: 18px 20px 22px;
  border-radius: 22px 22px 0 0; color: var(--pass-ink); overflow: hidden;
  background:
    radial-gradient(120% 90% at 100% 0%, rgba(255, 255, 255, .16), transparent 55%),
    linear-gradient(180deg, transparent 35%, rgba(8, 18, 38, .45)),
    radial-gradient(rgba(255, 255, 255, .14) 1px, transparent 1.4px) 0 0 / 14px 14px,
    var(--pass-deep);
}
.pass.is-jp .pass-art {
  background:
    radial-gradient(120% 90% at 100% 0%, rgba(255, 255, 255, .14), transparent 55%),
    linear-gradient(100deg, rgba(20, 44, 84, .82) 8%, rgba(20, 44, 84, .35) 60%, rgba(20, 44, 84, .1)),
    linear-gradient(180deg, transparent 30%, rgba(8, 18, 38, .5)),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='24' viewBox='0 0 48 24'%3E%3Cg stroke='rgba%28255%2C255%2C255%2C.16%29' stroke-width='1.3'%3E%3Ccircle cx='24' cy='0' r='24' fill='%231d3d70'/%3E%3Ccircle cx='24' cy='0' r='24' fill='none'/%3E%3Ccircle cx='24' cy='0' r='18' fill='none'/%3E%3Ccircle cx='24' cy='0' r='12' fill='none'/%3E%3Ccircle cx='24' cy='0' r='6' fill='none'/%3E%3Ccircle cx='0' cy='12' r='24' fill='%231d3d70'/%3E%3Ccircle cx='0' cy='12' r='24' fill='none'/%3E%3Ccircle cx='0' cy='12' r='18' fill='none'/%3E%3Ccircle cx='0' cy='12' r='12' fill='none'/%3E%3Ccircle cx='0' cy='12' r='6' fill='none'/%3E%3Ccircle cx='48' cy='12' r='24' fill='%231d3d70'/%3E%3Ccircle cx='48' cy='12' r='24' fill='none'/%3E%3Ccircle cx='48' cy='12' r='18' fill='none'/%3E%3Ccircle cx='48' cy='12' r='12' fill='none'/%3E%3Ccircle cx='48' cy='12' r='6' fill='none'/%3E%3Ccircle cx='24' cy='24' r='24' fill='%231d3d70'/%3E%3Ccircle cx='24' cy='24' r='24' fill='none'/%3E%3Ccircle cx='24' cy='24' r='18' fill='none'/%3E%3Ccircle cx='24' cy='24' r='12' fill='none'/%3E%3Ccircle cx='24' cy='24' r='6' fill='none'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 48px 24px,
    var(--pass-deep);
}
.pass-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.pass-kicker { font-size: .7rem; font-weight: 650; letter-spacing: .14em; text-transform: uppercase; color: var(--pass-dim); }
.pass-flag {
  flex: none; width: 36px; height: 36px; display: grid; place-items: center; border-radius: 50%;
  background: rgba(255, 255, 255, .92); font-size: 1.25rem; line-height: 1;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, .18);
}
.pass-name {
  font-family: var(--font-display); font-size: clamp(1.9rem, 8.4vw, 2.5rem); line-height: 1.02;
  letter-spacing: -.005em; text-wrap: balance; overflow-wrap: anywhere; margin-top: 6px;
}
.pass-count { display: flex; align-items: baseline; gap: 10px; margin-top: 10px; }
.pass-count-num {
  font-size: 3.6rem; font-weight: 250; line-height: .9; letter-spacing: -.045em; font-variant-numeric: tabular-nums;
}
.pass-count-unit { font-size: .95rem; color: var(--pass-dim); }
/* The tear: a dashed rule between two bites out of the sides. */
.pass-tear {
  position: relative; height: 18px; background:
    radial-gradient(circle at 0 50%, transparent 9px, var(--bg-raised) 9.5px) left / 51% 100% no-repeat,
    radial-gradient(circle at 100% 50%, transparent 9px, var(--bg-raised) 9.5px) right / 51% 100% no-repeat;
}
.pass-tear::after {
  content: ""; position: absolute; left: 16px; right: 16px; top: 50%;
  border-top: 1.5px dashed var(--line);
}
.pass-stub {
  display: grid; gap: 14px; padding: 4px 20px 18px; border-radius: 0 0 22px 22px; background: var(--bg-raised);
}
.pass-fields { display: flex; justify-content: space-between; gap: 12px; margin: 0; }
.pass-field { min-width: 0; }
.pass-field:last-child { text-align: right; }
/* Four fields do not fit across the smallest phones: two rows of two. */
@media (max-width: 359px) {
  .pass-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
  .pass-field:nth-child(odd) { text-align: left; }
  .pass-field:nth-child(even) { text-align: right; }
}
.pass-field dt { font-size: .64rem; font-weight: 650; letter-spacing: .12em; text-transform: uppercase; color: var(--text-faint); }
.pass-field dd { margin: 3px 0 0; font-size: .98rem; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.pass-route {
  list-style: none; margin: 0; padding: 12px 0 0; border-top: 1px solid var(--line-soft);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 0;
}
.pass-route:empty { display: none; }
.pass-route li { display: inline-flex; align-items: baseline; gap: 4px; font-size: .9rem; }
.pass-route li:not(:last-child)::after { content: "→"; margin: 0 8px 0 4px; color: var(--text-faint); font-size: .8rem; }
.pass-city { font-weight: 560; }
.pass-nights { font-size: .72rem; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.pass-route li.is-here .pass-city { color: var(--accent); }
.pass-open {
  display: inline-flex; align-items: center; gap: 8px; justify-self: start;
  font-weight: 650; font-size: .95rem; color: var(--accent);
}
.pass-open-arrow { transition: transform .18s var(--ease); }
@media (hover: hover) { .pass:hover .pass-open-arrow { transform: translateX(4px); } }

/* Every other trip, a line each. */
.trips-list {
  display: grid; background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow-card);
}
.trip-row {
  display: flex; align-items: center; gap: 14px; width: 100%; margin: 0; padding: 14px 16px;
  background: none; border: 0; border-radius: 0; text-align: left; color: inherit; font: inherit; cursor: pointer;
}
.trip-row + .trip-row { border-top: 1px solid var(--line-soft); }
.trip-row:active { background: var(--bg-sunken); }
.trip-row.is-excluded { opacity: .6; }
.trip-row-flag {
  flex: none; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
  background: var(--bg-sunken); font-size: 1.3rem; line-height: 1;
}
.trip-row-main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.trip-row-name { font-weight: 620; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trip-row-meta { font-size: .82rem; color: var(--text-dim); }
.trip-ghost .trip-row-name { color: var(--accent); }
.trip-ghost-icon {
  flex: none; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
  border: 1.5px dashed color-mix(in srgb, var(--accent) 50%, var(--line)); color: var(--accent);
}
.trip-ghost-icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* ------------------------------------------------------------- bell --- */
.appbar-bell {
  position: relative; flex: none; width: 40px; height: 40px; margin: 0; padding: 0;
  display: grid; place-items: center; border-radius: 50%; border: 0; background: none;
  color: var(--text); cursor: pointer;
}
.appbar-bell svg { width: 23px; height: 23px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.appbar-bell:active { background: var(--bg-sunken); }
/* The count sits on the icon's shoulder, ringed in the page colour so it
   never swallows the shape underneath. */
.bell-count, .approve-count {
  position: absolute; top: 2px; left: 22px; min-width: 17px; height: 17px; padding: 0 4.5px;
  border-radius: 999px; background: var(--badge-bg); color: #fff; box-shadow: 0 0 0 2.5px var(--bg);
  font-size: .64rem; font-weight: 700; line-height: 17px; text-align: center;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
  animation: badge-in .28s cubic-bezier(.3, 1.4, .5, 1);
}
.approve-count { background: var(--warn-strong); color: var(--warn-ink); }
@keyframes badge-in { from { transform: scale(.4); opacity: 0; } to { transform: none; opacity: 1; } }
.appbar-bell[hidden] { display: none; }
/* The header's round buttons sit close as one cluster, leaving the trip's
   name the room. */
.appbar-bell { width: 38px; }
.appbar-bell + .appbar-bell { margin-left: -6px; }
/* The organiser's payments button: a note with a tick, amber while any wait. */
.appbar-approve.has-waiting { color: var(--warn-strong); }

/* -------------------------------------------------- payments to approve --- */
.approvals { display: grid; gap: 20px; }
.approve-intro { display: grid; gap: 10px; }
.approve-intro p { margin: 0; color: var(--text-dim); line-height: 1.45; }
.approve-left {
  justify-self: start; padding: 4px 10px; border-radius: 999px; font-size: .78rem; font-weight: 650;
  background: var(--warn-soft); color: var(--warn-strong); font-variant-numeric: tabular-nums;
}
.approve-list, .approve-history ul { list-style: none; margin: 0; padding: 0; }
.approve-list { display: grid; gap: 10px; }
.approve-row {
  display: flex; gap: 12px; align-items: flex-start; padding: 14px;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-card); transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.approve-row.is-good { border-color: color-mix(in srgb, var(--good) 45%, var(--line)); background: color-mix(in srgb, var(--good) 5%, var(--bg-raised)); }
.approve-row.is-muted { opacity: .6; }
.approve-main { flex: 1; min-width: 0; display: grid; gap: 4px; }
.approve-line { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.approve-name { font-weight: 650; overflow-wrap: anywhere; }
.approve-amount { flex: none; font-size: 1.15rem; font-weight: 700; letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
.approve-sub { font-size: .84rem; color: var(--text-dim); }
.approve-ref { display: flex; align-items: center; gap: 8px; font-size: .78rem; color: var(--text-faint); }
.approve-ref code {
  padding: 2px 8px; border-radius: 6px; background: var(--bg-sunken); color: var(--text);
  font: 600 .82rem/1.4 ui-monospace, "SF Mono", Menlo, monospace; letter-spacing: .04em;
}
.approve-note { font-size: .84rem; color: var(--text-dim); font-style: italic; }
.approve-actions { display: flex; gap: 8px; margin-top: 8px; }
.approve-actions button { flex: 1; }
.approve-done { font-size: .88rem; font-weight: 650; padding: 6px 0; }
.approve-done.good { color: var(--good); }
.approve-done.muted { color: var(--text-dim); }
.approve-empty { display: grid; justify-items: center; gap: 6px; padding: 18px 8px 6px; text-align: center; }
.approve-empty p { margin: 0; max-width: 30ch; color: var(--text-dim); line-height: 1.45; }
.approve-empty-mark { width: 52px; height: 52px; display: grid; place-items: center; border-radius: 50%; background: var(--good-soft); color: var(--good); margin-bottom: 6px; }
.approve-empty-mark svg { width: 30px; height: 30px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.approve-history .settings-head { margin: 0 0 6px; }
.approve-history li {
  display: grid; grid-template-columns: 1fr auto auto; gap: 12px; align-items: baseline;
  padding: 10px 2px; border-top: 1px solid var(--line-soft); font-size: .9rem;
}
.approve-history li:first-child { border-top: 0; }
.approve-history-when { color: var(--text-faint); font-size: .8rem; }
.approve-history-amount { font-weight: 650; font-variant-numeric: tabular-nums; }
.inbox-row { align-items: flex-start; }
.inbox-dot { flex: none; width: 8px; height: 8px; margin-top: 8px; border-radius: 50%; background: transparent; }
.inbox-row.is-unread .inbox-dot { background: var(--accent); }
.inbox-row.is-unread .cell-title { font-weight: 650; }
.inbox-meta { margin-top: 4px; font-size: .76rem; color: var(--text-faint); }

.inbox-row { padding: 0; gap: 0; }
.inbox-open {
  flex: 1; min-width: 0; display: flex; align-items: flex-start; gap: 12px; margin: 0; padding: 10px 4px 10px 14px;
  background: none; border: 0; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.inbox-open .cell-main { display: grid; gap: 2px; }
.inbox-delete {
  flex: none; width: 44px; align-self: stretch; margin: 0; border: 0; background: none;
  color: var(--text-faint); font-size: 1.4rem; line-height: 1; cursor: pointer;
}
.inbox-delete:active { color: var(--bad); background: var(--bad-soft); }

/* ------------------------------------------------------------ invoice --- */
.invoice {
  border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; display: grid; gap: 8px;
  background: var(--bg-raised);
}
.invoice-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding-bottom: 8px; border-bottom: 1px dashed var(--line); }
.invoice-kicker { margin: 0; font-size: .72rem; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; color: var(--text-faint); }
.invoice-title { margin: 2px 0 0; font-family: var(--font-display); font-size: 1.4rem; line-height: 1.15; overflow-wrap: anywhere; }
.invoice-sub { margin: 2px 0 0; font-size: .84rem; color: var(--text-dim); }
.invoice-row { display: flex; justify-content: space-between; gap: 12px; font-size: .92rem; font-variant-numeric: tabular-nums; }
.invoice-row span:first-child { color: var(--text-dim); }
.invoice-row.is-total { padding-top: 8px; border-top: 1px dashed var(--line); font-size: 1.05rem; font-weight: 650; }
.invoice-row.is-total span:first-child { color: var(--text); }

/* ------------------------------------------------- paid for, on My share --- */
.paid-for .track { margin-top: 8px; }
.paid-for-total .cell-title { font-size: 1.05rem; font-weight: 650; }
.paid-for-row .cell-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.paid-for-row.is-paid { background: color-mix(in srgb, var(--good) 7%, var(--bg-raised)); }

/* ------------------------------------------------------ spending money --- */
/* What you actually spend on the trip, against a pot. During the trip it is
   the first thing on My share, so it gets the page's strongest number. */
.spend-card {
  display: grid; gap: 8px; margin: 0 0 22px; padding: 18px;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}
.spend-card.is-during { border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); }
.spend-kicker {
  margin: 0; font-size: .7rem; font-weight: 650; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint);
}
.spend-big { margin: 0; font-size: 1.05rem; color: var(--text-dim); line-height: 1.2; }
.spend-big span {
  font-size: 2.3rem; font-weight: 700; letter-spacing: -.03em; color: var(--text); font-variant-numeric: tabular-nums;
}
.spend-big.is-over span { color: var(--bad); }
.spend-meter { height: 8px; border-radius: 999px; background: var(--bg-sunken); overflow: hidden; }
.spend-meter span { display: block; height: 100%; border-radius: inherit; background: var(--good); transition: width .5s var(--ease); }
.spend-meter.is-over span { background: var(--bad); }
.spend-sub { margin: 0; font-size: .88rem; color: var(--text-dim); line-height: 1.45; font-variant-numeric: tabular-nums; }
.spend-sub .link-btn { font-size: .88rem; padding: 0; }
.spend-hint { margin: 0; font-size: .84rem; color: var(--text-faint); line-height: 1.45; }
.spend-actions { display: flex; gap: 10px; margin-top: 4px; }
.spend-actions button { flex: 1; }
.spend-kinds { display: grid; gap: 8px; margin-top: 6px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.spend-kinds-bar { display: flex; height: 6px; border-radius: 999px; overflow: hidden; gap: 2px; }
.spend-kinds-bar span { display: block; height: 100%; }
.spend-kinds-key { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: .78rem; color: var(--text-dim); }
.spend-kinds-key li { display: inline-flex; align-items: center; gap: 5px; }
.spend-kinds-key i { width: 8px; height: 8px; border-radius: 50%; }
.spend-kinds-key b { color: var(--text); font-weight: 650; font-variant-numeric: tabular-nums; }
.spend-list { list-style: none; margin: 4px 0 0; padding: 0; }
.spend-row { display: flex; align-items: center; gap: 4px; border-top: 1px solid var(--line-soft); }
/* The whole line opens it for changing; the × deletes. Both thumb-sized. */
.spend-open {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; min-height: 48px; margin: 0; padding: 6px 0;
  background: none; border: 0; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.spend-open:active { background: var(--bg-sunken); }
.spend-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 8px; }
.spend-pace { margin: 0; font-size: .86rem; color: var(--text-dim); line-height: 1.4; }
.spend-pace b { font-weight: 650; color: var(--text); }
.spend-pace.is-above b { color: var(--warn-strong); }
.spend-pace.is-on b, .spend-pace.is-below b { color: var(--good); }
.spend-approx b { color: var(--text); font-weight: 650; }
.spend-approx span { font-size: .8rem; color: var(--text-faint); }
.field-label { font-size: .88rem; font-weight: 600; color: var(--text-dim); }
.danger-link {
  justify-self: start; margin: 4px 0 0; padding: 8px 0; border: 0; background: none;
  color: var(--bad); font: inherit; font-size: .9rem; font-weight: 600; cursor: pointer;
}
.spend-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; }
.spend-what { flex: 1; min-width: 0; display: grid; }
.spend-note { font-size: .92rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.spend-kind { font-size: .74rem; color: var(--text-faint); }
.spend-amount { display: grid; justify-items: end; font-variant-numeric: tabular-nums; }
.spend-amount b { font-size: .92rem; font-weight: 650; }
.spend-amount small { font-size: .72rem; color: var(--text-faint); }
.spend-delete {
  flex: none; width: 44px; height: 44px; margin: 0 -6px 0 0; border: 0; border-radius: 50%; background: none;
  color: var(--text-faint); font-size: 1.2rem; line-height: 1; cursor: pointer;
}
.spend-delete:active { background: var(--bad-soft); color: var(--bad); }
.spend-days { margin-top: 4px; }
.spend-days summary { cursor: pointer; padding: 8px 0; font-size: .86rem; font-weight: 600; color: var(--accent); }
.spend-day-head { display: flex; justify-content: space-between; margin: 10px 0 0; font-size: .82rem; color: var(--text-dim); }
.spend-day-head b { color: var(--text); font-variant-numeric: tabular-nums; }

/* Logging one: the amount big, the money beside it, kinds as chips. */
.spend-form { display: grid; gap: 10px; }
.spend-amount-row { display: flex; align-items: center; gap: 10px; }
.spend-input {
  flex: 1; min-width: 0; font-size: 2rem !important; font-weight: 650; letter-spacing: -.02em;
  padding: 10px 14px !important; font-variant-numeric: tabular-nums;
}
.spend-cur { flex: none; }
.spend-cur-one { flex: none; font-weight: 650; color: var(--text-dim); }
.spend-approx { margin: -4px 0 0; min-height: 1.2em; font-size: .88rem; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.spend-kind-pick { display: flex; flex-wrap: wrap; gap: 8px; }
.spend-kind-pick button {
  display: inline-flex; align-items: center; gap: 7px; margin: 0; padding: 8px 12px; border-radius: 999px;
  border: 1.5px solid var(--line); background: var(--bg-raised); color: var(--text); font: inherit; font-size: .88rem; cursor: pointer;
}
.spend-kind-pick button i { width: 9px; height: 9px; border-radius: 50%; background: var(--kind); }
.spend-kind-pick button.is-on { border-color: var(--kind); background: color-mix(in srgb, var(--kind) 12%, var(--bg-raised)); font-weight: 650; }

/* ---------------------------------------------------------- day pace --- */
/* Packed days warn; travel and rest days say what they are; the rest say nothing. */
.pace-tag {
  justify-self: start; display: inline-block; margin-top: 4px; padding: 2px 8px; border-radius: 999px;
  font-size: .7rem; font-weight: 650; letter-spacing: .02em;
}
.pace-tag.is-rest { background: var(--good-soft); color: var(--good-ink); }
.pace-tag.is-travel { background: var(--accent-soft); color: var(--accent); }
.pace-tag.is-packed { background: var(--warn-soft); color: var(--warn-strong); }
.pace-note {
  margin: 0 0 14px; padding: 12px 14px; border-radius: 14px; font-size: .88rem; line-height: 1.45;
  background: var(--warn-soft); color: var(--text);
  border: 1px solid color-mix(in srgb, var(--warn-strong) 25%, transparent);
}
.pace-note strong { color: var(--warn-strong); }

/* ------------------------------------------------------------- brand --- */
/* Tabi (旅, "journey"): the wordmark in the display serif, with a hanko
   seal - the red stamp that signs a document in Japan, and the one a
   traveller collects at stations and temples along the way. */
:root { --seal: #b3261e; --seal-ink: #fff8f2; }
.brand-word {
  display: inline-flex; align-items: flex-start; gap: 8px;
  font-family: var(--font-display); font-weight: 400; font-size: 3rem; line-height: 1; letter-spacing: -.01em;
}
.brand-seal, .appbar-titles.is-trips .appbar-title::after {
  display: inline-grid; place-items: center; flex: none;
  width: 1.05em; height: 1.05em; margin-top: .12em; border-radius: .16em;
  background: var(--seal); color: var(--seal-ink);
  font-family: "Hiragino Mincho ProN", "Yu Mincho", "Noto Serif JP", "Noto Serif CJK JP", serif;
  font-size: .5em; font-weight: 600; line-height: 1;
  transform: rotate(-5deg); box-shadow: inset 0 0 0 .06em rgba(255, 255, 255, .28);
}
.gate-brand .brand-mark, .gate-brand .gate-logo { display: block; margin: 0 auto; }
.gate-brand .gate-logo[hidden] { display: none; }
.gate-brand h1.brand-word { display: flex; justify-content: center; margin: 12px 0 8px; font-size: 3.2rem; }
.brand-line { margin: 0; font-size: 1.05rem; font-weight: 560; color: var(--text); }
.brand-sub { margin: 4px 0 0; font-size: .86rem; }
/* On the trips page the top bar says Tabi, with its seal. */
.appbar-titles.is-trips .appbar-title {
  display: inline-flex; align-items: center; gap: 7px; padding-right: 0;
  font-family: var(--font-display); font-weight: 400; font-size: 1.55rem; letter-spacing: -.005em;
}
.appbar-titles.is-trips .appbar-title::after {
  content: ""; position: static; display: inline-block; width: .9em; height: .9em; margin: 0;
  border: 0; border-radius: 0; font-size: 1em; box-shadow: none;
  background: url(/img/tabi-seal.svg) center / contain no-repeat;
}

/* ---------------------------------------------------------- money states --- */
/* Paid, booked and estimated: solid, outlined and hatched, so the three read
   apart without colour too. */
.money-states { display: grid; gap: 10px; margin: 14px 0 6px; }
.ms-bar { display: flex; height: 10px; border-radius: 999px; overflow: hidden; background: var(--bg-sunken); gap: 2px; }
.ms-bar span { display: block; height: 100%; min-width: 0; }
.ms-bar .is-paid { background: var(--good); }
.ms-bar .is-committed { background: var(--accent); }
.ms-bar .is-estimated { background: repeating-linear-gradient(135deg, var(--text-faint) 0 3px, transparent 3px 6px); opacity: .7; }
.ms-parts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 0; }
.ms-part { display: grid; gap: 1px; min-width: 0; }
.ms-part dt { display: flex; align-items: center; gap: 6px; font-size: .72rem; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim); }
.ms-part dd { margin: 0; display: grid; gap: 1px; }
.ms-amount { font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.ms-hint { font-size: .72rem; color: var(--text-faint); line-height: 1.3; }
.ms-swatch { width: 9px; height: 9px; border-radius: 3px; flex: none; }
.ms-part.is-paid .ms-swatch { background: var(--good); }
.ms-part.is-committed .ms-swatch { background: var(--accent); }
.ms-part.is-estimated .ms-swatch { background: repeating-linear-gradient(135deg, var(--text-faint) 0 2px, transparent 2px 4px); outline: 1px solid var(--text-faint); }

/* ------------------------------------------------ overview: the money --- */
.hub-money { margin: 0 0 26px; }
.hub-money:empty:not([data-pending]) { display: none; }
/* While the travel hub loads: plain blocks the size of the cards to come. */
.journey[data-pending], .hub-money[data-pending] { border-radius: 20px; background: var(--bg-sunken); }
.hub-money-open {
  display: grid; gap: 4px; width: 100%; margin: 0; padding: 16px 18px 14px; text-align: left; cursor: pointer;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius); color: inherit; font: inherit;
  box-shadow: var(--shadow-card);
}
.hub-money-open:active { background: var(--bg-sunken); }
.hub-money-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.hub-money-head { display: flex; justify-content: space-between; align-items: center; }
.hub-kicker-plain { font-size: .7rem; font-weight: 650; letter-spacing: .14em; text-transform: uppercase; color: var(--text-faint); }
.hub-money-total { font-size: 1.9rem; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.hub-money-total small { font-size: .95rem; font-weight: 500; color: var(--text-dim); letter-spacing: 0; }
.hub-money-status { font-size: .9rem; color: var(--good); font-weight: 600; }
.hub-money-status.is-over { color: var(--bad); }
.hub-money-status.is-mixed { color: var(--warn); }
.hub-money .money-states { margin: 10px 0 0; }
.hub-money-today { margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--line-soft); font-size: .88rem; color: var(--text-dim); }
/* Estimated, booked or paid, beside a stop's cost on the plan. */
.cost-state {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px; vertical-align: 1px;
  font-size: .68rem; font-weight: 650; letter-spacing: .02em;
}
.cost-state.is-estimated { background: var(--bg-sunken); color: var(--text-dim); }
.cost-state.is-booked { background: var(--accent-soft); color: var(--accent); }
.cost-state.is-paid { background: var(--good-soft); color: var(--good-ink); }

/* No budget set: a neutral question, not a verdict. */
.status-pill.is-unset { background: var(--bg-sunken); color: var(--text-dim); }
.status-unset { color: var(--accent); font-weight: 650; }

/* People: the places kept for those still to join, and the organiser's tools. */
.people-open-mark {
  flex: none; width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center;
  border: 1.5px dashed var(--line); color: var(--text-dim); font-size: .8rem; font-weight: 650;
}
.people-manage { display: flex; flex-wrap: wrap; gap: 10px; margin: 4px 0 8px; }
.people-manage button { flex: 1 1 160px; }

/* Recently: what changed on the trip, and who changed it. */
.hub-recent { margin: 0 0 22px; }
.hub-recent:empty { display: none; }
.recent-list { list-style: none; margin: 0; padding: 0; }
.recent-list li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 10px 2px; border-top: 1px solid var(--line-soft); font-size: .9rem;
}
.recent-list li:first-child { border-top: 0; }
.recent-text { min-width: 0; overflow-wrap: anywhere; }
.recent-when { flex: none; font-size: .78rem; color: var(--text-faint); }
.spend-biggest { margin-top: 6px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.cost-you { display: grid; gap: 6px; margin-top: 6px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.cost-you-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: .92rem; }
.cost-you-row small { display: block; font-size: .74rem; color: var(--text-faint); }
.cost-you-row b { font-variant-numeric: tabular-nums; }
.cost-you-row.is-total { padding-top: 6px; border-top: 1px solid var(--line-soft); font-weight: 650; font-size: 1rem; }

/* ------------------------------------------------------- settle up --- */
.settle-card {
  display: grid; gap: 8px; margin: 0 0 22px; padding: 18px;
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}
.settle-card > * { margin-top: 0; margin-bottom: 0; }
.settle-big.is-owed { color: var(--good-ink); }
.settle-big.is-owe { color: var(--text); }
.settle-empty { margin: 4px 0 12px; color: var(--text-dim); font-size: .92rem; }
.settle-sub { margin-top: 14px; }
.settle-list { list-style: none; margin: 6px 0 0; padding: 0; }
.settle-row { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--line-soft); }
.settle-row:first-child { border-top: 0; }
.settle-who { flex: 1 1 auto; min-width: 0; font-size: .92rem; overflow-wrap: anywhere; }
.settle-arrow { color: var(--text-faint); }
.settle-amt { font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap; }
.settle-row.is-yours .settle-who b { color: var(--text); }
.settle-done { margin: 12px 0 0; color: var(--good-ink); font-weight: 600; }
.settle-details { margin-top: 10px; }
.settle-paid { padding: 6px 0; }
.spend-row.is-shared .spend-kind { white-space: normal; }
.spend-who { margin: 0 0 4px; }
.split-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.split-people { display: flex; flex-wrap: wrap; gap: 8px; }
.split-person {
  display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 4px 12px 4px 5px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--bg-raised); color: var(--text-dim);
  font: inherit; font-size: .9rem; cursor: pointer;
}
.split-person.is-on { border-color: var(--accent); background: var(--accent-soft, rgba(42,92,168,.1)); color: var(--text); font-weight: 600; }
.split-person:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.split-avatar { flex: none; }

/* ------------------------------------------------------------ demo --- */
.gate-demo { margin-top: 18px; display: grid; gap: 8px; }
.gate-demo-note { margin: 0; text-align: center; }
.demo-banner {
  position: sticky; top: var(--appbar-h, calc(61px + var(--safe-top))); z-index: 850;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0; padding: 8px calc(var(--gutter) + var(--safe-right)) 8px calc(var(--gutter) + var(--safe-left));
  background: color-mix(in srgb, var(--accent) 10%, var(--bg));
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 25%, var(--line));
  font-size: .84rem; color: var(--text);
}
.demo-tag {
  flex: none; padding: 2px 8px; border-radius: 999px; background: var(--accent); color: var(--accent-ink, #fff);
  font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
.demo-text { flex: 1 1 12em; min-width: 0; color: var(--text-dim); }
.demo-left { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.demo-leave {
  flex: none; min-height: 36px; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--bg-raised); color: var(--text); font: inherit; font-weight: 600; cursor: pointer;
}
.demo-leave:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* -------------------------------------------------------- 3D sign-in --- */
/* A trip in three layers floating in depth over the waves: the boarding
   pass at the back, a receipt in yen, the seal nearest. It drifts, and tilts
   toward a finger or pointer (--tx/--ty, set by app.js). Still when the
   phone asks for less motion. */
.scene3d {
  --tx: 0; --ty: 0;
  position: relative; width: 280px; height: 196px; margin: 0 auto;
  perspective: 900px; perspective-origin: 50% 40%;
  box-shadow: none; border-radius: 0;
}
.scene3d[hidden] { display: none; }
.scene3d-stage {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transform: rotateX(calc(14deg - var(--ty) * 10deg)) rotateY(calc(-18deg + var(--tx) * 14deg));
  transition: transform .5s cubic-bezier(.2, .8, .2, 1);
}
.s3-pass, .s3-receipt, .s3-seal, .s3-shadow { position: absolute; transform-style: preserve-3d; }
.s3-pass {
  left: 0; top: 40px; width: 210px; height: 116px; padding: 12px 14px; border-radius: 14px;
  display: grid; align-content: space-between; color: #fffdf8;
  background:
    linear-gradient(110deg, rgba(255, 255, 255, .18), rgba(255, 255, 255, 0) 45%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='24' viewBox='0 0 48 24'%3E%3Cg stroke='rgba%28255%2C255%2C255%2C.16%29' stroke-width='1.3'%3E%3Ccircle cx='24' cy='0' r='24' fill='%231d3d70'/%3E%3Ccircle cx='24' cy='0' r='24' fill='none'/%3E%3Ccircle cx='24' cy='0' r='18' fill='none'/%3E%3Ccircle cx='24' cy='0' r='12' fill='none'/%3E%3Ccircle cx='24' cy='0' r='6' fill='none'/%3E%3Ccircle cx='0' cy='12' r='24' fill='%231d3d70'/%3E%3Ccircle cx='0' cy='12' r='24' fill='none'/%3E%3Ccircle cx='0' cy='12' r='18' fill='none'/%3E%3Ccircle cx='0' cy='12' r='12' fill='none'/%3E%3Ccircle cx='0' cy='12' r='6' fill='none'/%3E%3Ccircle cx='48' cy='12' r='24' fill='%231d3d70'/%3E%3Ccircle cx='48' cy='12' r='24' fill='none'/%3E%3Ccircle cx='48' cy='12' r='18' fill='none'/%3E%3Ccircle cx='48' cy='12' r='12' fill='none'/%3E%3Ccircle cx='48' cy='12' r='6' fill='none'/%3E%3Ccircle cx='24' cy='24' r='24' fill='%231d3d70'/%3E%3Ccircle cx='24' cy='24' r='24' fill='none'/%3E%3Ccircle cx='24' cy='24' r='18' fill='none'/%3E%3Ccircle cx='24' cy='24' r='12' fill='none'/%3E%3Ccircle cx='24' cy='24' r='6' fill='none'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 36px 18px,
    #1d3d70;
  box-shadow: 0 22px 40px -18px rgba(8, 18, 38, .7), inset 0 0 0 1px rgba(255, 255, 255, .14);
  transform: translateZ(-40px) rotateZ(-6deg);
  animation: s3-float-a 7s ease-in-out infinite;
}
.s3-kicker { font-size: .56rem; letter-spacing: .16em; text-transform: uppercase; opacity: .78; font-weight: 650; }
.s3-route { display: flex; align-items: center; gap: 8px; font-family: var(--font-display); font-size: 1.7rem; line-height: 1; }
.s3-route b { font-weight: 400; }
.s3-route i { flex: 1; height: 1px; background: repeating-linear-gradient(90deg, rgba(255, 255, 255, .7) 0 4px, transparent 4px 8px); position: relative; }
.s3-route i::after { content: "✈"; position: absolute; left: 50%; top: -9px; transform: translateX(-50%); font-size: .8rem; font-style: normal; }
.s3-meta { display: flex; gap: 12px; font-size: .62rem; opacity: .85; font-variant-numeric: tabular-nums; }
.s3-receipt {
  right: -4px; top: 122px; width: 146px; padding: 11px 12px 12px; border-radius: 10px;
  display: grid; gap: 6px; color: #17150f; text-align: left;
  background: #fffefb;
  box-shadow: 0 20px 34px -16px rgba(8, 18, 38, .55), 0 0 0 1px rgba(23, 21, 15, .06);
  transform: translateZ(30px) rotateZ(4deg);
  animation: s3-float-b 6s ease-in-out infinite;
  -webkit-mask: radial-gradient(5px at 8px 100%, transparent 98%, #000) -8px 0 / 16px 100% repeat-x;
          mask: radial-gradient(5px at 8px 100%, transparent 98%, #000) -8px 0 / 16px 100% repeat-x;
  padding-bottom: 16px;
}
.s3-rline { display: flex; justify-content: space-between; gap: 8px; font-size: .74rem; font-variant-numeric: tabular-nums; }
.s3-rline b { font-weight: 700; }
.s3-rline.is-dim { color: #6b655b; font-size: .66rem; }
.s3-rline.is-left b { color: #0e6a3d; }
.s3-rbar { height: 5px; border-radius: 999px; background: #ece8df; overflow: hidden; }
.s3-rbar i { display: block; height: 100%; width: 62%; border-radius: inherit; background: #17804d; }
.s3-seal {
  left: 176px; top: 30px; width: 54px; height: 54px; border-radius: 12px;
  filter: drop-shadow(0 14px 16px rgba(120, 20, 14, .38));
  transform: translateZ(70px) rotateZ(-8deg);
  animation: s3-float-c 5s ease-in-out infinite;
}
.s3-shadow {
  left: 30px; right: 30px; bottom: -14px; height: 22px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(8, 18, 38, .28), transparent);
  transform: translateZ(-80px) rotateX(90deg); filter: blur(2px);
}
@keyframes s3-float-a { 0%, 100% { transform: translateZ(-40px) rotateZ(-6deg) translateY(0); } 50% { transform: translateZ(-40px) rotateZ(-5deg) translateY(-6px); } }
@keyframes s3-float-b { 0%, 100% { transform: translateZ(30px) rotateZ(4deg) translateY(0); } 50% { transform: translateZ(30px) rotateZ(3deg) translateY(-9px); } }
@keyframes s3-float-c { 0%, 100% { transform: translateZ(70px) rotateZ(-8deg) translateY(0); } 50% { transform: translateZ(70px) rotateZ(-4deg) translateY(-12px); } }
.gate-brand .scene3d.brand-mark { display: block; margin: 6px auto 14px; }
@media (prefers-reduced-motion: reduce) {
  .s3-pass, .s3-receipt, .s3-seal { animation: none; }
  .scene3d-stage { transition: none; }
}

/* ------------------------------------------------------------ motion --- */
/* The trip pass, held in the hand: it leans toward the pointer and the light
   follows (trips.js sets --rx/--ry/--mx/--my). On a phone, one sweep of
   light when it arrives. */
.pass { transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform .45s cubic-bezier(.2, .8, .2, 1); }
.pass.is-tilting { transition: transform .08s linear; }
.pass .pass-art::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, -40%), rgba(255, 255, 255, .2), transparent 45%);
  opacity: 0; transition: opacity .3s ease;
}
.pass.is-tilting .pass-art::after { opacity: 1; }
.pass .pass-art::before {
  content: ""; position: absolute; inset: -20% auto -20% -60%; width: 40%; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .22), transparent);
  transform: skewX(-18deg) translateX(0); animation: pass-sheen 1.6s .5s cubic-bezier(.3, .6, .2, 1) both;
}
@keyframes pass-sheen { from { transform: skewX(-18deg) translateX(0); } to { transform: skewX(-18deg) translateX(520%); } }

/* A good outcome is stamped with the seal. */
.toast:not([hidden]) { display: flex; align-items: center; gap: 10px; }
.toast-stamp { flex: none; width: 22px; height: 22px; animation: seal-stamp .42s cubic-bezier(.2, 1.4, .4, 1) both; }

/* The route draws itself, stop by stop. */
.journey-stop::before { transform-origin: left center; animation: grow-x .5s calc(var(--i, 0) * 90ms + 150ms) cubic-bezier(.2, .8, .2, 1) both; }
.journey-node, .journey-city, .journey-when, .journey-nights { animation: tip-in .4s calc(var(--i, 0) * 90ms) ease both; }

@media (prefers-reduced-motion: reduce) {
  .pass { transform: none; transition: none; }
  .pass .pass-art::before, .toast-stamp, .journey-stop::before,
  .journey-node, .journey-city, .journey-when, .journey-nights { animation: none; }
}
.settle-done { display: flex; align-items: center; gap: 10px; }
.settle-stamp { width: 30px; height: 30px; animation: seal-stamp .5s .15s cubic-bezier(.2, 1.4, .4, 1) both; }
@media (prefers-reduced-motion: reduce) { .settle-stamp { animation: none; } }

/* A switch drawn to match the phone's own (Settings → Haptics). */
.switch-look {
  flex: none; position: relative; width: 44px; height: 26px; border-radius: 999px;
  background: var(--bg-sunken); box-shadow: inset 0 0 0 1px var(--line); transition: background .2s ease;
}
.switch-look::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .25); transition: transform .25s cubic-bezier(.3, 1.4, .5, 1);
}
[aria-checked="true"] > .switch-look { background: var(--good); box-shadow: none; }
[aria-checked="true"] > .switch-look::after { transform: translateX(18px); }
@media (prefers-reduced-motion: reduce) { .switch-look, .switch-look::after { transition: none; } }

/* ------------------------------------------------------------- feel --- */
/* Things you press give under the finger and spring back, a little jelly
   on the way out (posts.design's segmented control, Airbnb's tab buttons). */
.seg button, .mini, .pay-chip, .spend-kind-pick button, .split-person, .town-chip, .cell-add,
.tabbar .tab, .tabbar-add .tabbar-add-disc, button.primary, button.secondary, .demo-leave {
  transition: transform .38s cubic-bezier(.3, 1.6, .5, 1), background-color .2s ease, color .2s ease, box-shadow .2s ease;
}
.seg button:active, .mini:active, .pay-chip:active, .spend-kind-pick button:active, .split-person:active,
.town-chip:active, .tabbar .tab:active, .cell-add:active { transform: scale(.92); transition-duration: .08s; }
button.primary:active, button.secondary:active, .demo-leave:active { transform: scale(.97); transition-duration: .08s; }
.tabbar-add .tabbar-add-disc:active { transform: scale(.9); transition-duration: .08s; }

/* The tab you land on answers with a small pop of its icon. */
.tabbar .tab.active svg { animation: tab-pop .42s cubic-bezier(.3, 1.7, .5, 1); }
@keyframes tab-pop { 0% { transform: scale(.82); } 60% { transform: scale(1.12); } 100% { transform: none; } }

/* A deleted spend crumples away like a receipt. */
.spend-row.is-crumpling { animation: crumple .28s cubic-bezier(.5, 0, .75, 0) forwards; transform-origin: 20% 50%; }
@keyframes crumple {
  40% { transform: scale(.94, .82) rotate(-1.5deg); filter: blur(0); }
  100% { transform: scale(.4, .2) rotate(-6deg) translateX(-12%); opacity: 0; filter: blur(1px); }
}

/* Cards ease in as they scroll into view, where the browser does this
   natively; elsewhere (and at rest) they are simply there. */
@supports (animation-timeline: view()) {
  .panel .group, .panel .hero-card, .panel .spend-card, .panel .settle-card, .panel .card, .panel .hub-tile {
    animation: scroll-reveal linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 40%;
  }
}
@keyframes scroll-reveal { from { transform: translateY(22px) scale(.97); } to { transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .seg button, .mini, .pay-chip, .spend-kind-pick button, .split-person, .town-chip, .cell-add,
  .tabbar .tab, .tabbar-add .tabbar-add-disc, button.primary, button.secondary, .demo-leave { transition: none; }
  .seg button:active, .mini:active, .pay-chip:active, .spend-kind-pick button:active, .split-person:active,
  .town-chip:active, .tabbar .tab:active, .cell-add:active, button.primary:active, button.secondary:active,
  .demo-leave:active, .tabbar-add .tabbar-add-disc:active { transform: none; }
  .tabbar .tab.active svg, .spend-row.is-crumpling { animation: none; }
  .panel .group, .panel .hero-card, .panel .spend-card, .panel .settle-card, .panel .card, .panel .hub-tile { animation: none; }
}

/* Following along: the money side is not theirs (the server refuses it too). */
body.is-follower .tabbar-inner[data-section="money"],
body.is-follower .tab-switch,
body.is-follower .tabbar-add { display: none !important; }
.following-note { margin-top: 18px; }

/* The stay's facts are a description list; its "each" line sits under the total. */
dl.meta-grid { margin: 0; }
.meta-grid dd .rate-sub { display: block; }
dl.rate-grid { margin: 0; }
.rate-card dd .rate-sub { display: block; }

/* Trip settings: deleting the trip sits apart from everything else. */
.danger-zone { margin-top: 8px; padding-top: 14px; border-top: 1px solid var(--line); display: grid; gap: 8px; }
.danger-zone p { margin: 0; }
/* Never right against Save: a gap before the sheet's own buttons. */
.modal-form > .danger-zone:last-child { margin-bottom: 18px; }
.danger-zone .settings-head { margin-top: 0; }
/* What happens, before a step that cannot be taken back. */
.consequences { margin: 0; padding-left: 18px; display: grid; gap: 4px; font-size: .92rem; }
/* Choosing one person: the whole row is the target. */
.choice-cell { cursor: pointer; }
.choice-cell input[type="radio"] { flex: none; width: 20px; height: 20px; margin: 0; accent-color: var(--accent); }
.choice-cell:has(input:checked) { background: var(--accent-soft); }
.profile-picture { display: flex; align-items: center; gap: 14px; }

/* Sign-in: a calm confirmation ("check your email"), the forgot-password link. */
.form-note {
  margin: 0; padding: 10px 12px; font-size: .85rem; color: var(--text);
  background: var(--good-soft);
  border: var(--stroke) solid color-mix(in srgb, var(--good) 40%, transparent); border-radius: var(--radius-sm);
}
.gate-forgot { margin: -4px 0 0; text-align: center; }
.gate-help { margin: 0; font-size: .88rem; line-height: 1.45; }
.gate-foot a { color: inherit; margin-left: 6px; }

/* ------------------------------------------------------------- admin ---- */
/* The admin dashboard: the same cards and rows as the rest of the app, with
   a plain status line for admin mode and small, honest charts. */
.maintenance-banner { background: color-mix(in srgb, var(--warn) 14%, var(--bg)); border-bottom-color: color-mix(in srgb, var(--warn) 35%, var(--line)); }
.admin-mode {
  display: flex; align-items: center; gap: 10px; margin: 0 0 12px; padding: 8px 8px 8px 14px;
  border-radius: var(--radius); background: color-mix(in srgb, var(--accent) 9%, var(--bg-raised)); border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--line));
  font-weight: 600; font-size: .92rem;
}
.admin-mode-text { display: grid; gap: 1px; min-width: 0; }
.admin-mode small { font-weight: 500; color: var(--text-dim); font-size: .8rem; }
.admin-mode-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--good); flex: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--good) 25%, transparent); }
.admin-nav { margin: 0 calc(-1 * var(--gutter)) 6px; padding: 0 var(--gutter) 10px; }
.admin-nav .chip { min-height: 44px; padding: 0 16px; }
.admin-body { display: grid; gap: 14px; }
.admin-body > .group, .admin-body > .card { margin: 0; }
.admin-search, .admin-filters { display: grid; gap: 8px; }
.admin-filters { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; }
.admin-check { align-items: center; margin: 0; }
.admin-check input { margin: 0; }
.admin-filters > :first-child:nth-last-child(3) { grid-column: 1 / -1; }
.admin-badges { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; max-width: 45%; }
.admin-meter { height: 8px; border-radius: 999px; background: var(--bg-sunken); overflow: hidden; }
.admin-meter span { display: block; height: 100%; border-radius: inherit; background: var(--accent); min-width: 2px; }
.admin-bars { display: grid; grid-template-columns: repeat(30, minmax(0, 1fr)); gap: 2px; align-items: end; height: 84px; }
.admin-bar { position: relative; height: 100%; display: flex; align-items: flex-end; }
.admin-bar span { position: absolute; bottom: 0; left: 0; right: 0; border-radius: 2px 2px 0 0; min-height: 1px; }
/* Sign-ups drawn narrower, in front of the day's active accounts. */
.admin-bar .is-signup { left: 25%; right: 25%; }
.admin-bar .is-active, .admin-legend .is-active { background: color-mix(in srgb, var(--accent) 35%, transparent); }
.admin-bar .is-signup, .admin-legend .is-signup { background: var(--accent); }
.admin-legend span { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin: 0 4px 0 8px; vertical-align: -1px; }
.admin-legend span:first-child { margin-left: 0; }
.admin-gate, .admin-settings { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; font-size: .9rem; }
.admin-gate li { display: flex; gap: 10px; align-items: baseline; }
.admin-gate small { display: block; color: var(--text-dim); font-size: .8rem; }
.admin-gate-mark { flex: none; width: 1.2em; font-weight: 700; text-align: center; }
.admin-gate .is-ok .admin-gate-mark { color: var(--good); }
.admin-gate .is-bad .admin-gate-mark { color: var(--bad); }
.admin-settings li { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.admin-settings code { font-size: .82rem; overflow-wrap: anywhere; }
.admin-code, .admin-codes {
  display: block; margin: 0; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--bg-sunken);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 1.05rem; letter-spacing: .06em;
  overflow-wrap: anywhere; user-select: all; font-variant-numeric: tabular-nums;
}
.admin-codes { white-space: pre; font-size: .95rem; line-height: 1.7; overflow-x: auto; }
.button-link { display: flex; align-items: center; justify-content: center; min-height: 44px; text-decoration: none; }
.admin-stepup { display: grid; gap: 12px; }
