/* tour.com design language v0.2 — "Golden hour" (big-tech prestige tier) */
:root {
  --paper: #FAFAF8;
  --card: #FFFFFF;
  --ink: #0F0F0F;
  --muted: #6E6E6E;
  --daybreak: linear-gradient(135deg, #3A1C71, #CB4826 55%, #F6A723);
  --ember: #CB4826;
  --ember-dark: #B23A1D;
  --sea: #0B2B2B;
  --sun: #F6A723;
  --rating-ink: #8A5A14;
  --line: #ECECEC;
  --info: #6E6E6E;
  --radius-card: 18px;
  --radius-pill: 999px;
  --shadow-card: 0 1px 2px rgba(15,15,15,.04), 0 8px 24px rgba(15,15,15,.06);
  --shadow-lift: 0 2px 4px rgba(15,15,15,.05), 0 16px 40px rgba(15,15,15,.10);
  --font: "Plus Jakarta Sans", "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", -apple-system, "Segoe UI", system-ui, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

/* Round 6 (design review): Korean breaks mid-syllable by default, severing
   verb endings ("찾아보세"+"요."). keep-all breaks Korean only at spaces;
   Latin text is unaffected. Scoped to lang="ko" which i18n.js sets. */
html[lang="ko"] body { word-break: keep-all; }

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

:focus-visible {
  outline: 3px solid var(--ember-dark);
  outline-offset: 2px;
  border-radius: inherit;
}

/* ---------- No-JS warning ---------- */
.noscript-banner {
  background: #B3261E; color: #fff; font-weight: 700; font-size: 14px;
  padding: 12px 16px; text-align: center; line-height: 1.45;
}

/* ---------- Hero ---------- */
.hero {
  background:
    radial-gradient(1200px 500px at 85% -10%, rgba(203,72,38,.55), transparent 60%),
    radial-gradient(900px 420px at 10% 110%, rgba(58,28,113,.65), transparent 60%),
    var(--sea);
  color: #fff;
  padding: 56px 20px 0;
}
.hero-inner { max-width: 1060px; margin: 0 auto; position: relative; }
/* Round 6: language switcher — segmented EN | 한국어, top-right of the hero.
   Subtle glass pill on the deep-sea gradient; gold active state (Horizon). */
.lang-switch {
  position: absolute; top: 2px; right: 0;
  display: inline-flex; gap: 4px; padding: 4px;
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(255,255,255,.22);
  border-radius: 999px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.lang-switch button {
  border: 0; background: transparent; cursor: pointer;
  color: rgba(255,255,255,.75);
  font: 700 12px/1 "Plus Jakarta Sans", system-ui, sans-serif;
  letter-spacing: .02em;
  padding: 8px 12px; border-radius: 999px;
}
.lang-switch button.on { background: #F6A723; color: #23233a; }
/* Saved page header: icon + pill as a compact in-flow row on the right. */
.saved-head .topbar-row { display: flex; align-items: center; gap: 10px; }
.saved-head #account-area { position: static; }
.saved-head .lang-switch { position: static; margin: 0; }
/* Round 10.8: the saved header is light — the glass pill's white-on-dark
   styling made the inactive language label invisible. Dark variant. */
.saved-head .lang-switch { background: rgba(11,43,43,.07); border-color: rgba(11,43,43,.16); }
.saved-head .lang-switch button { color: rgba(11,43,43,.65); }
.saved-head .lang-switch button:not(.on):hover { color: #0B2B2B; }
.brand h1 {
  font-size: 22px; font-weight: 800; letter-spacing: -0.02em; margin: 0 0 28px;
  display: inline-flex; align-items: center;
}
/* Horizon mark: gradient sun rising over a gold horizon bar (inline SVG). */
.brand-mark {
  height: 24px; width: auto; margin-right: 8px; flex-shrink: 0;
  filter: drop-shadow(0 0 10px rgba(246,167,35,.45));
}
.brand h1 span { font-weight: 400; opacity: .75; }
.hero-headline {
  font-size: clamp(32px, 5vw, 44px); font-weight: 800;
  letter-spacing: -0.02em; line-height: 1.08; margin: 0 auto 12px; max-width: 640px;
}
.hero-sub { font-size: 16px; opacity: .82; margin: 0 auto 24px; max-width: 560px; }

.search-card {
  background: var(--card); color: var(--ink);
  border-radius: var(--radius-card); box-shadow: var(--shadow-lift);
  display: flex; gap: 8px; padding: 12px; align-items: stretch;
  transform: translateY(28px); margin-bottom: -8px;
  flex-wrap: wrap;
  text-align: left; /* M1: .hero-inner centering is for the plan CTA, not the form */
}
.field { display: flex; flex-direction: column; gap: 4px; padding: 8px 16px; min-width: 130px; }
.field.grow { flex: 1 1 220px; }
.field + .field { border-left: 1px solid var(--line); }
.field label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.field input {
  border: 0; font: inherit; font-size: 16px; font-weight: 600;
  background: transparent; color: var(--ink); padding: 4px 0; min-height: 30px;
}
.field input:focus { outline: none; }
/* Round 9: the city picker is a native select styled like the text fields —
   custom chevron because appearance:none drops the native arrow. */
.field select {
  border: 0; font: inherit; font-size: 16px; font-weight: 600;
  color: var(--ink); padding: 4px 24px 4px 0; min-height: 30px;
  appearance: none; -webkit-appearance: none; background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%236B6259' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 4px center;
  cursor: pointer; max-width: 100%;
}
.field select:focus { outline: none; }
.field:focus-within { background: #F6F4F0; border-radius: 12px; }
.stepper { display: flex; align-items: center; gap: 12px; min-height: 30px; }
.stepper button {
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--line); background: #fff; font-size: 18px; line-height: 1;
  cursor: pointer; color: var(--ink);
}
.stepper span { font-weight: 700; font-size: 14px; min-width: 20px; text-align: center; }
.search-btn {
  background: var(--ember); color: #fff; border: 0; border-radius: 12px;
  font: inherit; font-weight: 700; font-size: 16px; padding: 0 32px; cursor: pointer;
  min-height: 52px; transition: background .15s ease, transform .1s ease;
}
.search-btn:active { transform: scale(.98); }

/* ---------- Main ---------- */
main { max-width: 1060px; margin: 0 auto; padding: 48px 20px 40px; }

#demo-banner {
  background: #fff; border: 1px solid var(--line); color: var(--muted);
  padding: 12px 16px; border-radius: 12px; margin: 0 0 16px; font-size: 12px;
}

#controls {
  display: flex; gap: 12px; align-items: center; justify-content: space-between;
  margin: 0 0 8px; flex-wrap: wrap;
}
/* Round 10.14: author display:flex beats the UA [hidden] rule — force it. */
#controls[hidden] { display: none; }
#pills {
  display: flex; gap: 8px; flex-wrap: wrap;
  padding: 4px; flex: 1; min-width: 0;
  /* Design review 2026-09-11: desktop chips wrap instead of scrolling —
     a half-clipped "Passe:" next to Sort by reads as a layout bug. */
}
#pills::-webkit-scrollbar { display: none; }
.pill {
  flex: 0 0 auto; scroll-snap-align: start;
  padding: 12px 20px; min-height: 44px; font: inherit; font-size: 14px; font-weight: 600;
  border: 1px solid var(--line); background: #fff; border-radius: var(--radius-pill);
  cursor: pointer; color: var(--muted); transition: all .15s ease;
}
.pill.active { background: var(--ink); color: #fff; border-color: var(--ink); }
.sort-wrap { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted); font-weight: 600; flex: 0 0 auto; }
#sort {
  font: inherit; font-size: 14px; font-weight: 600; color: var(--ink);
  padding: 12px 16px; min-height: 44px; border: 1px solid var(--line);
  border-radius: 12px; background: #fff; cursor: pointer;
}

#meta { color: var(--muted); font-size: 14px; margin: 8px 0 16px; min-height: 20px; }

/* ---------- Cards ---------- */
.grid {
  display: grid; gap: 24px;
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
}
.card {
  background: var(--card); border-radius: var(--radius-card);
  overflow: hidden; box-shadow: var(--shadow-card);
  transition: transform .2s ease-out, box-shadow .2s ease-out;
  display: flex; flex-direction: column;
  position: relative; cursor: pointer;
}
.card:active { transform: scale(.99); }
.card-link { color: inherit; text-decoration: none; }
.card-link::after { content: ""; position: absolute; inset: 0; }
.card .save-btn, .card a.option, .card .price-note { position: relative; z-index: 2; }
.card:focus-within { outline: 3px solid var(--ember-dark); outline-offset: 2px; }
.card-link:focus-visible { outline: none; }
.imgwrap { position: relative; aspect-ratio: 4/3; overflow: hidden; background: #EFEDEA; }
.imgwrap img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .3s ease-out; }
.img-fallback { width: 100%; height: 100%; background: var(--daybreak); }
.pick-badge {
  position: absolute; top: 12px; left: 12px;
  background: var(--daybreak); color: #fff;
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
  padding: 8px 16px; border-radius: var(--radius-pill);
  box-shadow: 0 4px 14px rgba(58,28,113,.35);
}
/* ---------- Saved page ---------- */
.saved-wrap { max-width: 760px; margin: 0 auto; padding: 28px 20px calc(120px + env(safe-area-inset-bottom, 0px)); }
.saved-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; }
.saved-head h1 { margin: 0; font-size: 28px; font-weight: 800; letter-spacing: -0.02em; }
.saved-section { margin-bottom: 34px; }
.saved-section > h2 { font-size: 17px; font-weight: 800; margin: 0 0 12px; }
.saved-removed { font-size: 13px; color: var(--muted); margin: 0 0 12px; }
.saved-empty { border: 1px dashed var(--line); border-radius: var(--radius-card); padding: 28px 20px; text-align: center; color: var(--muted); background: #fff; }
.saved-empty p { margin: 0 0 14px; }
.saved-empty .plan-chip { text-decoration: none; display: inline-block; }
.trip-row { display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-card); margin-bottom: 10px; text-decoration: none; color: var(--ink); }
.trip-ico { font-size: 22px; }
.trip-label { flex: 1; font-weight: 700; font-size: 15px; }
.trip-go { color: var(--muted); font-size: 22px; line-height: 1; }
.tour-row { display: flex; gap: 14px; padding: 12px; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-card); margin-bottom: 10px; }
.tour-thumb { width: 96px; height: 96px; object-fit: cover; border-radius: 10px; flex-shrink: 0; background: #EFEDEA; }
.tour-thumb-link { flex-shrink: 0; display: block; }
.tour-title-link { color: inherit; text-decoration: none; }
.tour-body { flex: 1; min-width: 0; }
.tour-body h3 { margin: 0 0 4px; font-size: 15px; line-height: 1.35; }
.tour-meta { margin: 0 0 10px; font-size: 13px; color: var(--muted); }
.tour-price { font-weight: 800; color: var(--ink); }
.tour-actions { display: flex; gap: 8px; }
.tour-book { display: inline-block; padding: 8px 18px; border-radius: var(--radius-pill); background: var(--ember); color: #fff; font-size: 13px; font-weight: 700; text-decoration: none; }
.tour-remove { padding: 8px 14px; border-radius: var(--radius-pill); border: 1px solid var(--line); background: #fff; color: var(--muted); font-size: 13px; font-weight: 700; cursor: pointer; }

/* ---------- Bottom tab bar ---------- */
/* Mobile: full-width bar. Desktop: centered floating pill. Hidden on the
   planner page — the planner is a focused full-screen flow. */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex; background: rgba(255,255,255,.96);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.tabbar a {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 10px 0 9px; text-decoration: none;
  color: var(--muted); font-size: 11px; font-weight: 700;
  -webkit-tap-highlight-color: transparent;
}
.tab-ico { font-size: 21px; line-height: 1; }
body[data-tab="explore"] .tabbar a[data-tablink="explore"],
body[data-tab="saved"] .tabbar a[data-tablink="saved"] { color: var(--ember); }
@media (min-width: 768px) {
  .tabbar {
    left: 50%; right: auto; transform: translateX(-50%); bottom: 20px;
    border: 1px solid var(--line); border-radius: var(--radius-pill);
    padding: 6px; box-shadow: var(--shadow-lift);
  }
  .tabbar a { flex-direction: row; gap: 8px; padding: 10px 22px; font-size: 14px; border-radius: var(--radius-pill); }
  .tab-ico { font-size: 18px; }
}
/* Pages with a tab bar need bottom clearance for it. */
body[data-tab] main { padding-bottom: calc(110px + env(safe-area-inset-bottom, 0px)); }
.save-btn {
  position: absolute; top: 10px; right: 10px;
  width: 40px; height: 40px; border: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.92); color: #3a3a4a; cursor: pointer;
  box-shadow: 0 2px 10px rgba(0,0,0,.18);
  -webkit-tap-highlight-color: transparent;
}
.save-btn svg { display: block; }
.save-btn.on { color: #CB4826; }
.save-btn.on svg { fill: currentColor; }
.body { padding: 16px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.body h2 { font-size: 19px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.3; margin: 0; }
.rating-row { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.stars { position: relative; display: inline-block; color: var(--sun); letter-spacing: 1px; font-size: 12px; line-height: 1; }
.stars-bg { color: #E2DCCF; }
.stars-fg { position: absolute; left: 0; top: 0; overflow: hidden; white-space: nowrap; color: var(--sun); }
.rating-num { font-weight: 700; color: var(--rating-ink); }
.rating-src { color: var(--muted); }
.dot { color: var(--line); }
.duration { color: var(--muted); }
.desc {
  font-size: 14px; color: var(--muted); line-height: 1.55; margin: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.price-row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
/* Round 9 QA: price and its info icon are glued together — the descriptive
   per-party text may wrap below, but the icon never dangles on its own line. */
.price-row .price-group { display: inline-flex; align-items: center; gap: 8px; }
.price { font-size: 17px; font-weight: 800; letter-spacing: -0.01em; }
.per { font-size: 12px; color: var(--muted); }
/* Price ⓘ: tight visual footprint, invisible 44px touch target (hard rule).
   The note itself lives in the singleton #price-pop anchored popover. */
.price-note {
  position: relative;
  border: 0; background: none; padding: 2px 4px; cursor: pointer;
  color: var(--muted); font-size: 13px; line-height: 1;
  display: inline-flex; align-items: center; align-self: center;
}
.price-note::after {
  content: ""; position: absolute; inset: -14px; /* 44px+ hit area, zero visual space */
}
#price-pop {
  position: fixed; z-index: 75;
  max-width: 240px;
  background: var(--ink); color: #fff;
  font-size: 12px; line-height: 1.5;
  padding: 8px 12px; border-radius: 12px;
  box-shadow: var(--shadow-lift);
  opacity: 0; transform: translateY(4px);
  transition: opacity .12s ease-out, transform .12s ease-out;
  pointer-events: none;
}
#price-pop[hidden] { display: none; }
#price-pop.show { opacity: 1; transform: none; }
#price-pop::before {
  content: ""; position: absolute; left: var(--caret-x, 50%);
  width: 10px; height: 10px; background: var(--ink);
  transform: translateX(-50%) rotate(45deg);
}
#price-pop[data-place="above"]::before { bottom: -5px; }
#price-pop[data-place="below"]::before { top: -5px; }

/* Provider option rows — the decision point */
.options { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.option {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  border: 1px solid var(--line); border-radius: 12px; padding: 12px 16px;
  text-decoration: none; color: var(--ink); min-height: 52px;
  transition: border-color .15s ease, background .15s ease;
}
.option:active { background: #FFF9F6; border-color: var(--ember); }
.option-name { display: flex; align-items: center; flex-wrap: wrap; row-gap: 4px; min-width: 0; max-width: 100%; font-weight: 700; font-size: 14px; }
/* Round 9 QA P1: below ~360px the provider name ellipsized mid-word
   ("See it on Tiqet…") and read as broken. The name now wraps to a second
   line instead of truncating; the LIVE chip keeps flex-shrink: 0 and never
   clips. */
.option-name .option-text { min-width: 0; }
.option-name .live-chip { flex-shrink: 0; }
.option-name .ext { color: var(--ember); font-weight: 700; }
.option-meta { font-size: 12px; color: var(--muted); white-space: nowrap; flex-shrink: 0; }
.option-meta strong { color: var(--rating-ink); }
/* Round 4: live/sample chips — bookable inventory labeled at the decision point */
.live-chip {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .02em;
  padding: 4px 8px; border-radius: 999px; margin-left: 8px; vertical-align: 1px;
  background: #FBE7E0; color: var(--ember-dark); white-space: nowrap;
}
.live-chip.sample { background: #EFEFEF; color: var(--muted); }
/* Sample provider rows are reference-only (no booking CTA): no link affordance. */
.option.is-sample { cursor: default; }
.option.is-sample:active { border-color: var(--line); background: transparent; }

.honesty { margin-top: 8px; padding-top: 12px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 4px; }
.honesty p { font-size: 12px; color: var(--info); margin: 0; line-height: 1.5; }
.honesty .neutral { color: var(--info); } /* commission line stays gray, never green */
.honesty .avail::before { content: "ⓘ "; }

/* Comparison synthesis note — sits under the provider option rows */
.compare-note { font-size: 12px; color: var(--info); margin-top: 8px; }
.compare-note::before { content: "ⓘ "; }

/* ---------- Skeleton (Round 10.14: full-anatomy, shared grid + rows) ---------- */
.skel { background: var(--card); border-radius: var(--radius-card); overflow: hidden; box-shadow: var(--shadow-card); }
.skel .img { aspect-ratio: 4/3; }
.shimmer {
  background: linear-gradient(100deg, #EFEDEA 40%, #F8F6F3 50%, #EFEDEA 60%);
  background-size: 200% 100%; animation: shimmer 1.2s infinite linear;
}
@keyframes shimmer { to { background-position: -200% 0; } }
.sk-body { padding: 16px; display: flex; flex-direction: column; gap: 8px; }
.sk-ln { border-radius: 6px; }
.sk-opt { height: 52px; border-radius: 12px; }
/* Round 10.16 (D2): compact-skeleton anatomy — second title line matches
   the skeleton's 16px title line (real compact titles clamp to 2 lines);
   the per line matches the 12px .per under the 17px price line. */
.sk-title2 { height: 16px; width: 65%; }
.sk-per { height: 12px; width: 55%; }

/* ---------- Round 10.14: homepage per-destination rows ---------- */
#rows-crumb {
  background: none; border: none; cursor: pointer;
  color: var(--ember); font: inherit; font-size: 14px; font-weight: 700;
  padding: 10px 4px; margin: 0 0 8px; min-height: 44px;
}
/* 16px track bottom padding + 16px section margin = 32px inter-row rhythm;
   no dividers, no tints. */
.row-section + .row-section { margin-top: 16px; }
.row-head { display: flex; align-items: baseline; justify-content: space-between; margin: 0 0 8px; }
/* Round 10.16 (D1): [city + count] is one flex group, [View all] the other. */
.row-title-group { display: flex; flex-wrap: wrap; align-items: baseline; }
.row-city { font-size: 20px; font-weight: 800; letter-spacing: -0.01em; margin: 0; }
.row-count { color: var(--muted); font-size: 14px; margin-left: 8px; }
.row-viewall {
  font-size: 14px; font-weight: 700; color: var(--ember);
  text-decoration: none; white-space: nowrap; padding: 10px 0 10px 12px;
}
.row-track {
  display: flex; align-items: flex-start; margin: 0 -20px; padding: 8px 0 16px 20px;
  overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none; scroll-snap-type: x proximity; scroll-behavior: smooth;
}
.row-track::-webkit-scrollbar { display: none; }
.row-card { flex: 0 0 auto; width: min(280px, 76vw); margin-right: 16px; scroll-snap-align: start; }
/* margin, not padding — iOS ignores end-padding in scroll overflow */
.row-card:last-child { margin-right: 20px; }
/* Founder 2026-09-16: cards size to their own content — no stretch-to-tallest.
   Row cards are compact browse cards (image/title/rating/price); the full
   comparison lives in the grid. */
/* Title clamp is scoped to compact row cards only — grid cards are the
   detail surface and keep their full titles. */
.card.compact { cursor: pointer; }
.card.compact .body h2 {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
@media (min-width: 768px) {
  /* 3 full cards + ~76px peek at 1020px usable */
  .row-card { width: 304px; }
}
@media (prefers-reduced-motion: reduce) {
  .row-track { scroll-behavior: auto; }
}
/* Trailing planner tile — quiet; every browse path terminates at the planner. */
.row-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; text-align: center; text-decoration: none; color: var(--ink);
  background: var(--card); border: 1.5px dashed var(--line); border-radius: var(--radius-card);
  padding: 32px 20px;
}
.row-tile-title { font-size: 16px; font-weight: 800; }
.row-tile-sub { font-size: 13px; color: var(--muted); }
/* Per-row failure: honest inline block in place of the track. */
.row-error {
  flex: 1 1 auto; min-width: 0;
  border: 1.5px dashed var(--line); border-radius: 18px;
  padding: 32px 20px; text-align: center;
}
.row-error p { font-size: 14px; color: var(--muted); margin: 0 0 8px; }
.row-error button {
  background: none; border: none; cursor: pointer;
  color: var(--ember); font: inherit; font-weight: 700;
  min-height: 44px; padding: 10px 16px;
}
.row-empty { color: var(--muted); font-size: 14px; padding: 24px 4px; margin: 0; }

/* ---------- Empty state ---------- */
#empty, #search-error {
  text-align: center; padding: 64px 20px; color: var(--muted);
  background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-card);
}
#empty p, #search-error p { margin: 8px 0; }
#empty-title { font-weight: 700; font-size: 16px; color: var(--ink); }
/* Round 8: dead-end search -> planner handoff. Ember CTA is primary; the
   "show everything" escape stays as the quiet secondary. */
.empty-actions {
  display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;
  margin-top: 20px;
}
#empty-handoff {
  padding: 12px 24px; min-height: 48px; border-radius: var(--radius-pill);
  border: 0; background: var(--ember); color: #fff;
  font: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
  transition: background .15s ease;
}
#empty-clear, #error-retry {
  padding: 12px 20px; min-height: 44px; border-radius: var(--radius-pill);
  border: 1px solid var(--ink); background: #fff; font: inherit; font-weight: 700; cursor: pointer;
}
#error-retry { margin-top: 16px; }

/* ---------- Trust strip ---------- */
/* Round 10.13: council TAKE — Trip.com's persuasion strip, brand-rewritten.
   Closer above the footer; the wedge's honesty leg, legible on the homepage.
   Static, no JS. 8pt scale: 32px section padding, 24px gaps, 8px tight pairs,
   20px horizontal. Mobile stacks 2x2. */
.trust-strip { background: var(--paper); border-top: 1px solid var(--line); }
.trust-inner {
  max-width: 1060px; margin: 0 auto; padding: 32px 20px;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px;
}
.trust-item { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.trust-icon { width: 28px; height: 28px; color: var(--ember); flex: none; }
.trust-title { margin: 0; font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
.trust-body { margin: 0; font-size: 13px; line-height: 1.55; color: var(--muted); }
@media (max-width: 640px) {
  .trust-inner { grid-template-columns: repeat(2, 1fr); padding: 24px 20px; }
}

/* ---------- Footer ---------- */
/* Round 8: one-line Horizon lockup + wordmark; the positioning line is the
   loudest element (20px/700). money stays undiminished (full opacity,
   readable size); only the proto-note stays muted. No fake links — ever. */
footer {
  background: var(--sea); color: rgba(255,255,255,.78);
  padding: 40px 20px; font-size: 14px; line-height: 1.6;
}
.footer-inner {
  max-width: 1060px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 16px;
}
.footer-lockup { display: flex; align-items: center; gap: 12px; }
.footer-mark { height: 32px; }
.footer-wordmark { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; color: #fff; }
.footer-wordmark span { font-weight: 400; opacity: .75; }
.footer-positioning { font-size: 20px; font-weight: 700; color: #fff; margin: 0; letter-spacing: -0.01em; }
.footer-money { margin: 0; color: rgba(255,255,255,.92); }
.footer-money strong { color: #fff; }
.footer-business { margin: 0; color: rgba(255,255,255,.92); }
.footer-business strong { color: #fff; }
.footer-business a { color: #fff; text-underline-offset: 2px; }
footer .proto-note { opacity: .55; margin: 0; }

/* ---------- Founder-mode chip ---------- */
/* Round 8: fixed, visually subordinate honesty-zone marker. Neutral gray,
   non-interactive (pointer-events: none), fixed positioning means it can
   never shift the 4pt grid. Renders only while suppression is ACTIVE. */
#founder-chip {
  position: fixed; top: 12px; right: 12px; z-index: 70;
  pointer-events: none;
  font-size: 11px; font-weight: 600; letter-spacing: .04em; white-space: nowrap;
  color: #8a8a8a; background: rgba(242,242,242,.94);
  border: 1px solid #dcdcdc; border-radius: 999px;
  padding: 4px 12px;
}

/* ---------- Handoff modal ---------- */
#handoff-modal {
  position: fixed; inset: 0; background: rgba(11,43,43,.55);
  display: flex; align-items: center; justify-content: center; padding: 20px; z-index: 80;
  animation: fade .18s ease-out;
  overflow-y: auto; /* 3b: tall viewports clip the card without this */
}
#handoff-modal[hidden] { display: none; }
@keyframes fade { from { opacity: 0; } }
.modal-card {
  background: #fff; border-radius: var(--radius-card); padding: 28px; max-width: 420px; width: 100%;
  box-shadow: var(--shadow-lift); animation: rise .22s ease-out;
  max-height: calc(100dvh - 40px); overflow-y: auto; /* 3b: clip fix on short viewports */
}
@keyframes rise { from { transform: translateY(16px); opacity: .6; } }
.modal-card h2 { font-size: 19px; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 12px; }
.modal-card h2 span {
  background: var(--daybreak); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.modal-card p { color: var(--muted); font-size: 14px; line-height: 1.6; margin: 0 0 20px; }
.modal-card .modal-trust {
  font-size: 12px; color: var(--info); border-top: 1px solid var(--line);
  padding-top: 12px; margin-top: 12px;
} /* scoped under .modal-card so margin-top wins over .modal-card p */
.modal-actions { display: flex; gap: 8px; }
.modal-actions .cta {
  flex: 1; background: var(--ember); color: #fff; border: 0; border-radius: 12px;
  font: inherit; font-weight: 700; padding: 12px; cursor: pointer; min-height: 48px;
}
.modal-actions .ghost {
  flex: 1; background: #fff; border: 1px solid var(--line); border-radius: 12px;
  font: inherit; font-weight: 600; padding: 12px; cursor: pointer; min-height: 48px;
}

@media (max-width: 640px) {
  .search-card { transform: translateY(20px); }
  .field + .field { border-left: 0; border-top: 1px solid var(--line); }
  .field { min-width: 0; }
  .search-btn { width: 100%; }
  #handoff-modal { align-items: flex-end; padding: 0; }
  .modal-card { border-radius: var(--radius-card) var(--radius-card) 0 0; max-width: none; }
  .modal-card::before {
    content: ""; display: block; width: 40px; height: 4px; border-radius: 2px;
    background: var(--line); margin: 0 auto 16px;
  }
  .modal-actions { flex-direction: column; }
  #pills {
    flex: 1 1 100%; flex-wrap: nowrap; overflow-x: auto;
    scrollbar-width: none; scroll-snap-type: x proximity;
  }
  .sort-wrap { width: 100%; justify-content: space-between; }
  #sort { flex: 1; }
  .option { flex-direction: column; align-items: flex-start; gap: 4px; }
}

/* ---- Conversational planner ---- */
.plan-cta {
  display: inline-block;
  text-decoration: none;
  /* Clear the search card's 28px downward bleed (translateY) plus breathing room. */
  margin: 48px auto 16px;
  padding: 12px 24px;
  max-width: 100%;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.55);
  background: rgba(255,255,255,.14);
  color: #fff;
  font: 600 16px/1.45 inherit;
  font-family: inherit;
  cursor: pointer;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition: background .15s ease;
}
.hero-inner { text-align: center; }

#planner[hidden] { display: none; }
body.planner-open { overflow: hidden; }
#planner {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: min(420px, 100vw);
  background: #fff;
  z-index: 60;
  display: flex;
  flex-direction: column;
  box-shadow: -18px 0 50px rgba(20,10,40,.25);
  border-left: 1px solid rgba(0,0,0,.06);
  animation: plan-in .22s ease;
}
@keyframes plan-in { from { transform: translateX(30px); opacity: 0; } to { transform: none; opacity: 1; } }
.plan-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px;
  border-bottom: 1px solid var(--line);
  background: var(--daybreak);
  color: #fff;
}
/* Round 10.8: the back chevron and language pill are different widths, so
   space-between left the title visibly off-center. Pin it to true center. */
.plan-head { position: relative; }
.plan-title { position: absolute; left: 50%; transform: translateX(-50%); white-space: nowrap; }
.plan-title { font-size: 16px; }
.plan-title #plan-mode { font-weight: 400; opacity: .8; font-size: 12px; }
#plan-close {
  border: 0; background: rgba(255,255,255,.16); color: #fff;
  width: 44px; height: 44px; border-radius: 50%; cursor: pointer; font-size: 14px;
}
#plan-messages {
  flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 16px;
  display: flex; flex-direction: column; gap: 8px;
  background: #FAFAF8;
}
.plan-msg { max-width: 88%; font-size: 14px; line-height: 1.5; }
.plan-msg.bot {
  align-self: flex-start;
  background: #fff; color: var(--ink);
  border: 1px solid var(--line);
  padding: 12px 16px; border-radius: 4px 16px 16px 16px;
  box-shadow: 0 1px 3px rgba(0,0,0,.05);
}
.plan-msg.user {
  align-self: flex-end;
  background: var(--ink); color: #fff;
  padding: 12px 16px; border-radius: 16px 4px 16px 16px;
}
.plan-msg.plan-hint { font-size: 12px; color: var(--muted); background: none; border: 0; box-shadow: none; padding: 0 4px; }
.plan-msg.typing span {
  display: inline-block; width: 8px; height: 8px; margin-right: 4px;
  background: #b9b9c0; border-radius: 50%;
  animation: plan-blink 1s infinite;
}
.plan-msg.typing span:nth-child(2) { animation-delay: .15s; }
.plan-msg.typing span:nth-child(3) { animation-delay: .3s; }
@keyframes plan-blink { 0%,100% { opacity: .3; } 50% { opacity: 1; } }

#plan-chips {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid var(--line);
  background: #fff;
}
#plan-chips:empty { display: none; }
.plan-chip {
  border: 1.5px solid var(--ink); color: var(--ink); background: #fff;
  border-radius: 999px; padding: 8px 16px; font-size: 14px; font-weight: 600;
  cursor: pointer; font-family: inherit; min-height: 44px;
  display: inline-flex; align-items: center;
}
.plan-chip:active { transform: scale(.97); }
.plan-chip.primary { background: var(--ember); border-color: var(--ember); color: #fff; }
.plan-chip.on { background: var(--ink); border-color: var(--ink); color: #fff; }

#plan-form { display: flex; gap: 8px; padding: 12px 16px; background: #fff; }
#plan-input {
  flex: 1; border: 1.5px solid var(--line); border-radius: 999px;
  padding: 12px 16px; font-size: 16px; font-family: inherit; outline: none;
}
#plan-input:focus { border-color: var(--ember); }
.plan-send {
  width: 44px; height: 44px; border-radius: 50%; border: 0;
  background: var(--ember);
  color: #fff; font-size: 18px; cursor: pointer; flex-shrink: 0;
}

.plan-intro { margin-bottom: 12px; font-size: 16px; }
.plan-intro strong { font-weight: 800; letter-spacing: -0.01em; }
/* Plan arrival moment — kicker + summary card + staged day reveal */
.plan-kicker {
  font-size: 12px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ember); margin-bottom: 4px;
}
.plan-summary {
  background: #fff; border-radius: 12px; box-shadow: var(--shadow-card);
  padding: 16px; margin-bottom: 16px;
}
.plan-summary-title { font-size: 16px; font-weight: 800; color: var(--ink); margin-bottom: 4px; }
.plan-summary-meta { font-size: 14px; color: var(--muted); margin-bottom: 8px; }
.plan-summary-totals { font-size: 17px; font-weight: 800; color: var(--ink); margin-bottom: 8px; }
.plan-summary-close { font-size: 12px; color: var(--info); line-height: 1.5; }
.plan-note {
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--info); line-height: 1.5;
}
.plan-short {
  margin: 10px 0 2px; padding: 8px 12px; border-radius: 10px;
  background: rgba(246,167,35,.12); color: var(--ink);
  font-size: 13px; line-height: 1.45;
}
.plan-note::before { content: "ⓘ "; }
.plan-day {
  margin: 12px 0; padding-top: 12px; border-top: 1px dashed rgba(0,0,0,.12);
  animation: plan-day-in .35s ease-out both;
}
/* nth-of-type counts the div siblings inside the plan bubble: kicker(1) +
   summary(2) + intro(3), so day 1 is the 4th div. */
.plan-day:nth-of-type(5) { animation-delay: 90ms; }
.plan-day:nth-of-type(6) { animation-delay: 180ms; }
.plan-day:nth-of-type(7) { animation-delay: 270ms; }
@keyframes plan-day-in { from { opacity: 0; transform: translateY(10px); } }
.plan-day-head { font-weight: 800; font-size: 16px; margin-bottom: 4px; }
.plan-day-intro { font-size: 14px; color: var(--muted); margin-bottom: 8px; font-style: italic; }
.plan-day-foot { font-size: 12px; color: var(--muted); margin-top: 8px; }
.plan-tour { margin-bottom: 12px; }
.plan-tour-title { font-weight: 700; font-size: 14px; }
.plan-tour-meta { font-size: 12px; color: var(--muted); margin: 4px 0 8px; }
.plan-tour-why { font-size: 12px; color: var(--muted); margin-top: 4px; }
.plan-tour .option { margin: 4px 0; }

/* ---- Dedicated planner page (plan.html) ----
   The chat is normal document flow and the body scrolls natively — iOS
   keeps a focused in-flow input above the keyboard on its own. No
   position:fixed panel, no visualViewport tracking (those were the iPhone
   keyboard bug). The form/header are sticky, not fixed, so native
   scroll-into-view keeps working. */
body[data-planner-page] {
  background: #FAFAF8;
}
body[data-planner-page] #planner {
  position: static;
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 0; /* override the generic `main` padding — the chat is full-bleed */
  min-height: 100vh;
  min-height: 100dvh;
  box-shadow: none;
  border: 0;
  border-left: 1px solid rgba(0,0,0,.06);
  border-right: 1px solid rgba(0,0,0,.06);
  animation: none;
  background: #fff;
}
body[data-planner-page] .plan-head {
  position: sticky;
  top: 0;
  z-index: 20;
  gap: 12px;
}
/* Page back control: real SVG chevron, 44px target (hard rule). The i18n
   label lives in .back-label for screen readers; phones show chevron-only. */
body[data-planner-page] #plan-close {
  display: inline-flex; align-items: center; gap: 4px;
  min-width: 44px; min-height: 44px;
  color: #fff; text-decoration: none;
  font-size: 14px; font-weight: 600; line-height: 1.2;
  white-space: nowrap; flex-shrink: 0;
}
body[data-planner-page] #plan-close svg { flex-shrink: 0; display: block; }
body[data-planner-page] .plan-title {
  flex: 1;
  text-align: center;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Planner header language pill: its own component, not an override of the
   homepage hero's .lang-switch (which fights it across breakpoints). */
body[data-planner-page] .plan-lang {
  display: inline-flex; gap: 4px; padding: 4px;
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(255,255,255,.22);
  border-radius: 999px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  flex-shrink: 0;
}
body[data-planner-page] .plan-lang button {
  border: 0; background: transparent; cursor: pointer;
  color: rgba(255,255,255,.75);
  font: 700 12px/1 "Plus Jakarta Sans", system-ui, sans-serif;
  letter-spacing: .02em;
  padding: 8px 12px; border-radius: 999px;
  font-family: inherit;
}
body[data-planner-page] .plan-lang button.on { background: #F6A723; color: #23233a; }
body[data-planner-page] #plan-messages {
  flex: 1;
  overflow: visible;
}
body[data-planner-page] #plan-form {
  position: sticky;
  bottom: 0;
  z-index: 20;
  border-top: 1px solid var(--line);
  padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
}
body[data-planner-page] #plan-chips:empty {
  display: none;
}

@media (max-width: 560px) {
  #planner { width: 100vw; border-left: 0; }
  body[data-planner-page] #planner {
    width: 100%;
    max-width: none;
    border-left: 0;
    border-right: 0;
  }
}
/* Narrow phones: iOS-style chevron-only back control; the label stays
   available to screen readers. */
@media (max-width: 480px) {
  body[data-planner-page] .back-label {
    position: absolute; width: 1px; height: 1px;
    clip-path: inset(50%); overflow: hidden; white-space: nowrap;
  }
  body[data-planner-page] .plan-title {
    font-size: 15px;
  }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---- Hover, gated to real hover devices ----
   iOS Safari keeps :hover stuck after a tap (and shows it while a
   scroll-touch is down), so CTAs looked "selected" while scrolling.
   :active still gives press feedback on touch. */
@media (hover: hover) and (pointer: fine) {
  .lang-switch button:not(.on):hover { color: #fff; }
  .stepper button:hover { border-color: var(--ink); }
  .search-btn:hover { background: var(--ember-dark); }
  .pill:hover { border-color: var(--ink); color: var(--ink); }
  .card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); }
  .card:hover .imgwrap img { transform: scale(1.03); }
  .option:hover { border-color: var(--ember); background: #FFF9F6; }
  .option.is-sample:hover { border-color: var(--line); background: transparent; }
  #empty-handoff:hover { background: var(--ember-dark); }
  #empty-clear:hover, #error-retry:hover { background: var(--ink); color: #fff; }
  .modal-actions .cta:hover { background: var(--ember-dark); }
  .modal-actions .ghost:hover { border-color: var(--ink); }
  .plan-cta:hover { background: rgba(255,255,255,.24); }
  .plan-send:hover { background: var(--ember-dark); }
}
/* Kill the gray tap flash on iOS; :active already covers press feedback. */
button, a { -webkit-tap-highlight-color: transparent; }
\n
/* ---- Planner page: desktop treatment ----
   Mobile-first styling left desktop as a 760px phone slab floating in a
   gray void (hairline bezel borders, 14px app type). On desktop: widen the
   column, drop the device bezel, step type up to desktop scale. */
@media (min-width: 1024px) {
  body[data-planner-page] { background: #fff; }
  body[data-planner-page] #planner {
    max-width: 900px;
    border-left: 0;
    border-right: 0;
  }
  body[data-planner-page] #plan-messages { padding: 28px 40px; gap: 12px; }
  body[data-planner-page] .plan-msg { font-size: 15px; max-width: 82%; }
  body[data-planner-page] #plan-chips { padding: 12px 40px; }
  body[data-planner-page] #plan-form { padding: 16px 40px; }
}

/* Saved-trip share UI (no accounts) */
.plan-save-box { margin: 12px 0 4px; }
.plan-save-msg { font-weight: 600; margin-bottom: 8px; }
.plan-save-link { display: flex; gap: 8px; align-items: stretch; }
.plan-save-link input {
  flex: 1; min-width: 0; padding: 10px 12px; font-size: 13px;
  border: 1px solid rgba(0,0,0,.15); border-radius: 10px; background: #fff;
}
.plan-save-copied { margin-top: 6px; font-size: 13px; color: #1a7f37; }

/* ---------- Round 10: Google sign-in account area ---------- */
/* Round 10.2: the top bar is one compact row — [account icon] [brand]
   [language pill]. Desktop keeps the brand truly centered with the icon and
   pill as corner overlays; on narrow screens (media query below) the three
   share a single 40px flex row, so nothing stacks and nothing grazes. */
.topbar-row { position: relative; }
#account-area { position: absolute; top: 0; left: 0; z-index: 50; line-height: 0; }
#account-area:empty { display: none; }
.topbar-row .brand { text-align: center; }
.account-wrap { position: relative; display: inline-block; }
.account-chip { border: 0; background: transparent; cursor: pointer; padding: 2px; border-radius: 50%; }
.account-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: #F6A723; color: #23233a;
  font: 800 15px/1 "Plus Jakarta Sans", system-ui, sans-serif;
  border: 2px solid rgba(255,255,255,.65);
}
.account-menu {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 60;
  min-width: 190px; background: #fff; color: #23233a;
  border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 32px rgba(11,43,43,.18); padding: 6px;
}
.account-who {
  font: 700 13px/1.3 "Plus Jakarta Sans", system-ui, sans-serif;
  padding: 10px 12px; border-bottom: 1px solid var(--line);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.account-signout {
  display: block; width: 100%; border: 0; background: transparent; cursor: pointer;
  text-align: left; font: 600 13px/1 "Plus Jakarta Sans", system-ui, sans-serif;
  color: #b3261e; padding: 12px; border-radius: 8px;
}
.account-signout:hover { background: rgba(179,38,30,.08); }
.sync-prompt {
  max-width: 760px; margin: 0 auto 18px; padding: 0 20px;
  font-size: 13px; color: var(--muted); text-align: center;
}
/* Round 10.2/10.5: narrow screens — one 40px header row, brand LEADING.
   10.2 centered the wordmark between the buttons; 10.5 moves it left and up
   to 24px with the controls grouped right — the sandwich made the logo feel
   bunched, leading position + size gives it standalone presence. */
@media (max-width: 480px) {
  .topbar-row { display: flex; align-items: center; gap: 8px; }
  .topbar-row .brand { order: -1; flex: 1 1 auto; min-width: 0; text-align: left; }
  .topbar-row .brand h1 { margin: 0; font-size: 24px; white-space: nowrap; }
  #account-area { position: relative; flex: 0 0 auto; }
  .topbar-row .lang-switch { position: static; margin: 0; flex: 0 0 auto; }
  .account-menu { left: auto; right: 0; transform: none; }
  /* Round 10.3: tighten the dead space after the planner CTA — the CTA's
     bottom margin plus main's top padding stacked to 64px. */
  /* Round 10.7: …but 8px of dark below the CTA before the hard cut to white
     felt abrupt — the pill nearly touched the color change. 16px dark + 16px
     white = 32 total, matching the 32px page-top section boundary. */
  .plan-cta { margin: 24px auto 16px; }
  main { padding: 16px 20px 32px; }
  /* Round 10.4: one consistent 8pt vertical rhythm on mobile — sections at
     24-32, blocks at 16, tight pairs at 8. Was a ragged 56/24/8/20/34/16/12/8
     staircase down the homepage. */
  .hero { padding-top: 32px; }
  #controls { gap: 16px; margin-bottom: 16px; }
  #meta { margin-top: 0; }
  /* Round 10.6: hero rhythm was 0/12/44/20 — the headline crashed into the
     header row, and the card's translateY bleed inflated the gap above it
     while shrinking the one below. Kill the bleed on mobile, set explicit
     steps so the hero reads 24/16/24/24. */
  .hero-headline { margin: 24px auto 16px; }
  .search-card { transform: none; margin-bottom: 0; }
}
/* Very narrow phones: tighten the header row so brand + controls fit. */
@media (max-width: 360px) {
  .topbar-row { gap: 6px; }
  .topbar-row .brand h1 { font-size: 20px; }
  .topbar-row .lang-switch button { padding: 6px 8px; }
}
.account-delete {
  display: block; width: 100%; border: 0; background: transparent; cursor: pointer;
  text-align: left; font: 600 13px/1.4 "Plus Jakarta Sans", system-ui, sans-serif;
  color: var(--muted); padding: 12px; border-radius: 8px;
}
.account-delete:hover { background: rgba(0,0,0,.05); }
.footer-legal { margin-top: 14px; font-size: 13px; }
.footer-legal a { color: var(--muted); text-decoration: none; margin: 0 4px; }
.footer-legal a:hover { text-decoration: underline; }

/* ---------- Round 10.15: listing detail page ---------- */
.detail-wrap { max-width: 760px; margin: 0 auto; animation: detail-in .22s ease-out; }
@keyframes detail-in { from { transform: translateY(6px); opacity: .6; } }
.detail-hero { position: relative; aspect-ratio: 4/3; background: #EFEDEA; overflow: hidden; }
.detail-hero img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0; transition: opacity .3s ease; }
.detail-hero img.loaded { opacity: 1; }
.detail-hero .img-fallback { width: 100%; height: 100%; }
.detail-hero .save-btn { top: 12px; right: 12px; }
.detail-back {
  position: absolute; top: 12px; left: 12px; z-index: 3;
  display: inline-flex; align-items: center; gap: 4px;
  min-height: 40px; padding: 8px 16px 8px 10px; border: 0; border-radius: var(--radius-pill);
  background: rgba(255,255,255,.92); color: var(--ink);
  font: inherit; font-size: 14px; font-weight: 700; cursor: pointer;
  box-shadow: 0 2px 10px rgba(0,0,0,.18);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.detail-back::after { content: ""; position: absolute; inset: -4px; }
.detail-back svg { flex-shrink: 0; display: block; }
.detail-body { padding: 24px 20px calc(40px + env(safe-area-inset-bottom, 0px)); }
.detail-body .pick-badge { position: static; display: inline-block; margin: 0 0 8px; }
.detail-title { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.2; margin: 0; }
.detail-body .rating-row { margin-top: 8px; }
.detail-meta { margin-top: 8px; font-size: 14px; color: var(--muted); }
.detail-section { margin-top: 32px; }
.detail-section h2 { font-size: 20px; font-weight: 800; letter-spacing: -0.01em; margin: 0 0 8px; }
.detail-sub { font-size: 14px; color: var(--muted); margin: 0 0 8px; }
.detail-from { font-size: 17px; font-weight: 800; letter-spacing: -0.01em; margin: 0 0 8px; }
.detail-from .per { font-size: 12px; font-weight: 400; }
.options.detail .option { min-height: 64px; padding: 16px; }
.options.detail .option-name { font-size: 15px; }
.options.detail .option-meta { font-size: 13px; }
.options.detail .option-meta .opt-price { font-weight: 700; color: var(--ink); }
.detail-only { font-size: 13px; color: var(--muted); margin-top: 8px; }
.detail-price-note { font-size: 12px; color: var(--info); margin-top: 12px; line-height: 1.5; }
.detail-sample-note { font-size: 12px; color: var(--info); margin-top: 8px; }
.detail-about p { font-size: 16px; line-height: 1.6; margin: 0; }
.detail-cat-row { display: flex; gap: 12px; font-size: 14px; }
.detail-cat-label { font-weight: 700; flex-shrink: 0; }
.detail-cat-vals { color: var(--muted); }
.detail-body .honesty { margin-top: 24px; padding-top: 16px; }
.detail-tile { margin-top: 32px; display: flex; }
.detail-tile .row-tile { flex: 1; }
/* Skeleton (full anatomy) */
.skel-detail { padding: 0 0 40px; }
.skel-detail .sk-hero { aspect-ratio: 4/3; }
.skel-detail .sk-body2 { padding: 24px 20px 0; display: flex; flex-direction: column; gap: 8px; }
.skel-detail .sk-opt { height: 64px; border-radius: 12px; }
/* Light error card (retry) + dark branded not-found */
.detail-error {
  margin: 40px 20px; text-align: center; padding: 48px 20px; color: var(--muted);
  background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-card);
}
.detail-error p { margin: 8px 0; }
.detail-error button {
  padding: 12px 20px; min-height: 44px; border-radius: var(--radius-pill); margin-top: 16px;
  border: 1px solid var(--ink); background: #fff; font: inherit; font-weight: 700; cursor: pointer;
}
.detail-notfound {
  min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(900px 420px at 50% 108%, rgba(203,72,38,.45), transparent 62%), var(--sea);
  color: #FAFAF8; text-align: center; padding: 40px 20px;
}
.detail-notfound .nf-wrap { max-width: 560px; }
.detail-notfound .motif { width: 216px; height: auto; opacity: .28; margin-bottom: 32px; filter: drop-shadow(0 0 24px rgba(246,167,35,.35)); }
.detail-notfound h1 { font-size: clamp(28px, 6vw, 40px); font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; margin: 0 0 12px; }
.detail-notfound p { font-size: 16px; line-height: 1.6; color: rgba(250,250,248,.82); margin: 0 0 8px; }
.detail-notfound .actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 32px; }
.detail-notfound .btn {
  display: inline-block; text-decoration: none; font-weight: 700; font-size: 16px;
  padding: 12px 28px; min-height: 52px; border-radius: 999px; line-height: 1.5;
}
.detail-notfound .btn.primary { background: var(--ember); color: #fff; }
.detail-notfound .btn.ghost { border: 1px solid rgba(255,255,255,.55); color: #fff; background: rgba(255,255,255,.08); }
@media (min-width: 768px) {
  .detail-hero { margin: 24px 20px 0; border-radius: var(--radius-card); aspect-ratio: 2/1; max-height: 380px; }
  .detail-title { font-size: 34px; line-height: 1.15; }
  .skel-detail .sk-hero { margin: 24px 20px 0; border-radius: var(--radius-card); aspect-ratio: 2/1; max-height: 380px; }
}
@media (hover: hover) and (pointer: fine) {
  .detail-notfound .btn.primary:hover { background: var(--ember-dark); }
  .detail-notfound .btn.ghost:hover { background: rgba(255,255,255,.18); }
}

/* ---------- Round 10.20: SEO city pages + homepage destinations ---------- */
/* Server-rendered city pages (/cities/<slug>) and the static homepage
   destinations index. All spacing on the 8pt scale (8/16/24/32/40/48);
   tokens and card treatment reuse the existing design language. */
.city-wrap { max-width: 1060px; margin: 0 auto; padding: 48px 20px 40px; }
.city-topbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; margin: 0 0 32px; }
.city-topbar .city-brand { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; color: var(--ink); text-decoration: none; }
.city-topbar .city-brand span { font-weight: 400; opacity: .75; }
.city-topbar nav { display: flex; flex-wrap: wrap; gap: 8px; }
.city-topbar nav a { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 16px; font-size: 15px; font-weight: 600; color: var(--ink); text-decoration: none; }
.city-wrap h1 { font-size: 32px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.15; margin: 0 0 8px; }
.city-ko { font-size: 16px; color: var(--muted); margin: 0 0 16px; }
.city-intro { font-size: 16px; line-height: 1.6; margin: 0 0 8px; }
.city-avail { font-size: 14px; color: var(--muted); margin: 0 0 24px; }
.city-cta { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 24px; margin: 0 0 32px; background: var(--ember); color: #fff; font-weight: 700; font-size: 15px; text-decoration: none; border-radius: var(--radius-pill); }
.city-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 24px; }
.city-item { background: var(--card); border-radius: var(--radius-card); box-shadow: var(--shadow-card); padding: 24px; display: flex; flex-direction: column; }
.city-item img { display: block; width: 100%; border-radius: 8px; margin: 0 0 16px; order: -1; }
.city-item-title { font-size: 20px; font-weight: 800; letter-spacing: -0.01em; margin: 0 0 8px; }
.city-item-title a { color: var(--ink); text-decoration: none; }
.city-item-desc { font-size: 15px; line-height: 1.65; color: #2b2b3a; margin: 0 0 8px; }
.city-item-browse { font-size: 13px; color: var(--muted); margin: 0 0 8px; }
.city-item-price { font-size: 16px; font-weight: 800; margin: 0; }
.city-siblings { margin: 40px 0 0; }
.city-siblings h2 { font-size: 20px; font-weight: 800; letter-spacing: -0.01em; margin: 0 0 16px; }
.city-siblings a { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 16px; margin: 0 8px 8px 0; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-pill); font-size: 14px; font-weight: 600; color: var(--ink); text-decoration: none; }
.city-foot { margin: 48px 0 0; padding: 24px 0 0; border-top: 1px solid var(--line); font-size: 14px; line-height: 1.6; color: var(--muted); }
.city-foot p { margin: 0 0 8px; }
.city-foot a { color: var(--sea); }
.city-foot .city-avail { margin: 0 0 8px; }
.city-index { background: var(--paper); border-top: 1px solid var(--line); }
.city-index-inner { max-width: 1060px; margin: 0 auto; padding: 32px 20px 40px; }
.city-index h2 { font-size: 20px; font-weight: 800; letter-spacing: -0.01em; margin: 0 0 16px; }
.city-index-links a { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 16px; margin: 0 8px 8px 0; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-pill); font-size: 14px; font-weight: 600; color: var(--ink); text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  .city-cta:hover { background: var(--ember-dark); }
  .city-item-title a:hover { text-decoration: underline; }
  .city-siblings a:hover, .city-index-links a:hover { border-color: var(--muted); }
}
