/* ==========================================================================
   Holidayz — Overview dashboard
   Tokens extracted from Figma node 32:5218 (1440×852)
   ========================================================================== */

/* The wordmark, self-hosted rather than linked from Google Fonts or left to a
   locally-installed face. Every other font in this file is a trial the design
   team has on their machines and everyone else silently falls back from — that
   is survivable for body text and not for a logo, which has to be the same
   mark for every viewer. Latin subset only: it renders one word. */
@font-face {
  font-family: 'Lobster';
  src: url('assets/fonts/lobster-latin.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  /* Show the fallback immediately and swap — the mark arriving a beat late
     beats a blank corner where the logo should be. */
  font-display: swap;
}

:root {
  /* Surfaces */
  --bg-page:        #ecefec;
  --bg-card:        #fefefe;
  --bg-nav:         transparent;
  --bg-button:      #e7e7e7;
  --bg-avatar:      #d6d9d6;
  --bg-avatar-alt:  #ecefec;

  /* Brand greens */
  --green:          #70d55f;
  --green-deep:     #17412d;
  --green-mid:      #25764c;
  --bar-fill:       #256252;
  --bar-track:      #8dc8b2;
  --bar-empty:      #e4ebe7;

  /* Text */
  --text:           #000000;
  --text-muted:     #424542;
  --text-muted-2:   #424242;
  --text-soft:      #515151;
  --text-faint:     #7a7a7a;

  /* Borders */
  --border:         #dbdbdb;
  --border-soft:    #e2e2e2;
  --border-nav:     #c1c1c1;
  --border-avatar:  #c9ccc9;
  --border-avatar-2:#d9dcd9;

  /* Accent pill (Per person) */
  --pill-bg:        #c4dcff;
  --pill-border:    #a1c4ff;
  --pill-text:      #2a3985;

  /* Icon tiles */
  --tile-flight:    #e5bbfd;
  --tile-bed:       #8fb0fe;
  --tile-people:    #b2c2ff;
  --tile-waiting:   #fd8853;
  --tile-approved:  #8ee3e6;
  --tile-traveler:  #ffd97d;   /* added — not from the Figma palette */

  /* Radii */
  --r-card:  24px;
  --r-nav:   16px;
  --r-pill:  100px;
  --r-tile:  6.667px;

  /* Spacing */
  --gap:       10px;
  --tabbar-h:  58px;   /* phone bottom bar; .app pads itself by this */
  --card-pad:  24px;

  /* Type
     The design uses trial fonts. If they're installed locally they'll be picked
     up first; otherwise these fall back to the closest widely-available match.
     Swap in the licensed webfonts here when you have them. */
  /* Exact installed family names — verified against the machine's font list.
     The hyphen matters: "Bagoss Condensed TRIAL" does not resolve and silently
     falls back to Helvetica. */
  --font-display: 'Bagoss Condensed-TRIAL', 'Bagoss Condensed',
                  'Oswald', 'Archivo Narrow', 'Helvetica Neue', system-ui, sans-serif;
  --font-sans:    'Saans-TRIAL', 'Saans',
                  'Inter', system-ui, -apple-system, 'Helvetica Neue', sans-serif;
  /* Cursive last, not sans-serif: if Lobster fails the wordmark should still
     read as a wordmark rather than as another line of UI text. */
  --font-logo:    'Lobster', 'Brush Script MT', cursive;
}

/* --------------------------------------------------------------- reset --- */
*, *::before, *::after { box-sizing: border-box; }
/* The UA's [hidden] rule is display:none at the weakest possible weight, so any
   component that sets its own display silently defeats it. That has now caused
   four separate bugs here (.dayselect, .daymap__empty, .setup__card and the
   hero flight strip), each shipping content that was supposed to be gone.
   Settle it once: hidden means hidden. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.3;
  -webkit-font-smoothing: antialiased;
}

p, h1, h2, h3, h4 { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

button {
  font: inherit;
  color: inherit;
  border: none;
  background: none;
  cursor: pointer;
  /* The UA's default 1px 6px was still applying — asymmetric padding pushes
     the contents of fixed-size icon buttons off-centre (and can overflow
     them). Every button here sets its own padding where it needs one. */
  padding: 0;
}

img { display: block; max-width: 100%; }

/* Icons.
   Figma exports each glyph as a tightly-cropped path, then positions it inside
   a 24px (or 16px) box using inset percentages. Rendering the raw path at full
   box size stretches it — carets end up huge and distorted. These paddings
   reproduce the design's insets exactly, and object-fit keeps the aspect ratio. */
.icon   { width: 24px; height: 24px; flex-shrink: 0; }
.icon-s { width: 16px; height: 16px; flex-shrink: 0; }

img.icon, img.icon-s { box-sizing: border-box; object-fit: contain; }

.i-airplane      { padding: 1.5px; }
.i-caret-down    { padding: 0; }   /* full-frame stroke export — no inset */
.i-caret-right   { padding: 3.75px 6.75px 3.75px 8.25px; }
.i-search        { padding: 2.25px; }
.i-plus          { padding: 3px; }
.i-corners       { padding: 3.75px; }
.i-takeoff       { padding: 4.5px 0.75px 3px; }
.i-landing       { padding: 3px 0 3px 2.25px; }
.i-bed           { padding: 3.75px 0 3.75px 1.5px; }
.i-person        { padding: 1.5px 3.75px; }
.i-copy          { padding: 2px; }
.i-square        { padding: 2px; }
.i-check         { padding: 4px 1.5px 3px 2px; }
.i-caret-right-s { padding: 3px 5px 3px 6px; }
.i-square-24     { padding: 3px; }
.i-check-24      { padding: 6px 2.25px 4.5px 3px; }

/* ============================================================== layout === */
/* 24px gutters on every side. The Figma frame achieved this with 16px of frame
   padding plus 8px on the content column; here the full 24px lives on .app and
   the column gap absorbs the difference, so the dashboard fills the viewport
   instead of being capped and centred. */
.app {
  display: flex;
  gap: 24px;
  min-height: 100vh;
  padding: 24px;
}

/* Added to an iPhone home screen the app runs with no browser chrome, so the
   status bar and the home indicator sit over the page instead of above and
   below it. viewport-fit=cover hands us those strips; these add the padding
   the browser used to. They resolve to 0 everywhere else, so this costs
   nothing on desktop. */
@supports (padding: env(safe-area-inset-top)) {
  .app {
    padding-top: calc(24px + env(safe-area-inset-top));
    padding-bottom: calc(24px + env(safe-area-inset-bottom));
    padding-left: calc(24px + env(safe-area-inset-left));
    padding-right: calc(24px + env(safe-area-inset-right));
  }
  /* The nav sticks to the top of the padded box, not the top of the screen. */
  .nav { top: calc(24px + env(safe-area-inset-top)); }
}

/* ================================================================= nav === */
/* Sticky sidebar: stays put while the main column scrolls. It needs its own
   height (viewport minus the 24px gutters) rather than stretching with the
   content, or there'd be nothing for `top` to stick against. If the nav itself
   ever outgrows the viewport it scrolls internally instead of clipping. */
.nav {
  position: sticky;
  top: 24px;
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex-shrink: 0;
  width: 200px;
  height: calc(100vh - 48px);
  padding-bottom: 10px;
  border-radius: var(--r-nav);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}

.nav__brand {
  padding: 0 10px;
  margin-bottom: 28px;
  height: 38px;
  display: flex;
  align-items: center;
  font-family: var(--font-logo);
  font-size: 32px;
  font-weight: 400;
  /* -0.96px at 32px, kept as a ratio so the mark tracks correctly at any size. */
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--green-deep);
}

/* Nav icons run smaller than the 24px used elsewhere. All six are full-frame
   Phosphor Stroke/Light exports (1.5px stroke), so they need no inset padding.
   The stroke scales with the box, so at 20px it renders slightly under 1.5. */
.nav .icon { width: 20px; height: 20px; }

.nav__list { display: flex; flex-direction: column; gap: 8px; }

.nav__foot {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--border-nav);
}

.nav-tab {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  height: 38px;
  padding: 10px 18px 10px 12px;
  border-radius: 8px;
  font-size: 16px;
  text-align: left;
  transition: background-color .15s ease;
}
.nav-tab:hover              { background: rgba(255, 255, 255, .55); }
.nav-tab--active            { background: var(--bg-card); font-weight: 500; }
/* Only the phone tab bar shows this; there is no room for it in the sidebar
   and no need for it, since the foot it opens is already visible there. */
.nav-tab--more { display: none; }
.nav-tab--active:hover      { background: var(--bg-card); }

/* Count of ideas still waiting for a vote — hidden once there are none. */
.nav-tab__badge {
  margin-left: auto;
  padding: 1px 8px;
  border-radius: var(--r-pill);
  /* Grey, not the brand green — the sidebar background is already a near-white
     grey, so this needs its own fill (--bg-avatar) to read as a distinct chip. */
  background: var(--bg-avatar);
  font-size: 12px;
  font-weight: 600;
  color: var(--green-deep);
}
.nav-tab__badge[hidden] { display: none; }

/* Expandable nav item — chevron parked on the right for a future dropdown. */
.nav-tab--expandable { padding-right: 12px; }
.nav-tab__chevron {
  margin-left: auto;
  opacity: .55;
  transition: transform .15s ease;
}
.nav .nav-tab__chevron { width: 16px; height: 16px; }
.nav-tab--expandable[aria-expanded="true"] .nav-tab__chevron { transform: rotate(180deg); }

.nav-user {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 18px 10px 12px;
  border-radius: 8px;
  text-align: left;
}

.nav-user__name { font-size: 16px; }
.nav-user__role { font-size: 14px; color: var(--text-soft); }

.avatar {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: var(--r-pill);
  background: var(--bg-avatar);
  border: 1px solid var(--border-avatar);
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}
.avatar--stacked {
  background: var(--bg-avatar-alt);
  border-color: var(--border-avatar-2);
}

/* ================================================================ main === */
.main {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

/* ---------------------------------------------------------- topbar ------ */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 0 18px;
}

.topbar__trip-wrap { position: relative; display: inline-flex; }

.topbar__trip {
  display: flex;
  align-items: center;
  gap: 8px;
  /* Padding gives the hover state something to fill; the negative margin pulls
     the label back so it stays flush with the cards below (x = 248). */
  padding: 6px 10px;
  margin-left: -10px;
  border-radius: 8px;
  font-size: 24px;
  font-weight: 500;
  transition: background-color .12s ease;
}
.topbar__trip:hover { background: rgba(255, 255, 255, .6); }
.topbar__trip:focus-visible {
  outline: none;
  background: rgba(255, 255, 255, .6);
  box-shadow: 0 0 0 2px var(--green);
}
.topbar__trip[aria-expanded="true"] { background: rgba(255, 255, 255, .75); }

/* Pencil is a hint, not a heading — stays quiet until the row is hovered. */
#trip-name-btn .icon { width: 18px; height: 18px; opacity: 0; transition: opacity .12s ease; }
#trip-name-btn:hover .icon, #trip-name-btn:focus-visible .icon { opacity: .5; }

.topbar__trip-input {
  width: auto;
  min-width: 160px;
  border: none;
  outline: none;
  background: rgba(255, 255, 255, .6);
  box-shadow: 0 0 0 2px var(--green);
  font-family: inherit;
}
.topbar__trip-input[hidden] { display: none; }

.topbar__actions { display: flex; align-items: center; gap: 8px; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  font-size: 16px;
  font-weight: 500;
  white-space: nowrap;
  transition: background-color .15s ease, border-color .15s ease;
}
.btn:hover { background: rgba(255, 255, 255, .6); }
.btn[hidden] { display: none; }   /* inline-flex would otherwise win */

.btn--search {
  gap: 12px;
  width: 199px;
  background: var(--bg-button);
}
.btn--search:hover { background: #dedede; }

.btn--primary {
  gap: 12px;
  background: var(--green);
  border-color: var(--green);
  color: var(--green-deep);
}
.btn--primary:hover { background: #63c853; border-color: #63c853; }

.btn--icon {
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 10px;
  background: var(--bg-page);
}

/* ---------------------------------------------------------- content ----- */
.content {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  flex: 1;
}
/* `display: flex` beats the hidden attribute, so it needs stating explicitly. */
.content[hidden] { display: none; }

/* Rows use grid rather than flex.
   With flex, `flex-basis: 0` resolves against the CONTENT box, so a card with
   padding is handed its padding on top of its share — the hero (48px padding)
   came out exactly 48px wider than the map (no padding) despite identical flex
   values. Grid's `fr` is padding-aware under border-box, so equal tracks are
   genuinely equal. Proportions below come from the Figma frame. */
/* One shared 4-column grid across every row, so cards line up vertically.
   Spanning tracks (rather than 2fr/1fr/1fr) is what keeps widths consistent
   between rows: a 2fr track subtracts two gaps, while a half-width track in a
   2-column row subtracts only one — which left the budget card 5px narrower
   than the hero directly above it. */
.row { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); align-items: stretch; }
.row > * { min-width: 0; }

/* Top row is two grid rows deep: hero over budget on the left, with the
   schedule card spanning both on the right so it runs their full height. */
.row--top > .hero      { grid-column: 1 / 3; grid-row: 1; }
.row--top > .budget    { grid-column: 1 / 3; grid-row: 2; }
.row--top > .card--day { grid-column: 3 / 5; grid-row: 1 / 3; }

.row--tiles { flex: 1; }                                /* detail: 1/4 each */

.card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--card-pad);
  border-radius: var(--r-card);
  background: var(--bg-card);
  overflow: hidden;
}
/* Set by initDropdown so an in-card menu isn't clipped by the rule above. */
.card.has-open-menu { overflow: visible; }

.card__label {
  font-size: 16px;
  font-weight: 500;
  color: var(--text-muted);
}

.card__title {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}


/* display:inline-flex outranks the UA's [hidden]{display:none}, so restate it. */
.link[hidden] { display: none; }

.link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 0;
  font-size: 16px;
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}
.link--green { color: var(--green-deep); }

/* ------------------------------------------------------------- hero ----- */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-height: 247px;
  padding: var(--card-pad);
  border-radius: var(--r-card);
  background: var(--green);
  overflow: hidden;
}

/* Destination + countdown on the left, illustration on the right — what
   .hero itself used to lay out before the flight strip became a second row. */
.hero__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.hero__copy {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-self: stretch;
  /* Genuinely shrinks below its content's natural width — the flex sibling
     below claims its space first, so copy is never given more room than
     the card actually has, at any viewport width. */
  flex: 1 1 auto;
  min-width: 0;
}

.hero__eyebrow { font-size: 16px; font-weight: 500; color: var(--text-muted); }

.hero__title {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}

.hero__countdown-label {
  font-size: 16px;
  font-weight: 500;
  color: var(--text-muted);
}

.countdown {
  display: flex;
  align-items: center;
  gap: 16px;
  white-space: nowrap;
  font-family: var(--font-display);
  line-height: 1;
}
.countdown__unit  { display: flex; align-items: baseline; gap: 4px; }
.countdown__value { font-size: 32px; font-weight: 500; color: var(--green-deep); }
.countdown__name  { font-size: 20px; font-weight: 500; color: var(--green-mid); }
.countdown__rule  { width: 1px; height: 25px; background: var(--green-deep); opacity: .35; }

/* A real flex sibling of .hero__copy, not an absolutely-positioned overlay.
   The old absolute layout sized the art against the card's full width while
   the text sized itself independently against nothing — neither knew about
   the other, so at common laptop widths (~1440px) the two collided. As a
   flex item, .hero's own layout keeps them apart at every width; flex-shrink
   lets the art give ground to the text instead of the text losing the fight. */
.hero__art {
  flex: 0 1 287px;
  align-self: flex-start;
  min-width: 0;
  max-width: 45%;
  pointer-events: none;
}

/* Flight details, moved in from the standalone flight card. Lives in the
   left (copy) column above the countdown, not the full hero width, so this
   is a compact single line rather than the card's original two-row timeline.
   Departure + arrival sit left, wrapped in flex-wrap so a narrow column drops
   the flight number to its own line instead of clipping; the number carries
   its own departure icon and sits pinned to the right via margin-left:auto. */
/* Grouped in its own chip rather than sitting as loose text. The flight
   number is the title (icon + 14pt), with the departure/arrival points as a
   plain caption underneath — no icons there, so the route doesn't compete
   with the title for attention. */
/* Rules rather than a filled box — separates it from the meta line above
   and the countdown below without adding another solid shape to the hero. */
.hero__flight {
  display: flex;
  flex-wrap: wrap;
  /* baseline (not center) — the icon is a replaced element with no text
     baseline of its own, which broke the flex baseline synthesis for
     .hero__flight-num and threw the two rows off. Isolating the icon out
     of the baseline item (below) lets baseline alignment work correctly. */
  align-items: baseline;
  row-gap: 3px;
  column-gap: 10px;
  margin: 10px 0 4px;
  padding: 10px 0;
  border-top: 1px solid rgba(23, 65, 45, .15);
  border-bottom: 1px solid rgba(23, 65, 45, .15);
}

.hero__flight-num {
  position: relative;
  padding-left: 20px;
  font-size: 13px;
  font-weight: 600;
  color: var(--green-deep);
  white-space: nowrap;
}
/* Out of flow, not just offset: an in-flow icon is still the flex item the
   baseline-synthesis algorithm measures from (a replaced element's synthesized
   baseline is its bottom edge, not the text baseline next to it), which threw
   this row off from .hero__flight-route below. Absolute-positioning it removes
   it from that calculation entirely — "A3 552" itself becomes the only in-flow
   content, so its own text baseline is what the parent aligns on. */
.hero__flight-num .icon-s {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  opacity: .85;
}

.hero__flight-route {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  font-size: 12px;
  color: var(--text-muted);
  white-space: nowrap;
}
.hero__flight-place { font-weight: 500; }
.hero__flight-time { color: var(--text-muted); }
.hero__flight-arrow { opacity: .5; }


/* -------------------------------------------------------------- plan ---- */
/* Ideas and Schedule are segments of one screen (HZ-3.5), sharing .item-card
   which renders differently per state rather than being two components. */
.plan { display: flex; flex-direction: column; gap: 20px; }
.plan[hidden] { display: none; }

.plan__panel { display: flex; flex-direction: column; gap: 16px; }
.plan__panel[hidden] { display: none; }

.segmented__count {
  padding: 1px 7px;
  border-radius: var(--r-pill);
  background: var(--bg-page);
  font-size: 12px;
  font-weight: 600;
  color: var(--green-deep);
}
.segmented__tab.is-active .segmented__count { background: rgba(255, 255, 255, .22); color: #fff; }

/* Underline variant — Plan's segments read as page tabs, not filter pills;
   the pill/button treatment above still serves Documentation's category
   tabs unchanged. */
.segmented.segmented--underline {
  gap: 22px;
  padding: 0;
  border-radius: 0;
  background: transparent;
  /* Bottom-align within .docs__bar (which centers its taller sibling, the
     Sort control) so the tabs sit flush with the row's own bottom edge —
     the marker below is positioned relative to that edge, not the tab's
     vertical center, so it can land exactly on the grey line. */
  align-self: flex-end;
}
.segmented--underline .segmented__tab {
  padding: 8px 1px 12px;
  border-radius: 0;
  background: transparent;
}
.segmented--underline .segmented__tab:hover { background: transparent; color: var(--text); }
.segmented--underline .segmented__tab.is-active,
.segmented--underline .segmented__tab.is-active:hover {
  background: transparent;
  color: var(--green-deep);
  font-weight: 600;
}
/* The line itself, drawn under the active tab only. */
.segmented--underline .segmented__tab {
  position: relative;
}
.segmented--underline .segmented__tab::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  /* Reaches past .docs__bar's 4px padding-bottom + 1px border so the marker
     sits ON the grey line instead of floating above it under the tab. */
  bottom: -5px;
  height: 2px;
  border-radius: 2px;
  background: var(--green-deep);
  opacity: 0;
  transition: opacity .12s ease;
}
.segmented--underline .segmented__tab.is-active::after { opacity: 1; }

/* Count badge stays legible on the white tab bar instead of the dark-pill
   inverse styling the button variant uses. */
.segmented--underline .segmented__tab.is-active .segmented__count {
  background: var(--bg-page);
  color: var(--green-deep);
}
/* Same for category icons (Documentation's tabs) — the button variant
   inverts them to white for a dark pill background; there's no pill here,
   so the invert would make them vanish against the page. */
.segmented--underline .segmented__tab .icon-s { opacity: .75; filter: none; }
.segmented--underline .segmented__tab.is-active .icon-s { opacity: 1; filter: none; }

.plan__tools { display: flex; align-items: center; gap: 8px; }
.plan__select {
  padding: 8px 12px;
  /* Native <select> draws its chevron inside the padding box, so the right
     padding is what sets the gap between the arrow and the field edge. */
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--bg-card);
  font-family: inherit;
  font-size: 14px;
  color: var(--green-deep);
  cursor: pointer;
}
/* Chrome draws the native select arrow at its own fixed offset and ignores
   padding-right, so the chevron is replaced with one we can place exactly. */
select.plan__select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("assets/icons/btn-caret.svg");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 16px 16px;
  padding-right: 30px;          /* keeps the label clear of the chevron */
}

/* Quorum reached — prompted, never an automatic promotion (HZ-2.4). */
.quorum {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--r-card);
  background: var(--bg-card);
}
.quorum[hidden] { display: none; }
.quorum__text { flex: 1; font-size: 14px; color: var(--text-muted); }
.quorum__text b { font-weight: 600; color: var(--green-deep); }
.quorum__cta { background: var(--green); border-color: var(--green); }

.ideagrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--gap);
}
.ideagrid[hidden] { display: none; }
/* Flight cards carry a full route block and a facts grid — 280px columns
   would crush them. */
.ideagrid--wide { grid-template-columns: repeat(auto-fill, minmax(460px, 1fr)); }
/* Accommodation cards put a photo beside the detail, so they need more room
   than a flight card before the body column becomes unusable. */
.ideagrid--stay { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
/* Activity cards carry no photo, just a header, two facts and one action —
   three per row reads cleanly without crowding. */
.ideagrid--act { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 900px) {
  .ideagrid--act { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .ideagrid--act { grid-template-columns: minmax(0, 1fr); }
}

/* ----------------------------------------------- shared item card ------- */
/* One component, four states. Proposed shows votes and no time; Agreed shows
   a time and closed votes; Booked adds a confirmation; Declined is muted. */
.item-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  border-radius: var(--r-card);
  background: var(--bg-card);
}
.item-card__head { display: flex; align-items: flex-start; gap: 12px; }
.item-card__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.item-card__name { font-size: 16px; font-weight: 500; color: var(--green-deep); }
.item-card__meta { font-size: 13px; color: var(--text-muted); }
.item-card__cost { margin-left: auto; font-size: 14px; font-weight: 600; color: var(--green-deep); white-space: nowrap; }

.item-card__foot {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--border-soft);
}
.item-card__by { font-size: 13px; color: var(--text-faint); }

.item-card--declined { opacity: .55; }
.item-card--declined .item-card__name { text-decoration: line-through; }

/* Votes — hidden entirely on a one-traveller trip (principle P·9). */
/* Two-option vote: each row is its own button (click anywhere to cast that
   vote), circle = this traveller's own choice, bar fill = that option's share
   of all votes cast — two different signals, so both render independently. */
.votebars { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }

.votebar {
  display: grid;
  grid-template-columns: 16px 28px 1fr 20px;
  align-items: center;
  gap: 8px;
  padding: 4px 2px;
  cursor: pointer;
  text-align: left;
}

.votebar__radio {
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--border);
  border-radius: 50%;
  transition: border-color .15s ease, background-color .15s ease;
}
.votebar:hover .votebar__radio { border-color: var(--green-mid); }
.votebar.is-selected .votebar__radio {
  border-color: var(--green-deep);
  border-width: 5px;
}

.votebar__label { font-size: 13px; font-weight: 500; color: var(--text-muted-2); }
.votebar.is-selected .votebar__label { color: var(--green-deep); font-weight: 600; }

.votebar__track {
  height: 10px;
  border-radius: var(--r-pill);
  background: var(--bar-empty);
  overflow: hidden;
}
.votebar__fill {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--green);
  transition: width .2s ease;
}

.votebar__count { font-size: 13px; font-weight: 600; text-align: right; color: var(--text-muted); }
.votebar.is-selected .votebar__count { color: var(--green-deep); }

/* Full-width separator ahead of the declined list, in place of the old
   click-to-reveal toggle — declined ideas are always visible now. */
.ideas-divider { padding-top: 20px; margin-top: 4px; border-top: 1px solid var(--border-soft); }
.ideas-divider[hidden] { display: none; }
.ideas-divider__label { font-size: 13px; font-weight: 600; color: var(--text-muted); }

/* ---------------------------------------------------------- money screen */
/* PRD F8. The overview block is the card's own mock (§04) at full size, not
   cropped to card height — bigger meter, room for both conditional lines. */
.money { display: flex; flex-direction: column; gap: 28px; }
.money[hidden] { display: none; }

.money__overview {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 28px;
  border-radius: var(--r-card);
  background: var(--bg-card);
}

.money__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }

.money__figures { font-size: 15px; }
.money__figures .budget__value { font-size: 48px; }
.money__figures .budget__currency { font-size: 28px; }

.meter--lg { height: 20px; }

/* Amber, never red — exceeding a budget is information, not a status
   (HZ-8.2f). Plain text when within budget. */
.money__projection {
  font-size: 15px;
  font-weight: 500;
  color: var(--text-muted-2);
  cursor: pointer;
}
.money__projection:hover { text-decoration: underline; }
.money__projection--over { color: #8a5a12; }

.money__unpriced { font-size: 13px; color: var(--text-faint); }
.money__unpriced[hidden] { display: none; }

/* Expenses take the wide column, Balance the narrow one — .card gives both
   their padding/radius/background, this just splits the row 3:1. */
.money__row { display: grid; grid-template-columns: 1fr 3fr; align-items: start; gap: var(--gap); }

.money__section { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.money__section-head { display: flex; align-items: center; justify-content: space-between; }
.money__section-title { margin: 0; font-family: var(--font-display); font-size: 22px; font-weight: 500; color: var(--green-deep); }

/* Full expense list — same row shape as the Overview card's, just not
   capped at three and never collapsed behind the accordion. */
.money__expenses { display: flex; flex-direction: column; gap: 2px; }
/* +8px over the base .expense row (7px) — scoped here so the Overview card's
   compact accordion list stays as tight as it was. */
.money__expenses .expense { padding: 12px 0; }

.balance-list { display: flex; flex-direction: column; gap: 2px; }
/* Stacked, not inline — the Balance card is the narrow 1fr column, and
   "name · owes you · amount" in one row wraps into a ragged three-liner
   at that width. Avatar sits beside the stack instead of the amount. */
.balance-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 0;
  border-top: 1px solid var(--border-soft);
}
.balance-row:first-child { padding-top: 0; border-top: none; }

.balance-row__label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
}
/* Same size/weight as the Overview tiles' big counts (e.g. "04" on Ideas
   waiting for approval), but --green-mid rather than --green-deep: that's
   the token the Overview card's "Sam owes you 65.40 ₪" already uses for a
   money-positive figure, so the two read as the same kind of number. */
.balance-row__amount {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-mid);
}
.balance-row__currency { margin-left: 4px; font-size: 22px; font-weight: 600; }
.balance-row--settled { padding: 12px 0; color: var(--text-faint); border-top: 1px solid var(--border-soft); font-size: 14px; }

/* ------------------------------------------------------------- settings */
.settings { display: flex; flex-direction: column; gap: var(--gap); }
.settings[hidden] { display: none; }

.set__card { gap: 18px; }
.set__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.set__title { margin: 0; font-family: var(--font-display); font-size: 22px; font-weight: 500; color: var(--green-deep); }
.set__subtitle {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.set__note { font-size: 13px; line-height: 1.45; color: var(--text-faint); }

.set__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px 16px; }

/* One row per traveller: identity, role, and the travelling flag — which is
   deliberately NOT the role (HZ-9.4: access and presence are different facts). */
.traveller-list { display: flex; flex-direction: column; }
.traveller-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 0;
  border-top: 1px solid var(--border-soft);
}
.traveller-row:first-child { border-top: none; padding-top: 0; }
.traveller-row__body { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.traveller-row__name { font-size: 15px; font-weight: 500; color: var(--green-deep); }
.traveller-row__meta { font-size: 13px; color: var(--text-muted); }
.traveller-row__role { flex-shrink: 0; }
.traveller-row .plan__select { padding: 6px 10px; font-size: 13px; }

/* The travelling flag drives quorum and the budget divisor, so it reads as a
   labelled control rather than an anonymous switch. */
.traveller-row__flag { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.traveller-row__flag-label { font-size: 13px; color: var(--text-muted); }

.set__pending[hidden] { display: none; }
.pending-row__state {
  flex-shrink: 0;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: #fdf0dc;
  font-size: 12px;
  font-weight: 600;
  color: #8a5a12;
}

.switch-list { display: flex; flex-direction: column; }
.switch-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 0;
  border-top: 1px solid var(--border-soft);
}
.switch-row:first-child { border-top: none; padding-top: 0; }
.switch-row__body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.switch-row__name { font-size: 15px; font-weight: 500; color: var(--green-deep); }
.switch-row__hint { font-size: 13px; line-height: 1.4; color: var(--text-muted); }

/* Switch — brand green when on, neutral when off. */
.switch {
  flex-shrink: 0;
  position: relative;
  width: 44px;
  height: 26px;
  padding: 0;
  border: none;
  border-radius: var(--r-pill);
  background: var(--bg-avatar);
  cursor: pointer;
  transition: background-color .15s ease;
}
.switch__dot {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fefefe;
  transition: transform .15s ease;
}
.switch[aria-checked="true"] { background: var(--green); }
.switch[aria-checked="true"] .switch__dot { transform: translateX(18px); }
.switch:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(112, 213, 95, .45); }

.set__quiet { display: flex; flex-direction: column; gap: 12px; }
.set__quiet-times { display: flex; gap: 12px; padding-left: 0; }
.set__quiet-times[hidden] { display: none; }

.invitedlg__body { display: flex; flex-direction: column; gap: 14px; margin: 4px 0 20px; text-align: left; }
.invitedlg__link { display: flex; gap: 8px; }
.invitedlg__link .plan__select { flex: 1; min-width: 0; }

/* -------------------------------------------------------------- profile */
.profile__identity { display: flex; align-items: center; gap: 14px; }
.profile__identity-body { flex: 1; min-width: 0; }
.profile__avatar { width: 56px; height: 56px; font-size: 22px; }
.profile__name { margin: 0; font-size: 17px; font-weight: 600; color: var(--green-deep); }
.profile__email { margin: 2px 0 0; font-size: 14px; color: var(--text-muted); }

.profile__account-actions { display: flex; gap: 8px; }

/* Counts read live from IDEAS / EXPENSES / the checklist markup, so voting in
   Plan moves the number here rather than leaving a stale figure behind. */
.profile__stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--gap); }
.profile__stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 16px;
  border-radius: 12px;
  background: var(--bg-page);
}
.profile__stat-value {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}
.profile__stat-label { font-size: 13px; color: var(--text-muted); }

.profile__split { display: grid; grid-template-columns: 1fr 2fr; gap: var(--gap); align-items: start; }
.profile__block { display: flex; flex-direction: column; }
.profile__owed {
  margin: 0;
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-mid);
}

.profile__tasks { display: flex; flex-direction: column; }
.profile__task {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-top: 1px solid var(--border-soft);
  font-size: 14px;
  color: var(--text-muted-2);
}
.profile__task:first-child { border-top: none; padding-top: 0; }
.profile__task--none { color: var(--text-faint); }

/* The chip is a nav destination, so it gets the same active treatment. */
.nav-user--active { background: var(--bg-card); border-radius: var(--r-nav); }

/* --------------------------------------------------- plan · accommodation */
.st-card { flex-direction: column; gap: 0; padding: 0; overflow: hidden; }

.st__media { position: relative; width: 100%; height: 170px; flex: none; padding: 8px; }
.st__photo { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 16px; }
/* CC BY requires attribution, and it also states plainly that this is the
   area rather than the property itself. */
.st__credit {
  position: absolute;
  left: 8px; right: 8px; bottom: 8px;
  padding: 4px 8px;
  border-radius: 6px;
  background: rgba(23, 65, 45, .72);
  font-size: 10px;
  line-height: 1.3;
  color: #fff;
}

.st__body { display: flex; flex-direction: column; gap: 14px; flex: 1; min-width: 0; padding: 20px; }
.st__body .fl__facts { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }

.st__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.st__name { margin: 0; font-size: 17px; font-weight: 600; color: var(--green-deep); }
.st__stars { margin-left: 4px; font-size: 12px; color: #d8a72c; letter-spacing: 1px; }
.st__room { margin: 3px 0 0; font-size: 13px; color: var(--text-muted); }
.st__nights {
  flex-shrink: 0;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--bg-page);
  font-size: 12px;
  font-weight: 600;
  color: var(--green-deep);
}

.st__dates { display: flex; align-items: center; gap: 14px; }
.st__date { display: flex; flex-direction: column; gap: 1px; }
.st__date-label { font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint); }
.st__date-value { font-size: 15px; font-weight: 600; color: var(--green-deep); }
.st__date-time { font-size: 12px; color: var(--text-muted); }
.st__date-arrow { color: var(--text-faint); }

.st__address {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 8px 8px 12px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
}
.st__address-text { font-size: 13px; color: var(--text-muted-2); min-width: 0; }
.st__address-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.stay__act.is-copied { background: var(--green); }

.st__cancel { font-size: 13px; font-weight: 500; color: var(--green-mid); }

.st__amenities { display: flex; flex-wrap: wrap; gap: 6px; }
.st__amenity {
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: var(--bg-page);
  font-size: 12px;
  color: var(--text-muted-2);
}

.st__link { align-self: flex-start; gap: 6px; text-decoration: none; }
.st__link .icon-s { opacity: .7; }

/* -------------------------------------------------------- plan · flights */
.fl-card { display: flex; flex-direction: column; gap: 18px; }

.fl__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.fl__number {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}
.fl__number-icon { width: 20px; height: 20px; opacity: .85; }
.fl__airline { margin: 4px 0 0; font-size: 13px; color: var(--text-muted); }

.fl__pill {
  flex-shrink: 0;
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: var(--green);
  font-size: 12px;
  font-weight: 600;
  color: var(--green-deep);
}
.fl__pill--off { background: var(--bg-page); color: var(--text-faint); }

/* Departure and arrival share the row; the middle column carries duration
   and stops on a rule, the way a ticket prints it. */
.fl__route { display: grid; grid-template-columns: 1fr auto 1fr; gap: 16px; align-items: center; }
.fl__end { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.fl__end:last-child { text-align: right; }
.fl__end-label { font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint); }
.fl__iata { font-family: var(--font-display); font-size: 30px; font-weight: 500; line-height: 1.05; color: var(--green-deep); }
.fl__city { font-size: 13px; color: var(--text-muted); }
.fl__time { margin-top: 4px; font-size: 15px; font-weight: 600; color: var(--green-deep); }
.fl__date { font-size: 12px; color: var(--text-faint); }

.fl__mid { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 120px; }
.fl__line { width: 100%; height: 1px; background: var(--border-soft); }
.fl__duration { font-size: 13px; font-weight: 600; color: var(--green-deep); }
.fl__stops { font-size: 12px; color: var(--text-muted); }

.fl__tz {
  padding: 8px 12px;
  border-radius: 10px;
  background: #eef2fb;
  font-size: 13px;
  font-weight: 500;
  color: #3c5a9a;
}

.fl__facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 14px 16px; margin: 0; }
.fl__fact dt { font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint); }
.fl__fact dd {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 3px 0 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--green-deep);
}
.fl__copy { display: grid; place-items: center; padding: 3px; border-radius: 6px; cursor: pointer; opacity: .6; }
.fl__copy:hover { background: var(--bg-page); opacity: 1; }
.fl__copy.is-copied { background: var(--green); opacity: 1; }

/* Live status. The "off" variant states plainly that nothing is connected
   rather than showing empty fields that look like a loading failure. */
.fl__status { padding-top: 16px; border-top: 1px solid var(--border-soft); }
.fl__status--off { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-faint); }
.fl__status-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--bg-avatar); }

.fl__stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 14px; }
.fl__stat { display: flex; flex-direction: column; gap: 2px; }
.fl__stat-label { font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--text-faint); }
.fl__stat-value { font-size: 16px; font-weight: 600; color: var(--green-deep); }
.fl__updated { margin: 12px 0 0; font-size: 12px; color: var(--text-faint); }

/* ----------------------------------------------------- plan · checklist */
.checklist__progress-line { font-size: 14px; color: var(--text-muted); }

.checklists { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); align-items: start; }

.checklist-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 24px;
  border-radius: var(--r-card);
  background: var(--bg-card);
}
.checklist-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.checklist-card__title { margin: 0; font-family: var(--font-display); font-size: 22px; font-weight: 500; color: var(--green-deep); }
.checklist-card__count { font-size: 13px; color: var(--text-faint); }

/* A real row rather than the card's compact label — needs room for the
   checkbox, an assignee control and a per-row menu. */
.check-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-top: 1px solid var(--border-soft);
}
.check-row:first-child { border-top: none; }
.check-row__box {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--border);
  border-radius: 6px;
  background: var(--bg-card);
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}
.check-row__box:hover { border-color: var(--green-mid); }
/* Inline SVG rather than an <img>: the source check.svg is a 12.5x9 filled
   path with preserveAspectRatio="none", so it distorted in a square box, and
   an <img> can't take a colour from CSS. currentColor lets the tick use the
   brand green token directly instead of a brightness/invert filter. */
.check-row__box svg { width: 14px; height: 14px; opacity: 0; }
.check-row[data-done="true"] .check-row__box {
  background: var(--green-deep);
  border-color: var(--green-deep);
  color: var(--green);          /* the tick itself — main CTA green on the dark box */
}
.check-row[data-done="true"] .check-row__box svg { opacity: 1; }

.check-row__text { flex: 1; min-width: 0; font-size: 15px; color: var(--text-muted-2); }
.check-row[data-done="true"] .check-row__text { color: var(--text-faint); text-decoration: line-through; }

.check-row__due {
  flex-shrink: 0;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: #fdf0dc;
  font-size: 12px;
  font-weight: 600;
  color: #8a5a12;
}
.check-row[data-done="true"] .check-row__due { background: var(--bg-page); color: var(--text-faint); }

.check-row__who { flex-shrink: 0; }
.check-row__who select {
  padding: 4px 8px;
  border: 1px solid var(--border-soft);
  border-radius: var(--r-pill);
  background: var(--bg-card);
  font-family: inherit;
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
}

.check-add { display: flex; gap: 8px; margin-top: 12px; }
.check-add input {
  flex: 1;
  min-width: 0;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-pill);
  background: var(--bg-card);
  font-family: inherit;
  font-size: 14px;
}
.check-add input:focus-visible { outline: none; border-color: var(--green); }

.check-row__del {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s ease, background-color .12s ease;
}
.check-row:hover .check-row__del, .check-row__del:focus-visible { opacity: .6; }
.check-row__del:hover { background: var(--bg-page); opacity: 1; }
.check-row__del img { width: 14px; height: 14px; }

/* ------------------------------------------------- schedule segment ----- */
/* Day picker and the Day/Week/Month toggle share one row; the toggle stays
   put when Week/Month hides the day-only controls beside it. */
.dayselect__row { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 8px; }
/* margin-left:auto rather than justify-content:space-between — the day
   picker hides in Week/Month, and space-between only pushes apart two
   visible children; with one it collapses left. */
.rangetoggle { margin-left: auto; }

.dayselect { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
/* display:flex outranks the UA's [hidden]{display:none}, so restate it —
   without this the day view stays on screen underneath week/month. */
.dayselect[hidden] { display: none; }

.dayselect__btn {
  gap: 10px;
  padding: 9px 12px 9px 16px;
  font-family: var(--font-display);
  font-size: 16px;
  background: var(--bg-card);
}
.dayselect__btn:hover { border-color: var(--green); background: var(--bg-card); }

/* A 12-day trip overflows any chip rail, and a longer one hides its own tail;
   the menu scrolls instead. max-height is ~6 rows so it never runs off-screen. */
.dayselect__menu {
  max-height: 288px;
  overflow-y: auto;
  overscroll-behavior: contain;
  min-width: 260px;
}
.dayopt { gap: 10px; }
.dayopt__n { flex: none; min-width: 46px; font-size: 12px; font-weight: 600; color: var(--text-muted); }
.dayopt__d { flex: 1; font-family: var(--font-display); font-size: 15px; color: var(--green-deep); }
.dayopt[aria-checked="true"] .dayopt__n { color: var(--green-mid); }
.dayopt__warn { flex: none; color: #d08b2c; font-size: 12px; }

.dayfeas { font-size: 14px; color: var(--text-muted); }

/* --------------------------------------------------- schedule + map ----- */
.schedsplit {
  margin-top: 16px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(332px, 432px);
  gap: 24px;
  align-items: start;
}
.schedsplit[hidden] { display: none; }
.schedsplit__main { min-width: 0; }

/* Sticky so the map stays put while a long day scrolls past it. */
.daymap {
  position: sticky;
  top: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* Height is set by sizeDayMap() against the live viewport so the frame ends
     24px above the fold instead of running past it. This is the fallback for
     the first paint. */
  height: calc(100vh - 132px);
  min-height: 320px;
}
.daymap__frame {
  position: relative;
  flex: 1;
  min-height: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--bg-page);
  overflow: hidden;
}
.daymap__tiles { position: absolute; inset: 0; }
.daymap__tiles img { position: absolute; width: 256px; height: 256px; }
.daymap__pins { position: absolute; inset: 0; }

.daymap__credit {
  position: absolute;
  right: 6px;
  bottom: 5px;
  z-index: 3;
  padding: 2px 6px;
  border-radius: 5px;
  background: rgba(255, 255, 255, .78);
  font-size: 10px;
  color: var(--text-muted);
  pointer-events: none;
}
.daymap__empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 24px;
  text-align: center;
  font-size: 14px;
  color: var(--text-muted);
}
.daymap__empty[hidden] { display: none; }
/* Zoom nudges on top of the automatic fit. */
.daymap__zoom {
  position: absolute;
  right: 10px;
  top: 10px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  border-radius: 10px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(23, 65, 45, .18);
}
.daymap__zoom button {
  width: 30px;
  height: 30px;
  background: rgba(255, 255, 255, .95);
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
  color: var(--green-deep);
  cursor: pointer;
}
.daymap__zoom button + button { border-top: 1px solid var(--border-soft); }
.daymap__zoom button:hover { background: #fff; }

/* A stop that falls outside the framed cluster, parked on the edge it lies
   past with the real distance to it. */
.daystray {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px 3px 4px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border-soft);
  background: rgba(255, 255, 255, .95);
  box-shadow: 0 2px 6px rgba(23, 65, 45, .2);
  cursor: pointer;
  transform: translate(-50%, -50%);
  white-space: nowrap;
}
.daystray__arrow { font-size: 9px; color: var(--green-mid); line-height: 1; }
.daystray__n {
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--green-deep);
  font-size: 10px;
  font-weight: 600;
  color: #fff;
}
.daystray__km { font-size: 11px; font-weight: 500; color: var(--text-muted-2); }
.daystray.is-linked { border-color: var(--green); }
.daystray.is-linked .daystray__n { background: var(--green); color: var(--green-deep); }

.daymap__note { font-size: 12px; color: var(--text-muted); }
.daymap__note[hidden] { display: none; }

/* Pins are anchored at their coordinate, so the transform pulls the marker's
   point (not its centre) onto the spot. */
.daypin {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  transform: translate(-14px, -14px);
  cursor: pointer;
}
.daypin__n {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 50%;
  border: 2px solid #fff;
  background: var(--green-deep);
  box-shadow: 0 2px 6px rgba(23, 65, 45, .35);
  font-size: 13px;
  font-weight: 600;
  color: #fff;
}
.daypin__label {
  max-width: 132px;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .94);
  box-shadow: 0 1px 4px rgba(23, 65, 45, .18);
  font-size: 12px;
  font-weight: 500;
  color: var(--green-deep);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transition: opacity .12s ease;
}
.daypin.is-linked { z-index: 4; }
.daypin.is-linked .daypin__n { background: var(--green); color: var(--green-deep); }
.daypin.is-linked .daypin__label { opacity: 1; }

/* Waypoint rail — numbered stops down the left, joined by a dotted line.
   The digit here is the digit on the map pin. */
/* Compound selectors: these rules sit above .tl-row/.tl-travel in this file,
   so at equal specificity the 2-column base would win and wrap the card onto
   a second grid row. */
.tl-row.tl-row--rail,
.tl-travel.tl-travel--rail { grid-template-columns: 64px 28px minmax(0, 1fr); }

.tl-rail { position: relative; align-self: stretch; display: flex; align-items: center; justify-content: center; }
.tl-rail__dot {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: 50%;
  border: 2px solid var(--bg-page);
  background: var(--green-deep);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  color: #fff;
  transition: background-color .12s ease, color .12s ease;
}
/* A stop the map can't place gets a marker that doesn't claim a number. */
.tl-rail__dot--off,
.tl-rail__dot--none {
  width: 14px;
  height: 14px;
  background: var(--bg-card);
  border: 2px solid var(--border);
  color: var(--text-faint);
  font-size: 10px;
}

/* Runs from under the dot into the 8px list gap, so the dashes read as one
   continuous line down the column. */
.tl-rail::after {
  content: '';
  position: absolute;
  left: 50%;
  top: calc(50% + 17px);
  bottom: -8px;
  border-left: 2px dotted var(--border);
  transform: translateX(-50%);
}
.tl-rail--seg::after { top: -8px; bottom: -8px; }
.timeline-list > .tl-row--rail:last-child .tl-rail::after { display: none; }
/* Anytime items have no order between them, so nothing to connect. */
.anytime .tl-rail::after { display: none; }

.tl-travel--rail .tl-travel__body { padding-left: 4px; }
/* Derived from coordinates rather than routed — visibly less certain. */
.tl-travel--est .tl-travel__body { color: var(--text-faint); cursor: help; }

.tl-row.is-linked .item-card { box-shadow: 0 0 0 2px var(--green); }
.tl-row.is-linked .tl-rail__dot { background: var(--green); color: var(--green-deep); }

/* Drag handle — sits in the gutter left of the rail, only while hovering the
   row it belongs to, so a resting list stays quiet. */
.tl-drag {
  position: absolute;
  left: -20px;
  top: 50%;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 3px;
  border-radius: 5px;
  opacity: 0;
  cursor: grab;
  transform: translateY(-50%);
  transition: opacity .12s ease, background-color .12s ease;
}
.tl-drag span { display: block; width: 10px; height: 2px; border-radius: 1px; background: var(--text-faint); }
.tl-row:hover .tl-drag,
.tl-drag:focus-visible { opacity: 1; }
.tl-drag:hover { background: var(--bg-page); }
.tl-row.is-dragging { opacity: .45; }
.tl-row.is-dragging .tl-drag { cursor: grabbing; }

/* Band header inside the timeline. Spans the full row so the rule runs the
   width of the list rather than starting at the card column. */
.tl-band {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0 2px;
}
.tl-band:first-child { margin-top: 0; }
.tl-band__label {
  flex: none;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.tl-band__rule { flex: 1; height: 1px; background: var(--border-soft); }
.tl-band__count {
  flex: none;
  min-width: 20px;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  background: var(--bg-card);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
  color: var(--text-muted);
}
.tl-band[data-band="anytime"] .tl-band__label { color: var(--text-faint); }

/* A timed stop takes its band from its clock, so it can't be dropped into
   another one — say so rather than just refusing silently. */
.tl-row.is-nodrop .item-card { box-shadow: 0 0 0 2px #e6c9c9; }
.tl-row.is-nodrop { cursor: not-allowed; }

/* Where the row will land. */
.tl-row.is-dropbefore .item-card { box-shadow: 0 -3px 0 -1px var(--green); }
.tl-row.is-dropafter .item-card { box-shadow: 0 3px 0 -1px var(--green); }

/* Add a stop, in the timeline's own grid so it lines up with the cards. */
.tl-add-row { display: grid; grid-template-columns: 64px 28px minmax(0, 1fr); gap: 12px; }
.tl-add {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  border: 1px dashed var(--border);
  border-radius: var(--r-card);
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
  transition: border-color .12s ease, color .12s ease, background-color .12s ease;
}
.tl-add:hover { border-color: var(--green-mid); color: var(--green-deep); background: var(--bg-card); }
.tl-add .icon-s { opacity: .6; }

/* Empty-day state: no rail to line up with, so the row sits flush with the
   text above it, and the button hugs its own label as the day's one action
   rather than stretching across the row. */
.tl-add-row--empty { grid-template-columns: minmax(0, 1fr); }
.tl-add--primary {
  justify-self: start;
  width: fit-content;
  border-style: solid;
}
.tl-add--primary:hover { background: #63c853; border-color: #63c853; color: var(--green-deep); }
.tl-add--primary .icon-s { opacity: 1; }

/* Rename and delete, straight on the row. */
.stop-acts { display: flex; align-items: center; gap: 2px; margin-left: auto; flex-shrink: 0; }
.stop-act {
  display: grid;
  text-decoration: none;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  opacity: .55;
  transition: background-color .12s ease, opacity .12s ease;
}
.stop-act:hover { background: var(--bg-page); opacity: 1; }
.stop-act--danger:hover { background: #fdecec; }
.stop-act img { width: 15px; height: 15px; }

/* A state chip that does something reads as pressable. */
.sched__chip--act {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  cursor: pointer;
  transition: filter .12s ease;
}
.sched__chip--act:hover { filter: brightness(.94); }
.sched__chip-arrow { width: 12px; height: 12px; transform: rotate(-90deg); opacity: .7; }

/* Landing flash after jumping to an idea or activity. */
.is-flagged { animation: flagpulse 2s ease; }
@keyframes flagpulse {
  0%, 70% { box-shadow: 0 0 0 2px var(--green); }
  100% { box-shadow: 0 0 0 2px transparent; }
}

/* ------------------------------------------------------------ activities */
.act-card { gap: 14px; }
.act__head { display: flex; align-items: flex-start; gap: 12px; }
.act__title { flex: 1; min-width: 0; }
.act__name { margin: 0; font-size: 16px; font-weight: 600; color: var(--green-deep); }
.act__place { margin: 2px 0 0; font-size: 13px; color: var(--text-muted); }
.act__foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: auto; }
.act__map { gap: 6px; text-decoration: none; background: var(--bg-card); }
.act__map:hover { border-color: var(--green-mid); color: var(--green-deep); }
.act__map .icon-s { opacity: .65; }

/* One column before the map squeezes the stop list. */
@media (max-width: 1000px) {
  .schedsplit { grid-template-columns: minmax(0, 1fr); }
  .daymap { position: static; height: auto; min-height: 0; }
  .daymap__frame { height: 300px; flex: none; }
}

.anytime { display: flex; flex-direction: column; gap: 8px; }
.anytime[hidden] { display: none; }
.anytime__label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.timeline-list { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; }
.timeline-list[hidden] { display: none; }

.tl-row { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 12px; align-items: start; }
.tl-time { padding-top: 18px; font-family: var(--font-display); font-size: 15px; font-weight: 500; color: var(--green-deep); }
/* On the rail the number is centred on the card, so the time matches it. */
.tl-row.tl-row--rail .tl-time { align-self: center; padding-top: 0; }

/* Travel between consecutive stops — HZ-3.2. */
.tl-travel {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  font-size: 13px;
  color: var(--text-muted);
}
.tl-travel__body { display: flex; align-items: center; gap: 8px; padding-left: 4px; }
.tl-travel__line { flex: 1; height: 1px; background: var(--border-soft); }
.tl-travel__dirs { color: var(--green-mid); font-weight: 600; cursor: pointer; }
.tl-travel__dirs:hover { text-decoration: underline; }

/* Time-zone crossing row — HZ-3.4. */
.tl-tz {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: 76px;
  padding: 8px 12px;
  border-radius: 10px;
  background: #eef2fb;
  font-size: 13px;
  font-weight: 500;
  color: #3c5a9a;
}

.plan__empty { padding: 32px 0; font-size: 15px; color: var(--text-muted); }

/* Day / Week / Month — Schedule segment only; the other segments aren't
   day-scoped. */
.rangetoggle { display: flex; align-self: flex-start; gap: 2px; padding: 4px; border-radius: var(--r-pill); background: var(--bg-card); }
.rangetoggle[hidden] { display: none; }
.rangetoggle__btn {
  padding: 6px 14px;
  border-radius: var(--r-pill);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  transition: background-color .12s ease, color .12s ease;
}
.rangetoggle__btn:hover { background: var(--bg-page); }
.rangetoggle__btn.is-active, .rangetoggle__btn.is-active:hover {
  background: var(--green-deep);
  color: #fff;
}

/* Per-stop actions. Rendered dynamically, so initDropdown is applied to each
   new menu after render rather than only at page load. */
.tl-row .dropdown { margin-left: auto; }
.stop-menu-btn {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  cursor: pointer;
}
.stop-menu-btn:hover, .stop-menu-btn[aria-expanded="true"] { background: var(--bg-page); }
.stop-menu-btn img { width: 16px; height: 16px; }
/* .card clips its content; lift it while an in-row menu is open. */
.item-card { position: relative; }

/* Week — each day a labelled block, items and travel rows inside. */
.weekview { display: flex; flex-direction: column; gap: 20px; }
.weekview[hidden], .monthview[hidden] { display: none; }

.weekday__head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border-soft);
}
.weekday__name { font-family: var(--font-display); font-size: 18px; font-weight: 500; color: var(--green-deep); }
.weekday__meta { font-size: 13px; color: var(--text-muted); }
.weekday__empty { padding: 10px 0; font-size: 14px; color: var(--text-faint); }
.weekday { display: flex; flex-direction: column; gap: 10px; }
.weekday--outside .weekday__name { color: var(--text-faint); }

/* Month — a real calendar grid; days outside the trip are dimmed. */
.monthview { display: flex; flex-direction: column; gap: 8px; }
.monthgrid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.monthgrid__dow {
  padding: 4px 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-faint);
  text-align: center;
}
.monthcell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 96px;
  padding: 8px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: var(--bg-card);
  text-align: left;
  cursor: pointer;
  transition: border-color .12s ease;
}
.monthcell:hover { border-color: var(--green); }
.monthcell--outside { background: transparent; border-color: transparent; cursor: default; }
.monthcell--outside .monthcell__n { color: var(--text-faint); }
.monthcell--outside:hover { border-color: transparent; }
.monthcell--today { border-color: var(--green-deep); }
.monthcell__n { font-family: var(--font-display); font-size: 15px; font-weight: 500; color: var(--green-deep); }
.monthcell__chip {
  overflow: hidden;
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--bg-page);
  font-size: 11px;
  color: var(--green-deep);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.monthcell__more { font-size: 11px; color: var(--text-faint); }
.monthcell__warn { color: #d08b2c; }

/* Stop dialog ------------------------------------------------------------ */
.stopform { display: flex; flex-direction: column; gap: 12px; margin: 4px 0 20px; text-align: left; }
.stopform[hidden] { display: none; }
.stopform__row { display: flex; gap: 12px; }
.stopform__row > .stopform__field { flex: 1; }
.stopform__field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.stopform__field > span { font-size: 13px; font-weight: 500; color: var(--text-muted); }
.stopform__field--time { max-width: 140px; }
.stopform .plan__select { width: 100%; }

.stopform__hint { font-style: normal; font-weight: 400; color: var(--text-faint); }
.stopform__note { font-size: 12px; line-height: 1.4; color: var(--text-muted); }
.stopform__note[hidden] { display: none; }
.stopform__note--ok { color: var(--green-mid); }
/* Amber, not red — a link we can't read isn't an error the user made. */
.stopform__note--warn { color: #8a5a12; }

.stopdlg__actions { display: flex; justify-content: flex-end; gap: 8px; }
.btn--danger { background: #fdecec; border-color: #f6d2d2; color: #a32020; }
.btn--danger:hover { background: #f9dcdc; border-color: #efbcbc; }
.btn--danger[hidden] { display: none; }

/* ---------------------------------------------------------- schedule ---- */
/* Map as the card's cover: bled out to the card's edges by cancelling its
   padding, and squared off at the bottom where the day content begins. It
   flexes so it absorbs whatever height the hero + budget stack leaves over. */
.card--day > .map-card {
  flex: 1 1 auto;
  min-height: 160px;
  /* Pull back most of the card's padding, leaving an 8px inset on the three
     outer sides. Inset rather than bled, so all four corners stay rounded.
     Its own radius, not --r-card — the map sits nested a level in, so it
     reads as an inner panel rather than matching the outer card exactly. */
  margin: calc(8px - var(--card-pad)) calc(8px - var(--card-pad)) 0;
  border-radius: 16px;
}
/* One day of the plan, sitting directly under the map so a day and its stop
   read together. Deliberately not the whole itinerary — that's the Plan tab. */
.card--day { gap: 12px; }
/* Own margin rather than the shared gap above, so the map's spacing can move
   independently of the gaps between the day's own header/warning/list/foot. */
.card--day > .map-card { margin-bottom: 8px; }

.sched__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }

/* The day's stop, doubling as the link to its pin on the map above. */
.sched__stop {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px 5px 5px;
  border-radius: var(--r-pill);
  background: var(--bg-page);
  font-size: 14px;
  font-weight: 500;
  color: var(--green-deep);
  cursor: pointer;
  transition: background-color .15s ease;
}
.sched__stop:hover, .sched__stop.is-active { background: var(--green); }
.sched__stop[hidden] { display: none; }

.sched__stop-pin {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: var(--r-pill);
  background: var(--green-deep);
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 1;
  color: var(--green);
}

/* Feasibility / weather — rendered only when the day actually carries one. */
.sched__warn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 10px;
  background: #fdf0dc;
  font-size: 13px;
  font-weight: 500;
  color: #8a5a12;
}
.sched__warn[hidden] { display: none; }

.sched__list { display: flex; flex-direction: column; gap: 2px; }

.sched__item {
  display: grid;
  grid-template-columns: 52px 28px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 6px 8px;
  border-radius: 8px;
  transition: background-color .12s ease;
}
.sched__item:hover { background: var(--bg-page); }

.sched__time {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  color: var(--green-deep);
}

/* Doubled class: base .tile is declared later in this file and would
   otherwise win on source order and force its 40px box. */
.tile.sched__tile { width: 28px; height: 28px; }
.sched__tile .icon-s { width: 15px; height: 15px; }

/* Name and place share a line on a full-width card; the place truncates. */
.sched__body { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.sched__name { font-size: 15px; font-weight: 500; color: var(--green-deep); white-space: nowrap; }
.sched__place {
  font-size: 13px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sched__chip {
  padding: 3px 10px;
  border-radius: var(--r-pill);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.sched__chip--vote { background: #e8e2fb; color: #5b45a8; }
.sched__chip--unbooked { background: #fdf0dc; color: #8a5a12; }
.sched__chip--booked { background: #e1f3e0; color: var(--green-mid); }

.sched__foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sched__more { font-size: 13px; color: var(--text-faint); }
.sched__more[hidden] { display: none; }

/* Raised while its day is hovered, so the link between them is visible. */
.map-pin.is-active {
  background: var(--green);
  color: var(--green-deep);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, .6);
}
.map-pin { transition: background-color .15s ease, color .15s ease, box-shadow .15s ease; }

/* -------------------------------------------------------------- map ----- */
.map-card {
  position: relative;
  min-height: 247px;
  padding: 0;
  border-radius: var(--r-card);
  background: var(--bg-card);
  overflow: hidden;
}

.map-card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0%;
}

.map-card__tint {
  position: absolute;
  inset: 0;
  background: rgba(112, 213, 95, .8);
  mix-blend-mode: soft-light;
}

.map-pin {
  position: absolute;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--r-pill);
  background: var(--green-deep);
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  color: var(--green);
}
/* Percentage positions preserve the pin layout as the card resizes. */
.map-pin--1 { left: 37.7%; top: 43.1%; }
.map-pin--2 { left: 25.7%; top: 28.3%; }
.map-pin--3 { left: 42.0%; top: 75.7%; }

/* Route paths.
   Positioned as percentages of the 579x247 Figma map frame, so they track the
   pins as the card resizes. route-3 runs off the bottom of the frame in the
   design too — the card's overflow:hidden clips it, same as Figma. */
.map-route {
  position: absolute;
  pointer-events: none;
}
/* Positions are set by projectOverlays() in app.js, which re-projects them
   through the same crop object-fit: cover applies to the image. These are the
   original design values, kept as the pre-script fallback. */
.map-route--1 { left: 30.43%; top: 35.40%; width:  8.27%; height: 11.66%; }
.map-route--2 { left: 29.16%; top: 40.04%; width: 15.13%; height: 37.55%; }
.map-route--3 { left: 43.58%; top: 87.15%; width: 21.64%; height: 60.08%; }

.map-card__controls {
  position: absolute;
  left: 12px;
  bottom: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* .btn's default is a full pill; these sit inside the map's own rounded
   corners, so they take that radius instead of staying circular. */
.map-card__controls .btn--icon { border-radius: 16px; }

/* ----------------------------------------------------------- budget ----- */
.budget { justify-content: space-between; }

.budget__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.budget__figures {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-display);
  line-height: 1;
  white-space: nowrap;
}
.budget__amount   { display: flex; align-items: baseline; gap: 4px; }
.budget__value    { font-size: 40px; font-weight: 500; color: var(--green-deep); }
.budget__currency { font-size: 24px; font-weight: 600; }
.budget__sep      { font-size: 32px; font-weight: 300; color: var(--text-faint); }
.budget__target   { color: var(--text-faint); }
.budget__target .budget__value,
.budget__target .budget__currency { color: var(--text-faint); }

.pill {
  flex-shrink: 0;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--pill-bg);
  border: 1px solid var(--pill-border);
  font-size: 14px;
  font-weight: 500;
  color: var(--pill-text);
}

.budget__meter { display: flex; flex-direction: column; gap: 12px; }

/* Segment widths are derived from the figures on the card, not hardcoded, so
   the bar always reflects the real ratio. The track shows through as unallocated
   budget whenever decided + potential is less than the target. */
.meter {
  display: flex;
  height: 16px;
  border-radius: var(--r-pill);
  background: var(--bar-empty);
  overflow: hidden;
}
.meter__seg { height: 100%; }
.meter__seg--decided   { width: calc(var(--decided)   / var(--target) * 100%); background: var(--bar-fill); }
.meter__seg--potential { width: calc(var(--potential) / var(--target) * 100%); background: var(--bar-track); }

.legend { display: flex; gap: 12px; }
.legend__item { display: flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 500; }
.legend__dot  { width: 12px; height: 12px; border-radius: 50%; }
.legend__dot--decided   { background: var(--bar-fill); }
.legend__dot--potential { background: var(--bar-track); }

.budget__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 4px;
}
.budget__total { font-size: 14px; color: var(--text-muted); }

/* -------------------------------------------------- info cards (row 2) -- */
.info-card { position: relative; gap: 16px; }

.info-card__head { display: flex; flex-direction: column; gap: 8px; }

.info-card__meta { font-size: 16px; color: var(--text-muted-2); }
.info-card__meta strong { font-weight: 500; color: var(--green-deep); }

/* Flight timeline */
.timeline { display: flex; gap: 8px; }

.timeline__rail {
  position: relative;
  flex-shrink: 0;
  width: 8px;
}
.timeline__rail::before {
  content: '';
  position: absolute;
  left: 3.5px;
  top: 20px;
  bottom: 20px;
  width: 1px;
  background: var(--green-deep);
  opacity: .35;
}
.timeline__node {
  position: absolute;
  left: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green-deep);
}
.timeline__node--start  { top: 16px; }
.timeline__node--middle { top: 50%; transform: translateY(-50%); background: var(--bg-card); box-shadow: 0 0 0 1.5px var(--green-deep); }
.timeline__node--end    { bottom: 16px; }

.timeline__body { display: flex; flex-direction: column; gap: 12px; flex: 1; min-width: 0; }

.stop { display: flex; align-items: flex-start; gap: 8px; }

.tile {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: var(--r-tile);
}
.tile--flight   { background: var(--tile-flight); }
.tile--bed      { background: var(--tile-bed); border-radius: 8px; }
.tile--people   { background: var(--tile-people); }
.tile--waiting  { background: var(--tile-waiting); }
.tile--approved { background: var(--tile-approved); }
.tile--trip     { background: var(--green); }
.tile--traveler { background: var(--tile-traveler); }

.stop__detail { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.stop__place { display: block; font-size: 16px; font-weight: 500; color: var(--green-deep); }
.stop__time  { display: block; font-size: 14px; color: var(--text-muted); }
.stop__note  { font-size: 14px; }

/* Hotel card */
/* Thumbnail rides alongside the hotel name, in the same rounded frame the
   hero illustration uses. */
.stay__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}
.stay__heading { min-width: 0; }

/* Same silhouette as the hero illustration, whose frame is 287x199 with r=8
   corners and a diagonal running from 49.8% along the bottom up to 53.2% of
   the left edge. Kept at that 1.42:1 ratio so the chamfer matches; the radius
   is scaled down proportionally (8 / 287 of the width). */
.stay__photo {
  margin: 0;          /* figure carries a UA margin that would shrink the slot */
  flex: none;
  width: 64px;
  height: 45px;
  overflow: hidden;
  border-radius: 2px;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 49.8% 100%, 0 53.2%);
  background: var(--bg-page);
}
.stay__photo img { display: block; width: 100%; height: 100%; object-fit: cover; }

.stay { display: flex; flex-direction: column; gap: 4px; margin-top: auto; }

.stay__address {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 6px 4px 4px;
  border: 1px solid var(--border-soft);
  /* Concentric with the bed tile inside it: the tile's 8px radius plus the
     4px of padding around it. --r-card (24px) is the outer card's radius and
     reads as a stadium on a box this short. */
  border-radius: 12px;
}
.stay__address-text {
  font-size: 14px;
  color: var(--text-muted-2);
  min-width: 0;
}
.stay__actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }

.stay__act {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  padding: 4px;
  border-radius: 6px;
  cursor: pointer;
  transition: background-color .15s ease;
}
.stay__act:hover { background: var(--bg-page); }
.stay__act[aria-expanded="true"] { background: var(--bg-page); }

.stay__status { font-size: 14px; font-weight: 500; padding: 0 2px; }

.stay__cancel {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 14px;
  color: var(--text-muted);
}

/* --------------------------------------------------- tile cards (row 3) - */
.card--tile { justify-content: space-between; gap: 16px; min-height: 201px; }

.avatar--xs { width: 24px; height: 24px; font-size: 11px; }

/* Ideas awaiting approval ------------------------------------------------ */
.ideas { display: flex; flex-direction: column; gap: 10px; margin-top: auto; }

.idea { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }

.idea__body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }

.idea__name {
  font-size: 16px;
  font-weight: 500;
  color: var(--green-deep);
  /* Card is a quarter-column, so long proposals have to clip. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.idea__meta { font-size: 14px; color: var(--text-muted); }

/* Documentation prompts -------------------------------------------------- */
/* Shown in place of the counts while a category is still empty: one missing
   item at a time, paged with the arrows, each with its own CTA. */
.prompt { display: flex; flex-direction: column; gap: 10px; }
/* Only the Documentation card pushes its prompt to the bottom: there it sits
   below a count that owns the top of the card. On a card where the prompt IS
   the content, margin-top:auto opened a gap above it and pushed the button
   past the card's edge. */
#docprompt.prompt, .prompt--bottom { margin-top: auto; }

/* An empty checklist grid stops being a grid: it grows to fill the card and
   sits last, so its prompt lands at the foot rather than mid-card with the
   packing note trailing underneath it. */
.checklist-groups--empty {
  display: flex;
  flex-direction: column;
  flex: 1;
  order: 9;
  margin-bottom: 0;
}
.prompt[hidden], .doccount[hidden] { display: none; }

/* One box holds the message, its CTA and the pager. */
.prompt__box {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: var(--bg-page);
}

/* Only Documentation carries arrows — it has three categories to page
   through. Its side padding clears them, because they pin to the box's own
   edges (see .prompt__arrow) rather than taking a row underneath; that row
   was the biggest single cost to the card's height. Every other card has one
   thing to add and no arrows, so that reserved gutter was empty space. */
#docprompt .prompt__box { padding-left: 32px; padding-right: 32px; }

.prompt__tip { display: flex; align-items: flex-start; gap: 8px; }
/* Clears the ✕, which floats over the box's top-right corner. Documentation's
   32px gutter already does this, so only the narrow boxes need it. */
.prompt:not(#docprompt) .prompt__tip { padding-right: 20px; }
/* Optical nudge so the bulb sits on the first line's cap height. */
.prompt__bulb { margin-top: 2px; opacity: .8; }

.prompt__msg { font-size: 14px; line-height: 1.35; color: var(--text-muted); }
.prompt__msg b { font-weight: 600; color: var(--green-deep); }

.prompt__foot { display: flex; align-items: center; gap: 8px; }

/* Secondary = the base .btn (outlined, white hover); only the scale changes,
   since a quarter-column card can't carry the default 16px/10px sizing. */
.btn--sm {
  gap: 6px;
  padding: 7px 14px;
  font-size: 14px;
}
.prompt__cta { cursor: pointer; background: var(--bg-card); }
.prompt__cta:hover { background: #f5f5f5; }

.prompt__close {
  position: absolute;
  top: 8px;
  right: 8px;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  cursor: pointer;
  color: var(--text-faint);
  transition: background-color .15s ease, color .15s ease;
}
.prompt__close:hover { background: var(--bg-card); color: var(--green-deep); }
.prompt__close svg { width: 12px; height: 12px; }

/* Pinned to the box's own left/right edge, vertically centred on the whole
   box rather than sitting in their own row. */
.prompt__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid var(--border-soft);
  background: var(--bg-card);
  cursor: pointer;
  color: var(--text-muted);
  transition: background-color .15s ease, color .15s ease;
}
.prompt__arrow[data-prompt-nav="-1"] { left: 6px; }
.prompt__arrow[data-prompt-nav="1"] { right: 6px; }
.prompt__arrow:hover:not(:disabled) { background: var(--bg-page); color: var(--green-deep); }
.prompt__arrow:disabled { opacity: .35; cursor: default; }
.prompt__arrow svg { width: 14px; height: 14px; }

.prompt__pos { font-size: 12px; color: var(--text-faint); }

.tile-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.tile-card__label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 500;
  color: var(--text-muted);
}
.tile-card__count {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}

.checklist { display: flex; flex-direction: column; gap: 8px; }
.checklist__item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 14px;
  color: var(--text-muted-2);
}
.checklist__more {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 14px;
  font-weight: 500;
  color: var(--green-deep);
}

.avatar-stack { display: flex; align-items: center; }
.avatar-stack .avatar { width: 40px; height: 40px; }
.avatar-stack .avatar + .avatar { margin-left: -12px; }
.avatar-stack .avatar { position: relative; }
.avatar-stack .avatar:first-child { border: 4px solid var(--bg-card); z-index: 2; }

.travelers__foot { display: flex; align-items: center; gap: 12px; }

/* ============================================================ responsive ==
   Desktop is the reference. These breakpoints keep the dashboard usable at
   narrower widths; the dedicated mobile layout comes next.
   ========================================================================== */
@media (max-width: 1180px) {
  .row--tiles { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 1024px) {
  .row { grid-template-columns: 1fr 1fr; }
  .row--hero > .hero,
  .row--hero > .map-card,
  .row--detail > .budget { grid-column: 1 / -1; }
  /* .row--top places its children by column number on the four-column grid
     (hero 1/3, schedule 3/5). Columns 3 and 4 stop existing here, so those
     rules were sending the schedule card into an implicit fifth column off
     the side of the grid. Restated for two columns: each spans the width and
     they stack in source order. */
  .row--top > .hero,
  .row--top > .budget,
  .row--top > .card--day { grid-column: 1 / -1; grid-row: auto; }
  .btn--search { width: auto; }
}

@media (max-width: 820px) {
  .nav { width: 72px; }
  .nav__brand,
  .nav-tab span,
  .nav-user__text { display: none; }
  .nav-tab, .nav-user { justify-content: center; padding: 10px; }
}

/* ============================================================== phone === */
/* Below 640 the sidebar stops being a sidebar. It pins to the bottom of the
   screen as a tab bar — the same buttons, the same data-view attributes, so
   none of the view-switching JS knows anything changed. */
@media (max-width: 640px) {
  .app {
    flex-direction: column;
    gap: 0;
    padding: 12px;
    /* Room for the fixed bar, so the last card is never trapped under it. */
    padding-bottom: calc(var(--tabbar-h) + 12px + env(safe-area-inset-bottom));
  }

  .nav {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 40;
    display: block;
    width: auto;
    height: auto;
    padding: 0 0 env(safe-area-inset-bottom);
    border-radius: 0;
    border-top: 1px solid var(--border-nav);
    background: var(--bg-card);
    overflow: visible;
  }
  .nav__brand { display: none; }

  .nav__list {
    flex-direction: row;
    align-items: stretch;
    gap: 0;
    height: var(--tabbar-h);
  }

  /* Icon over label, each tab taking an equal share of the width. */
  .nav__list .nav-tab {
    flex: 1;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    width: auto;
    height: 100%;
    padding: 6px 2px;
    border-radius: 0;
    text-align: center;
  }
  /* The 820 rule hid every label to fit the 72px rail. Down here there is a
     whole row to work with, and an unlabelled icon row is a guessing game.
     The label comes from data-label rather than the button's own text: with
     Setup showing there are six tabs on a 390px screen, and "Documentation"
     does not fit in 65px at any size worth reading. */
  .nav__list .nav-tab span,
  .nav__list .nav-tab .nav-tab__text { display: none; }
  .nav__list .nav-tab::after {
    content: attr(data-label);
    font-size: 10px;
    line-height: 1.1;
    font-weight: inherit;
  }
  .nav__list .nav-tab .icon { width: 22px; height: 22px; }
  /* The sidebar marks the active tab with a white pill, which reads as a
     button on a white bar. Here the contrast is carried by the label and the
     icon's own weight instead. */
  .nav__list .nav-tab { color: var(--text-faint); }
  .nav__list .nav-tab .icon { opacity: .55; }
  .nav-tab--active { background: none; }
  .nav-tab--active::after { color: var(--green-deep); font-weight: 600; }
  .nav-tab--active .icon { opacity: 1; }
  .nav-tab--more { display: flex; }

  /* Setup keeps its badge but loses the progress meter: a 12px-wide bar in a
     65px column reads as a rendering fault, not as progress. */
  .nav-setup__meter { display: none; }
  .nav-tab__badge { position: absolute; top: 4px; right: 50%; margin-right: -18px; }
  .nav__list .nav-tab { position: relative; }

  /* The foot becomes a sheet above the bar. Laid out the same way it is in
     the sidebar — this is the same element, not a copy. */
  .nav__foot {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    z-index: 41;
    padding: 8px;
    border-top: 1px solid var(--border-nav);
    background: var(--bg-card);
    box-shadow: 0 -12px 24px rgba(0, 0, 0, .1);
    transform: translateY(8px);
    opacity: 0;
    visibility: hidden;
    transition: opacity .18s ease, transform .18s ease, visibility .18s;
  }
  .nav.is-more-open .nav__foot {
    transform: none;
    opacity: 1;
    visibility: visible;
  }
  .nav__foot .nav-tab,
  .nav__foot .nav-user { justify-content: flex-start; padding: 10px 12px; }
  .nav__foot .nav-tab span,
  .nav-user__text { display: block; }

  /* One column, everything. The four-column grid and every span written
     against it collapse together. */
  .row { grid-template-columns: minmax(0, 1fr); }
  .row > * { grid-column: 1 / -1 !important; grid-row: auto !important; }

  /* A map is worth keeping for the sense of place, but not at the cost of
     the whole first screen: a strip above Day 1, not a panel beside it. */
  .map-card { height: 180px; min-height: 0; }

  /* Plan's segment strip is six items wide — more than a phone has. Scrolling
     it sideways keeps it whole; left alone it widened the DOCUMENT, which in
     turn stretched the fixed tab bar past the screen. */
  .segmented {
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .segmented::-webkit-scrollbar { display: none; }
  .segmented > * { flex: 0 0 auto; }

  .topbar { flex-wrap: wrap; gap: 8px; padding-bottom: 12px; }
  .topbar__trip { font-size: 20px; }

  /* .budget__figures is nowrap by design — "7,200 ₪ / 15,000 ₪" must never
     break mid-figure. At 40px that line alone is wider than the card, so the
     "Per person" pill beside it was pushed off the edge. The type scales
     down instead of the line wrapping. */
  .budget__value,
  .money__figures .budget__value    { font-size: 28px; }
  .budget__currency,
  .money__figures .budget__currency { font-size: 18px; }
  /* And the column holding it must be allowed to shrink at all: a flex item
     defaults to min-width:auto, which nowrap content sets to its full width. */
  .budget__head > * { min-width: 0; }
  .budget__head { gap: 10px; }
}

/* The Test control is a localhost-only development toggle. In the sheet it
   sits above a menu that opens upward into the bar — not worth the layout
   work for something a deployment never sees. */
@media (max-width: 640px) {
  [data-test-nav] { display: none; }
}


/* ============================================================ dropdown === */
.dropdown { position: relative; }

.menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 20;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  width: 382px;
  padding: 8px;
  border-radius: var(--r-card);
  border: 1px solid var(--border);
  background: var(--bg-card);
  box-shadow: 0 12px 32px rgba(23, 65, 45, .14), 0 2px 6px rgba(23, 65, 45, .06);
  /* No open animation. Animating opacity/transform promotes the panel to its own
     compositing layer, which macOS colour-manages differently until it flattens
     — #fefefe visibly flashed as pure white on open. */
}
.menu[hidden] { display: none; }

.menu__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  width: 100%;
  padding: 10px 4px;
  /* Concentric with the panel: panel radius (--r-card, 24px) minus its own
     8px padding, so a row's corner traces the same curve as the panel's
     corner instead of a visibly smaller, disjointed one. */
  border-radius: calc(var(--r-card) - 8px);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.25;
  text-align: center;
  text-wrap: balance;
  color: var(--green-deep);
  transition: background-color .12s ease;
}

/* Seven items as 4 / 3, all rows starting at the left edge. */
.menu__item { grid-column: span 1; }
.menu__item:hover,
.menu__item:focus-visible { background: var(--bg-page); outline: none; }
.menu__item:focus-visible { box-shadow: inset 0 0 0 2px var(--green); }

/* Caret flips while the menu is open. */
[aria-expanded="true"] .i-caret-down { transform: rotate(180deg); }
.i-caret-down { transition: transform .15s ease; }

/* Simple single-column menu (trip switcher) — left-aligned rows, no icon tiles. */
.menu--list {
  grid-template-columns: 1fr;
  gap: 2px;
  width: 208px;
  right: auto;
  left: 0;
}

/* Anchors the menu to the button's right edge, for triggers that sit at the
   right of a narrow card. */
.menu--end { left: auto; right: 0; }

.menu__item--row {
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  padding: 10px 12px;
  font-size: 14px;
  text-align: left;
}

.menu__item[aria-disabled="true"] {
  color: #a6aca7;
  cursor: default;
}
.menu__item[aria-disabled="true"]:hover { background: none; }

/* Menu that opens upwards — used low in the sidebar where there's no room below. */
.menu--up { top: auto; bottom: calc(100% + 8px); }

/* Radio-style menu: check mark on the selected entry. */
/* Only the plain label span should stretch — a leading .tile icon box must
   keep its own 40px size, or it inherits this flex:1 and stretches wide. */
.menu__item--row > span:first-child:not(.tile):not(.avatar) { flex: 1; }
.menu__item--row .tile { flex: none; }
.menu__check { margin-left: auto; opacity: 0; }
.menu__item[aria-checked="true"] .menu__check { opacity: 1; }
.menu__item[aria-checked="true"] { font-weight: 600; }

/* Icon-only toolbar button (More). */
.btn--square {
  justify-content: center;
  width: 46px;
  padding: 10px;
}

/* Menus that hang from a right-aligned trigger. */
.menu--right { left: auto; right: 0; }

/* Rows in a list menu carry a leading icon. */
.menu--list .menu__item--row .icon { flex-shrink: 0; }

/* Two-line nav item: title over a smaller secondary line. */
.nav-tab--stacked,
.nav-tab--expandable.nav-tab--stacked { height: auto; padding-top: 8px; padding-bottom: 8px; }
.nav-tab__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.25;
  min-width: 0;
}
.nav-tab__title { font-size: 16px; }
.nav-tab__sub   { font-size: 14px; color: var(--text-soft); }

/* ============================================================== wizard === */
.wizard {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex: 1;
  padding: 24px 8px 48px;
}
.wizard[hidden] { display: none; }

.wizard__card {
  width: 100%;
  max-width: 560px;
  padding: 40px;
  border-radius: var(--r-card);
  background: var(--bg-card);
}

.wizard__eyebrow {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
}
/* Bagoss Condensed · Medium 500 · 40px · line-height 100% · tracking 0% */
.wizard__title {
  margin-top: 4px;
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
  color: var(--green-deep);
}
.wizard__lede {
  margin-top: 10px;
  font-size: 15px;
  color: var(--text-muted);
}

/* stepper */
.stepper {
  display: flex;
  gap: 8px;
  margin: 28px 0 24px;
  padding: 0;
  list-style: none;
}
.stepper__step {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  padding-top: 10px;
  border-top: 2px solid var(--border);
  font-size: 13px;
  color: var(--text-faint);
}
.stepper__step span {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: var(--r-pill);
  background: var(--border);
  font-size: 12px;
  font-weight: 600;
  color: #fff;
}
.stepper__step.is-active { border-top-color: var(--green-deep); color: var(--green-deep); font-weight: 500; }
.stepper__step.is-active span { background: var(--green-deep); }
.stepper__step.is-done { border-top-color: var(--bar-track); color: var(--text-muted); }
.stepper__step.is-done span { background: var(--bar-track); color: var(--green-deep); }

/* fields */
.wizard__step { display: flex; flex-direction: column; gap: 18px; }
.wizard__step[hidden] { display: none; }

.field { display: flex; flex-direction: column; gap: 6px; border: none; padding: 0; margin: 0; }
.field__label {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 14px;
  font-weight: 500;
  padding: 0;
}
.field__label em {
  font-style: normal;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-faint);
}
.field__label em.req {
  font-size: inherit;
  color: var(--green-mid);
  margin-left: -4px;
}
.field__input {
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-page);
  font: inherit;
  font-size: 15px;
  color: var(--text);
}
.field__input::placeholder { color: var(--text-faint); }

select.field__input {
  appearance: none;
  -webkit-appearance: none;
  background-image: url('assets/icons/btn-caret.svg');
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 16px 16px;
  padding-right: 40px;
  cursor: pointer;
}
.field__input:focus {
  outline: none;
  border-color: var(--green-deep);
  box-shadow: 0 0 0 3px rgba(112, 213, 95, .35);
}
.field__hint { font-size: 13px; color: var(--text-faint); }

.field-row { display: flex; gap: 12px; }
.field-row > .field { flex: 1; min-width: 0; }

.check {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 0;
  font-size: 15px;
}
.check span { font-size: 13px; color: var(--text-faint); }
.check input { width: 16px; height: 16px; accent-color: var(--green-deep); }

/* Continue sits right in every step; Back is pushed to the far left when shown. */
.wizard__foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 28px;
}
#wizard-back { margin-right: auto; }
.wizard__skip { border-color: transparent; color: var(--text-muted); }

@media (max-width: 620px) {
  .wizard__card { padding: 24px; }
  .wizard__title { font-size: 32px; }
  .field-row { flex-direction: column; }
  .stepper__step span { display: none; }
}

/* ---------------------------------------------------------- combobox ---- */
.combo { position: relative; }

.combo__list {
  position: absolute;
  top: calc(100% - 18px);
  left: 0;
  right: 0;
  z-index: 30;
  max-height: 232px;
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  list-style: none;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-card);
  box-shadow: 0 12px 32px rgba(23, 65, 45, .14);
}
.combo__list[hidden] { display: none; }

.combo__option {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 9px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.combo__option:hover,
.combo__option.is-active { background: var(--bg-page); }
.combo__name { font-size: 15px; font-weight: 500; color: var(--green-deep); }
.combo__meta { font-size: 13px; color: var(--text-faint); }
.combo__status { padding: 10px; font-size: 13px; color: var(--text-faint); }

/* --------------------------------------------------------- date range --- */
.daterange { position: relative; }

.daterange__trigger {
  text-align: left;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.daterange__trigger.is-empty { color: var(--text-faint); }
.daterange__trigger[aria-expanded="true"] {
  border-color: var(--green-deep);
  box-shadow: 0 0 0 3px rgba(112, 213, 95, .35);
}

.calendar {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 30;
  width: 300px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-card);
  box-shadow: 0 16px 40px rgba(23, 65, 45, .16);
}
.calendar[hidden] { display: none; }

.calendar__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.calendar__month { font-size: 15px; font-weight: 600; color: var(--green-deep); }
.calendar__nav {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  font-size: 16px;
  line-height: 1;
  color: var(--green-deep);
}
.calendar__nav:hover { background: var(--bg-page); }
.calendar__nav:disabled { opacity: .3; cursor: default; }
.calendar__nav:disabled:hover { background: none; }

.calendar__grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.calendar__dow {
  padding-bottom: 6px;
  font-size: 11px;
  font-weight: 600;
  text-align: center;
  color: var(--text-faint);
  text-transform: uppercase;
}

/* Range background sits on the cell, the pill on the button inside it. */
.calendar__cell { padding: 1px 0; }
.calendar__cell.in-range { background: #e2f0e8; }
.calendar__cell.range-start { background: linear-gradient(to right, transparent 50%, #e2f0e8 50%); }
.calendar__cell.range-end   { background: linear-gradient(to left,  transparent 50%, #e2f0e8 50%); }
.calendar__cell.range-start.range-end { background: none; }

.calendar__day {
  width: 100%;
  aspect-ratio: 1;
  border-radius: var(--r-pill);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.calendar__day:hover:not(:disabled) { background: var(--bg-page); }
.calendar__day.is-outside { color: transparent; pointer-events: none; }
.calendar__day:disabled { color: var(--text-faint); opacity: .45; cursor: default; }
.calendar__day.is-today { box-shadow: inset 0 0 0 1px var(--bar-track); }
.calendar__day.is-selected,
.calendar__day.is-selected:hover { background: var(--green-deep); color: #fff; font-weight: 600; }

.calendar__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-faint);
}
.calendar__clear { font-size: 12px; font-weight: 500; color: var(--green-deep); text-decoration: underline; }

/* Wizard actions get roomier side padding than the toolbar buttons. */
.wizard__foot .btn { padding-left: 24px; padding-right: 24px; }

/* Disabled primary action — clearly inert, not just dimmed text. */
.btn:disabled,
.btn--primary:disabled {
  cursor: default;
  background: #cfe8c8;
  border-color: #cfe8c8;
  color: #6f8a72;
}
.btn--primary:disabled:hover { background: #cfe8c8; border-color: #cfe8c8; }

/* ---------------------------------------------------- invite & people --- */
.invite { display: flex; gap: 8px; align-items: flex-end; }
#invite-rows { display: flex; flex-direction: column; gap: 8px; }
#people-list { display: flex; flex-direction: column; }
/* Email is sized to its content rather than stretching the full card width. */
.invite__col { display: flex; flex-direction: column; gap: 4px; flex: 0 1 300px; min-width: 0; }
.invite__col--role { flex: 1; }
.invite__sublabel { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.invite__role { width: 100%; }

.field__hint b { font-weight: 600; color: var(--text-muted); }

.share { display: flex; gap: 8px; }
.share .btn { padding-left: 14px; padding-right: 16px; }

/* WhatsApp keeps its own brand green so it reads as the channel, not a CTA. */
.btn--whatsapp {
  background: #25d366;
  border-color: #25d366;
  color: #0b3d20;
}
.btn--whatsapp:hover { background: #1fbe5b; border-color: #1fbe5b; }

.person {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
}
.person .check { flex: 1; min-width: 0; padding: 4px 0; }
.person__role { flex-shrink: 0; }
.person__role:not(.is-owner) {
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--bg-page);
  font-size: 13px;
  color: var(--text-muted);
}
.person__role.is-owner {
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--bg-page);
  font-size: 13px;
  color: var(--text-muted);
}
.person .invite__role { width: auto; padding: 6px 36px 6px 10px; font-size: 14px;
  background-position: right 12px center; }

/* Extra invite rows drop the sub-labels and gain a remove control. */
.invite + .invite .invite__sublabel { display: none; }

.invite__remove {
  flex-shrink: 0;
  width: 32px;
  height: 42px;
  border-radius: 8px;
  font-size: 20px;
  line-height: 1;
  color: var(--text-faint);
}
.invite__remove:hover { background: var(--bg-page); color: var(--text); }
.invite__remove[hidden] { display: none; }

/* Quiet inline action, used for "Add traveller". */
.link-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  padding: 4px 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--green-deep);
}
.link-btn:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Test-only step switcher. Dashed and muted so it never reads as product UI. */
.testbar {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  max-width: 560px;
  padding: 8px 10px;
  border: 1px dashed var(--border-nav);
  border-radius: 10px;
}
.testbar__label {
  margin-right: 2px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.testbar__btn {
  padding: 5px 10px;
  border-radius: var(--r-pill);
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  white-space: nowrap;
}
.testbar__btn:hover { background: var(--bg-card); }
.testbar__btn.is-active {
  background: var(--green-deep);
  color: #fff;
}

/* =========================================================== celebrate ===
   Success is a wizard step, not an overlay. The confetti canvas sits over the
   whole wizard area so pieces can fly past the card edges. */
.wizard { position: relative; }

.wizard__confetti {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
}

.wizard__step--done {
  align-items: center;
  text-align: center;
  padding: 8px 0 4px;
}

.celebrate__badge {
  display: grid;
  place-items: center;
  width: 68px;
  height: 68px;
  border-radius: var(--r-pill);
  background: var(--green);
  animation: badge-pop .45s cubic-bezier(.2, .9, .3, 1.4) both;
}
.celebrate__badge .icon { width: 34px; height: 34px; }

.celebrate__title {
  font-family: var(--font-display);
  font-size: 36px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}
.celebrate__sub {
  margin-top: -6px;
  font-size: 15px;
  color: var(--text-muted);
}
.wizard__step--done .btn { margin-top: 6px; padding-left: 24px; padding-right: 24px; }

@keyframes badge-pop {
  0%   { transform: scale(0); }
  70%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) { .celebrate__badge { animation: none; } }

/* Once the trip exists the card is purely a success state — the creation
   heading, stepper and footer would all contradict it. */
.wizard__card.is-done .wizard__eyebrow,
.wizard__card.is-done .wizard__title,
.wizard__card.is-done .wizard__lede,
.wizard__card.is-done .stepper,
.wizard__card.is-done .wizard__foot { display: none; }

.wizard__card.is-done { padding-top: 48px; padding-bottom: 44px; }

/* ============================================================ skeleton === */
/* Ghost cards while the dashboard loads: card shells shimmer, contents hide. */
@keyframes shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.content.is-loading .hero,
.content.is-loading .map-card,
.content.is-loading .card {
  background: linear-gradient(90deg, #e6ebe7 25%, #f2f5f2 37%, #e6ebe7 63%);
  background-size: 200% 100%;
  animation: shimmer 1.5s linear infinite;
  border-color: transparent;
}
.content.is-loading .hero > *,
.content.is-loading .map-card > *,
.content.is-loading .card > * { visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .content.is-loading .hero,
  .content.is-loading .map-card,
  .content.is-loading .card { animation: none; }
}

/* Empty states for cards with nothing in them yet. */
.card__empty {
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex: 1;
  gap: 4px;
  padding: 8px 0;
  font-size: 14px;
  color: var(--text-faint);
}
.card__empty b {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 500;
  color: var(--text-muted);
}

/* Live map tiles (OpenStreetMap), used once a destination is known. */
.map-card__tiles { position: absolute; inset: 0; overflow: hidden; }
.map-card__tiles[hidden] { display: none; }
.map-card__tiles img {
  position: absolute;
  width: 256px;
  height: 256px;
  max-width: none;
  user-select: none;
}
.map-card__credit {
  position: absolute;
  right: 6px;
  bottom: 4px;
  z-index: 2;
  font-size: 10px;
  color: var(--green-deep);
  opacity: .65;
}
.map-card__credit[hidden] { display: none; }

/* ============================================================ skeleton === */
/* Ghost cards while the dashboard loads: card shells shimmer, contents hide. */
@keyframes shimmer {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

.content.is-loading .hero,
.content.is-loading .map-card,
.content.is-loading .card {
  background: linear-gradient(90deg, #e6ebe7 25%, #f2f5f2 37%, #e6ebe7 63%);
  background-size: 200% 100%;
  animation: shimmer 1.5s linear infinite;
  border-color: transparent;
}
.content.is-loading .hero > *,
.content.is-loading .map-card > *,
.content.is-loading .card > * { visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .content.is-loading .hero,
  .content.is-loading .map-card,
  .content.is-loading .card { animation: none; }
}

/* Empty states for cards with nothing in them yet. */
.card__empty {
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex: 1;
  gap: 4px;
  padding: 8px 0;
  font-size: 14px;
  color: var(--text-faint);
}
.card__empty b {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 500;
  color: var(--text-muted);
}

/* Live map tiles (OpenStreetMap), used once a destination is known. */
.map-card__tiles { position: absolute; inset: 0; overflow: hidden; }
.map-card__tiles[hidden] { display: none; }
.map-card__tiles img {
  position: absolute;
  width: 256px;
  height: 256px;
  max-width: none;
  user-select: none;
}
.map-card__credit {
  position: absolute;
  right: 6px;
  bottom: 4px;
  z-index: 2;
  font-size: 10px;
  color: var(--green-deep);
  opacity: .65;
}
.map-card__credit[hidden] { display: none; }

/* Expandable nav group (Documentation → categories). */
.nav-group { display: flex; flex-direction: column; gap: 8px; }

.nav-sub {
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* Aligned under the parent's label, with a rule marking the nesting. */
  margin-left: 21px;
  padding-left: 11px;
  border-left: 1px solid var(--border-nav);
}
.nav-sub[hidden] { display: none; }

.nav-tab--sub {
  height: 32px;
  padding: 8px 10px;
  font-size: 14px;
  color: var(--text-muted);
}
.nav-tab--sub:hover { background: rgba(255, 255, 255, .55); color: var(--text); }
.nav-tab--sub.is-active { background: var(--bg-card); color: var(--text); font-weight: 500; }

/* ======================================================= documentation === */
.docs {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  flex: 1;
}
.docs[hidden] { display: none; }

.docs__head { padding: 4px 0 2px; }
.docs__title {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}
.docs__lede { margin-top: 8px; font-size: 15px; color: var(--text-muted); }

/* Row of category tabs. */
.segmented {
  display: flex;
  gap: 6px;
  padding: 6px;
  border-radius: var(--r-pill);
  background: var(--bg-card);
  align-self: flex-start;
}
.segmented__tab {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  border-radius: var(--r-pill);
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
  white-space: nowrap;
  transition: background-color .12s ease, color .12s ease;
}
.segmented__tab .icon-s { opacity: .75; }
.segmented__tab:hover { background: var(--bg-page); color: var(--text); }
.segmented__tab.is-active,
.segmented__tab.is-active:hover { background: var(--green-deep); color: #fff; }
/* Icons are dark strokes by default — invert them to read on the dark pill. */
.segmented__tab.is-active .icon-s { opacity: 1; filter: brightness(0) invert(1); }

/* Panels are a centred upload area rather than a filled card. */
.docs__panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  flex: 1;
  min-height: 320px;
  padding: 24px 0 48px;
}
.docs__panel[hidden] { display: none; }

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  max-width: 440px;
  padding: 36px 32px;
  border: 1.5px dashed var(--border-nav);
  border-radius: var(--r-card);
  text-align: center;
  cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease;
}
.dropzone:hover,
.dropzone:focus-within { border-color: var(--green-mid); background: rgba(255, 255, 255, .5); }
.dropzone.is-over {
  border-color: var(--green-deep);
  border-style: solid;
  background: rgba(112, 213, 95, .12);
}

.dropzone__icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin-bottom: 6px;
  border-radius: var(--r-pill);
  background: var(--bg-card);
}
.dropzone__title {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 500;
  color: var(--green-deep);
}
.dropzone__hint { font-size: 14px; color: var(--text-muted); }
.dropzone__cta {
  margin-top: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--green-mid);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Once files exist the panel stops centring and reads left-to-right. */
.docs__panel.has-files {
  align-items: flex-start;
  justify-content: flex-start;
  padding-top: 8px;
}
.docs__panel.has-files > .dropzone { display: none; }
.docs__filtered-empty {
  padding: 32px 0;
  font-size: 14px;
  color: var(--text-muted);
  text-align: center;
  width: 100%;
}

/* Four across at most; the add tile takes the next cell. */
.doclist {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: stretch;
  gap: 14px;
  width: 100%;
}
@media (max-width: 1280px) { .doclist { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 980px)  { .doclist { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 680px)  { .doclist { grid-template-columns: 1fr; } }
.doclist[hidden] { display: none; }

.doc-card {
  display: flex;
  flex-direction: column;
  aspect-ratio: 1 / 1;      /* height follows the card's width */
  min-height: 0;
  padding: 12px;
  border-radius: var(--r-card);
  background: var(--bg-card);
  cursor: pointer;
  overflow: hidden;
  transition: box-shadow .15s ease;
}

/* Thumbnail fills the space above; details sit at the bottom. */
.doc-card__preview {
  position: relative;
  flex: 1;
  min-height: 0;
  margin-bottom: 10px;
  border-radius: 8px;
  background: var(--bg-page);
  overflow: hidden;
}
.doc-card__preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.doc-card__preview .doc-card__glyph {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  gap: 6px;
}
.doc-card__glyph .icon { width: 30px; height: 30px; opacity: .5; }

.doc-card__foot { display: flex; flex-direction: column; gap: 2px; }
.doc-card:hover { box-shadow: 0 6px 20px rgba(23, 65, 45, .10); }
.doc-card__name { margin-top: 0; font-size: 14px; -webkit-line-clamp: 2; }
.doc-card__meta { margin-top: 2px; }

.doc-card__type {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 1;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--bg-page);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--text-muted);
}

.doc-card__owner {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  border: 2px solid var(--bg-card);
}
.doclist.is-list .doc-card__owner { display: none; }

.doc-card__name {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--green-deep);
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.doc-card__name-input {
  width: 100%;
  padding: 2px 4px;
  border: 1px solid var(--green-mid);
  border-radius: 6px;
  font: inherit;
  font-size: 14px;
}
.doc-card__meta { margin-top: 2px; font-size: 12px; color: var(--text-faint); }

.doc-card__actions {
  display: flex;
  gap: 2px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border-soft);
}
.doc-card__actions button {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
}
.doc-card__actions button:hover { background: var(--bg-page); }
.doc-card__actions .icon { width: 18px; height: 18px; }
.doc-card__actions .is-danger:hover { background: #fbeceb; }

/* Add-another tile, same footprint as a file card. */
.doc-add {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  aspect-ratio: 1 / 1;
  padding: 14px;
  border: 1.5px dashed var(--border-nav);
  border-radius: var(--r-card);
  font-size: 14px;
  font-weight: 500;
  color: var(--green-deep);
  cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease;
}
.doc-add:hover { border-color: var(--green-mid); background: rgba(255, 255, 255, .5); }
.doc-add.is-over { border-color: var(--green-deep); border-style: solid; background: rgba(112, 213, 95, .12); }
.doc-add .icon { width: 22px; height: 22px; }

/* ============================================================ lightbox === */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 32px;
  background: rgba(23, 65, 45, .42);
  backdrop-filter: blur(2px);
}
.lightbox[hidden] { display: none; }

.lightbox__panel {
  display: flex;
  flex-direction: column;
  width: min(920px, 100%);
  height: min(84vh, 100%);
  border-radius: var(--r-card);
  background: var(--bg-card);
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(23, 65, 45, .3);
}

.lightbox__bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  padding: 14px 14px 14px 18px;
  border-bottom: 1px solid var(--border-soft);
}
.lightbox__type {
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--bg-page);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--text-muted);
}
.lightbox__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 15px;
  font-weight: 500;
  color: var(--green-deep);
}
.lightbox__close {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  font-size: 22px;
  line-height: 1;
  color: var(--text-muted);
}
.lightbox__close:hover { background: var(--bg-page); color: var(--text); }

/* Scroll lives here, so long documents scroll inside the panel. */
.lightbox__body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  background: var(--bg-page);
}
.lightbox__body iframe { display: block; width: 100%; height: 100%; border: 0; }
.lightbox__body img { display: block; width: 100%; height: auto; }
.lightbox__fallback {
  display: grid;
  place-items: center;
  height: 100%;
  padding: 40px;
  text-align: center;
  font-size: 14px;
  color: var(--text-muted);
}

/* Category tabs on the left, view toggle pinned to the right of the same row. */
.docs__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border-soft);
}

.docs__bar-right { display: flex; align-items: center; gap: 10px; }
/* Matches .viewtoggle's total height (36px button + 5px padding each side). */
#doc-traveler-btn { height: 46px; box-sizing: border-box; padding-left: 18px; }

.viewtoggle {
  display: flex;
  gap: 4px;
  padding: 5px;
  border-radius: var(--r-pill);
  background: var(--bg-card);
}
.viewtoggle__btn {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-pill);
  transition: background-color .12s ease;
}
.viewtoggle__btn:hover { background: var(--bg-page); }
.viewtoggle__btn.is-active,
.viewtoggle__btn.is-active:hover { background: var(--green-deep); }
.viewtoggle__btn.is-active .icon { filter: brightness(0) invert(1); }
.viewtoggle .icon { width: 20px; height: 20px; }

/* List view is a table: a header row plus one row per file, columns aligned. */
.doclist.is-list { grid-template-columns: 1fr; gap: 6px; }

.doclist__head,
.doclist.is-list .doc-card {
  display: flex;
  flex-direction: row;      /* the base card is a column — override it here */
  align-items: center;
  gap: 16px;
  padding: 16px;             /* top/bottom/right (and left) all equal */
}
.doclist__head {
  padding-bottom: 4px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.doclist__head > :nth-child(1) { flex: 1; padding-left: 60px; }
.doclist__head > :nth-child(2),
.doclist__head > :nth-child(3) { flex: 0 0 140px; }
.doclist__head > :nth-child(4) { flex: 0 0 116px; }

/* Column headers double as sort buttons. */
.doclist__sort {
  text-align: left;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-faint);
  cursor: pointer;
  transition: color .12s ease;
}
.doclist__sort:hover { color: var(--green-deep); }

.doclist.is-list .doc-card { aspect-ratio: auto; cursor: pointer; }
.doclist.is-list .doc-card__preview {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  margin: 0;
}
.doclist.is-list .doc-card__type { display: none; }
.doclist.is-list .doc-card__foot {
  flex: 1;
  flex-direction: row;
  align-items: center;
  gap: 16px;
  min-width: 0;
}
.doclist.is-list .doc-card__name { flex: 1; min-width: 0; -webkit-line-clamp: 1; }
.doclist.is-list .doc-card__cat,
.doclist.is-list .doc-card__date { flex: 0 0 140px; margin: 0; font-size: 13px; color: var(--text-muted); }
.doclist.is-list .doc-card__meta { display: none; }
.doclist.is-list .doc-card__actions {
  flex: 0 0 116px;
  justify-content: flex-end;  /* hug the row's right edge, not the column's left */
  margin: 0;
  padding: 0;
  border-top: none;
}
.doclist.is-list .doc-add {
  flex-direction: row;
  aspect-ratio: auto;
  padding: 12px 16px;
}

/* Category badge shown on cards in the All view. */
.doc-card__cat {
  margin-top: 4px;
  font-size: 12px;
  color: var(--text-faint);
}
.docs__allhint { font-size: 13px; color: var(--text-faint); }
.docs__panel.has-files > .docs__allhint { display: none; }

/* ============================================================= chooser === */
.chooser {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(23, 65, 45, .35);
  backdrop-filter: blur(2px);
}
.chooser[hidden] { display: none; }

.chooser__panel {
  width: min(420px, 100%);
  padding: 28px;
  border-radius: var(--r-card);
  background: var(--bg-card);
  box-shadow: 0 24px 60px rgba(23, 65, 45, .28);
}
.chooser__title {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}
.chooser__sub { margin-top: 8px; font-size: 14px; color: var(--text-muted); }
.chooser__options { display: flex; flex-direction: column; gap: 8px; margin: 20px 0 12px; }
.chooser__option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 15px;
  font-weight: 500;
  text-align: left;
  color: var(--green-deep);
  transition: border-color .12s ease, background-color .12s ease;
}
.chooser__option .icon-s { opacity: .75; }
.chooser__option:hover { border-color: var(--green-deep); background: var(--bg-page); }
.chooser__cancel { width: 100%; justify-content: center; border-color: transparent; color: var(--text-muted); }

/* Date column only exists in the table view. */
.doc-card__date { display: none; }
.doclist.is-list .doc-card__date { display: block; }
.doclist__head { display: none; }
.doclist.is-list .doclist__head { display: flex; }

/* ================================================== overview additions === */

/* Hero: who's going and when, under the destination. */
.hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin-top: 10px;
  font-size: 14px;
  font-weight: 500;
  color: var(--green-deep);
}
.hero__sep { opacity: .45; }

.avatar-stack--sm .avatar { width: 26px; height: 26px; font-size: 12px; }
.avatar-stack--sm .avatar:first-child { border-width: 2px; border-color: var(--green); }
.avatar-stack--sm .avatar + .avatar { margin-left: -8px; }
.avatar--xs {
  width: 20px;
  height: 20px;
  font-size: 10px;
  border-width: 1px;
  flex-shrink: 0;
}

/* Recent expenses inside the budget card. */
.expenses { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }
.expenses__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
/* Collapsed by default so the card stays glanceable; the list is opt-in. */
.expenses__toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 2px 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
}
.expenses__toggle:hover { color: var(--green-deep); }
.expenses__toggle .i-caret-down { transition: transform .15s ease; opacity: .7; }
.expenses__list[hidden] { display: none; }

.expenses__list { display: flex; flex-direction: column; gap: 2px; }
.expense {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  border-top: 1px solid var(--border-soft);
}
.expense:first-child { border-top: none; }

.tile--sm { width: 30px; height: 30px; border-radius: 7px; }
.tile--sm .icon-s { width: 15px; height: 15px; }

.expense__what { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.expense__name {
  font-size: 14px;
  font-weight: 500;
  color: var(--green-deep);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.expense__who { font-size: 12px; color: var(--text-faint); }
.expense__amount {
  flex-shrink: 0;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 500;
  color: var(--green-deep);
  font-variant-numeric: tabular-nums;
}

/* Settle-up line — the most actionable number on the card. */
.balance { font-size: 14px; color: var(--text-muted); }
.balance b { font-weight: 600; color: var(--green-mid); }

.checklist__progress {
  flex-shrink: 0;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--bg-page);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
}

.checklist-groups {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 24px;
  margin: 4px 0;
}
/* The card is a quarter-width tile now, not the half-row span it used to be
   (--card-wide is gone) — two columns of a checklist wouldn't fit, so this
   context always forces one regardless of the packing-visibility toggle. */
.card--tile .checklist-groups { grid-template-columns: 1fr; }
.checklist-group { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.checklist-group[hidden] { display: none; }
/* With packing hidden there's only one column, so let it use the full width. */
.checklist-groups--single { grid-template-columns: 1fr; }

.checklist__note { font-size: 12px; color: var(--text-faint); }
.checklist__note[hidden] { display: none; }
.checklist-group__label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.due {
  flex-shrink: 0;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 600;
  background: var(--bg-page);
  color: var(--text-muted);
}
/* Amber, not red: a deadline is information, not a failure (principle P·6). */
.due--soon { background: #fdf0dc; color: #8a5a12; }

@media (max-width: 1180px) {
  .checklist-groups { grid-template-columns: 1fr; }
}

/* Documentation tile breakdown. */
.doccount { display: flex; flex-direction: column; gap: 6px; }
.doccount__row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-muted);
}
.doccount__row b { margin-left: auto; font-weight: 600; color: var(--green-deep); }
.doccount__row .icon-s { opacity: .7; }


/* ============================================================== setup ===
   Checklist that replaces the old linear wizard. One required step, four
   skippable, with completion derived from real trip state. */
/* Centred column: the checklist is the only thing on this screen, so it sits
   in the middle of the container rather than hugging the left edge. */
.setup { position: relative; display: flex; flex-direction: column; align-items: center; }
.setup .docs__head { width: 100%; max-width: 780px; text-align: center; }
.setup[hidden] { display: none; }
.setup__card { gap: 0; padding: 0; width: 100%; max-width: 780px; margin-top: 32px; }
.setup__drop { padding: 22px 20px; }
/* .card sets display:flex, which outranks the UA's [hidden]{display:none} —
   the same trap as .dayselect and .daymap__empty. Restate it. */
.setup__card[hidden] { display: none; }
.setup__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 20px 24px 16px;
  border-bottom: 1px solid var(--border-soft);
}
.setup__heading { margin: 0; font-family: var(--font-display); font-size: 18px; font-weight: 500; color: var(--green-deep); }
.setup__progress { display: flex; align-items: center; gap: 10px; }
.setup__count { font-size: 13px; color: var(--text-muted); }
.setup__bar { width: 140px; height: 6px; border-radius: var(--r-pill); background: var(--bg-page); overflow: hidden; }
.setup__bar-fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: var(--r-pill);
  background: var(--green);
  transition: width .3s ease;
}

.setup__list { display: flex; flex-direction: column; }
.setup__step { border-bottom: 1px solid var(--border-soft); }
.setup__step:last-child { border-bottom: none; }
/* Marked by a rail, not a background — filling it with the page colour made
   the expanded fields read as floating outside the card. */
.setup__step.is-open { box-shadow: inset 3px 0 0 var(--green); }

.setup__row { display: flex; align-items: center; gap: 12px; padding: 16px 24px; }
.setup__dot {
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--border);
  background: var(--bg-card);
}
.setup__label { flex: 1; font-size: 15px; font-weight: 500; color: var(--green-deep); }
.setup__req {
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: #fdf0dc;
  font-size: 11px;
  font-weight: 600;
  color: #8a5a12;
}
.setup__cta { flex: none; background: var(--bg-card); }
.setup__cta[hidden] { display: none; }

.setup__dot { display: grid; place-items: center; color: #fff; }
.setup__dot svg { width: 11px; height: 11px; }

/* Filled in: ticked and struck through, the way the reference reads. */
.setup__step.is-filled .setup__label { text-decoration: line-through; color: var(--text-faint); }
.setup__step.is-done .setup__req { display: none; }
.setup__step.is-filled .setup__dot { border-color: var(--green-deep); background: var(--green-deep); }

/* Skipped resolves the step but earns no tick — it stays a hollow dot, and the
   button remains so it can still be filled in later. */
.setup__step.is-skipped .setup__label { color: var(--text-muted); }
.setup__step.is-skipped .setup__dot { border-style: dashed; background: var(--bg-card); }
.setup__tag {
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: var(--bg-page);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-faint);
}
.setup__tag[hidden] { display: none; }

/* Locked until the trip exists — there is nothing to attach them to yet. */
.setup__step.is-locked .setup__label { color: var(--text-faint); }
.setup__step.is-locked .setup__cta { opacity: .45; cursor: not-allowed; }

.setup__body { display: flex; flex-direction: column; gap: 16px; padding: 4px 24px 22px; }
.setup__body[hidden] { display: none; }
.setup__actions { display: flex; align-items: center; gap: 8px; }
.setup__skip { background: none; border-color: transparent; color: var(--text-muted); }
.setup__skip:hover { background: var(--bg-card); }

.setup__foot { padding: 14px 24px 18px; border-top: 1px solid var(--border-soft); }
.setup__dismiss {
  font-size: 13px;
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.setup__dismiss:hover { color: var(--green-deep); }

/* ---- success ---- */
.setup__done {
  position: relative;
  z-index: 1;
  width: 100%;
  /* Same gap below the title as the checklist card it replaces. */
  margin-top: 32px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  max-width: 780px;
  padding: 56px 32px 48px;
  border-radius: var(--r-card);
  background: var(--bg-card);
  text-align: center;
}
.setup__done[hidden] { display: none; }
/* The map illustration replaces the tick badge. Width-capped rather than
   fixed so the card still holds together on a narrow viewport; the intrinsic
   width/height on the element keep it from reflowing as the SVG loads. */
.setup__done-art {
  width: min(280px, 70%);
  height: auto;
  animation: setuppop .45s cubic-bezier(.2, 1.4, .5, 1) both;
}
@keyframes setuppop {
  from { transform: scale(.4); opacity: 0; }
  to   { transform: scale(1);  opacity: 1; }
}
.setup__done-title {
  margin: 4px 0 0;
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 500;
  line-height: 1;
  color: var(--green-deep);
}
/* The design puts the trip line in the body colour, not the muted one — it
   is the sentence the card is actually making. */
.setup__done-sub { margin: 0; font-size: 16px; line-height: 1.3; color: var(--green-deep); }
.setup__done-score { margin: 0; font-size: 14px; line-height: 1.3; color: var(--text-muted); }

/* Uploaded documents, listed back inside the Setup step so they can be
   checked before the step counts as done. Reuses .filechip from the flight
   PDF review so the two approve-before-continuing steps look alike. */
/* A duration we could not compute exactly, because an airport's timezone is
   not known. Marked rather than hidden: the figure is still the difference
   between the two printed clock times, which is useful and is not the time in
   the air. Same distinction stop_transits draws with is_routed. */
.fl__duration--approx { border-bottom: 1px dotted currentColor; cursor: help; }

/* The stay section of the stop editor. Set apart from the fields above it
   because it appears and disappears with the stop's type — without a boundary
   the dialog looks like it grew a random tail. */
/* Head of the Ideas panel — just the propose button, right-aligned so it sits
   above the grid without pretending to be a section title. */
.plan__panelhead { display: flex; justify-content: flex-end; margin-bottom: 12px; }

/* An expense row you can open. Kept quiet — a full button treatment on every
   row would turn a list into a wall of controls. */
.expense--editable { cursor: pointer; border-radius: 10px; }
.expense--editable:hover { background: var(--bg-page); }
.expense--editable:focus-visible { outline: 2px solid var(--green-mid); outline-offset: 2px; }

/* Choosing who an expense splits between. A plain list of checkboxes rather
   than a multi-select: the party is small, and seeing every name at once is
   the point — you are deciding who is in, not searching. */
.splitpick { margin: 0; padding: 12px 14px; border: 1px solid var(--border-soft); border-radius: var(--r-nav); }
.splitpick[hidden] { display: none; }
.splitpick__legend { padding: 0 4px; font-size: 12px; color: var(--text-muted); }
.splitpick__list { display: flex; flex-wrap: wrap; gap: 8px 18px; }
.splitpick__row { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }
.splitpick__row input { accent-color: var(--green-mid); }
.splitpick__row--out { color: var(--text-faint); }

/* A stay with no photo. The card is photo-led, so an empty frame reads better
   than a broken image — and better than collapsing the layout, which would
   make one card in a row of three a different height. */
.st__photo--none {
  display: grid;
  place-items: center;
  background: var(--bg-page);
}
.st__photo--none .icon { width: 28px; height: 28px; opacity: .35; }

.stayform {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 4px;
  padding-top: 16px;
  border-top: 1px solid var(--border-soft);
}
.stayform[hidden] { display: none; }
.stayform__head {
  margin: 0;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  color: var(--green-deep);
}
.stopform__hint { margin: -4px 0 0; font-size: 12px; color: var(--text-muted); }

.setup__docs { display: flex; flex-direction: column; gap: 8px; }
.setup__docs-head { margin: 0; font-size: 13px; color: var(--text-muted); }
.setup__docs-items { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; }

/* ---- nav tab ---- */
.nav-tab--setup { height: auto; padding-top: 9px; padding-bottom: 9px; align-items: center; }
.nav-tab--setup .nav-tab__text { display: flex; flex-direction: column; gap: 6px; align-items: stretch; flex: 1; min-width: 0; }
.nav-tab--setup .nav-tab__title { font-size: 16px; line-height: 1.1; }
.nav-setup__meter { display: block; width: 100%; height: 4px; border-radius: var(--r-pill); background: var(--bg-page); overflow: hidden; }
.nav-setup__fill { display: block; height: 100%; width: 0; border-radius: var(--r-pill); background: var(--green); transition: width .3s ease; }
.nav-tab--setup[hidden] { display: none; }

/* Other destinations are inert until the trip exists. */
.nav-tab.is-blocked { opacity: .4; pointer-events: none; }

/* ------------------------------------------------------- setup · legs ---
   One block per destination, each with its own combo and calendar. */
.legs { display: flex; flex-direction: column; gap: 14px; }
.leg {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 16px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--r-card);
  background: var(--bg-card);
}
.leg__head { display: flex; align-items: center; justify-content: space-between; }
.leg__n {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--green-deep);
  font-size: 11px;
  font-weight: 600;
  color: #fff;
}
.leg__remove {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-size: 18px;
  line-height: 1;
  color: var(--text-faint);
  cursor: pointer;
}
.leg__remove:hover { background: var(--bg-page); color: var(--green-deep); }
.leg__dest { position: relative; }
.leg__range { position: relative; }

.set__span { font-size: 13px; color: var(--text-muted); }
#set-legs { margin-bottom: 4px; }

/* Topbar actions are inert until the trip exists — there is nothing to add to. */
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:disabled:hover { background: var(--bg-card); border-color: var(--border); }
.btn--primary:disabled:hover { background: #cfe8c8; border-color: #cfe8c8; }

/* No IATA code: the city becomes the headline so the endpoint still reads. */
.fl__city--lead { font-family: var(--font-display); font-size: 22px; font-weight: 500; color: var(--green-deep); }

.setup__drop--slim { padding: 16px 20px; gap: 4px; }
.setup__drop--slim .dropzone__icon { width: 34px; height: 34px; }

/* Attached file, shown where the dropzone was. */
.filechip {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--r-card);
  background: var(--bg-card);
}
.filechip__icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 9px;
  background: var(--bg-page);
}
.filechip__icon .icon-s { width: 16px; height: 16px; opacity: .6; }
.filechip__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.filechip__name {
  font-size: 14px;
  font-weight: 500;
  color: var(--green-deep);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.filechip__meta { font-size: 12px; color: var(--text-muted); }
.filechip__remove {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: 50%;
  font-size: 18px;
  line-height: 1;
  color: var(--text-faint);
  cursor: pointer;
}
.filechip__remove:hover { background: var(--bg-page); color: var(--green-deep); }

/* Connection detail: one row per leg, with the layover as a labelled gap. */
.fl__legs { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.fl__leg {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px 12px;
  border-radius: 10px;
  background: var(--bg-page);
}
.fl__leg-num { font-size: 12px; font-weight: 600; color: var(--green-deep); }
.fl__leg-route { flex: 1; min-width: 0; font-size: 13px; color: var(--text-muted-2); }
.fl__leg-times { font-size: 13px; font-weight: 500; color: var(--green-deep); }
.fl__leg-op { flex-basis: 100%; font-size: 11px; color: var(--text-faint); }

.fl__layover {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  font-size: 12px;
  color: var(--text-muted);
}
.fl__layover-dot {
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--border);
}
/* Amber, not red — a short connection is a caution, not a failure. */
.fl__layover--tight { color: #8a5a12; font-weight: 500; }
.fl__layover--tight .fl__layover-dot { background: #d08b2c; }

/* Read from a PDF, awaiting confirmation — nothing is in the trip yet. */
.fl-preview { display: flex; flex-direction: column; gap: 10px; }
.fl-preview__head {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--green-deep);
}
.fl-preview__list { display: flex; flex-direction: column; gap: 8px; }
.fl-preview__item {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 12px 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--r-card);
  background: var(--bg-card);
}
.fl-preview__route { font-size: 15px; font-weight: 600; color: var(--green-deep); }
.fl-preview__meta { font-size: 12px; color: var(--text-muted); }
.fl-preview__item.is-outside { opacity: .6; }
.fl-preview__flag {
  align-self: flex-start;
  margin-top: 2px;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: #fdf0dc;
  font-size: 11px;
  font-weight: 600;
  color: #8a5a12;
}

.stay__dates { font-size: 13px; color: var(--text-muted); }
.hero__flight-stops {
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: rgba(23, 65, 45, .12);
  font-size: 11px;
  font-weight: 600;
  color: var(--green-deep);
}

/* ============================================================== auth ===
   Sign-in gate. The app markup stays hidden behind this because RLS means a
   signed-out visitor genuinely cannot read anything. */
.auth {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 32px 20px;
  background: var(--bg-page);
}
.auth[hidden] { display: none; }

.auth__card {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 36px 32px 28px;
  border-radius: var(--r-card);
  background: var(--bg-card);
  box-shadow: 0 10px 40px rgba(23, 65, 45, .08);
}
.auth__brand {
  margin-bottom: 18px;
  font-family: var(--font-logo);
  font-size: 26px;
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--green-deep);
}
.auth__title { margin: 0; font-family: var(--font-display); font-size: 26px; font-weight: 500; color: var(--green-deep); }
.auth__lead { margin: 0 0 12px; font-size: 14px; line-height: 1.45; color: var(--text-muted); }

.auth__form { display: flex; flex-direction: column; gap: 14px; }
.auth__submit { justify-content: center; margin-top: 4px; }

.auth__note { margin: 0; font-size: 13px; line-height: 1.45; color: var(--text-muted); }
.auth__note[hidden] { display: none; }
.auth__note--ok { color: var(--green-mid); }
/* Amber, not red — a mistyped password is not an error state to shout about. */
.auth__note--warn { color: #8a5a12; }

.auth__toggle {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border-soft);
  font-size: 13px;
  color: var(--green-mid);
  cursor: pointer;
}
.auth__toggle:hover { color: var(--green-deep); text-decoration: underline; text-underline-offset: 3px; }

/* Nothing behind the gate should be reachable, including by keyboard. */
body.is-signed-out .app { display: none; }
