:root {
  color-scheme: light;
  --paper: #f5f3ee;
  --surface: #fbfaf7;
  --ink: #17231f;
  --muted: #6a716d;
  --line: #deded8;
  --forest: #153c35;
  --accent: #9c6144;
  --sky: #d7e4e8;
  --radius-lg: 24px;
  --radius-md: 16px;

  /* ---------------------------------------------------------------- motion
     Apple-style motion rules of thumb this file follows:

     * Gesture-driven things (anything that tracks a finger) must move 1:1 with
       no transition at all while dragging, then settle on release with a
       spring. A transition during the drag is what makes a sheet feel "sticky".
     * Only `transform` and `opacity` are animated, so everything stays on the
       compositor. `filter`/`box-shadow` are used sparingly for material depth.
     * Durations are short. Press feedback is near-instant; anything above
       ~500ms reads as sluggish.
     * Springs are reserved for motion that should feel physical (sheets,
       cards, presses). Opacity and colour use plain easing — overshoot on a
       fade looks like a glitch.
     * Every animation must be neutralised by `.reduce-motion` (see the block
       near the end of this file). */
  --dur-press: 90ms;
  --dur-1: 140ms;
  --dur-2: 240ms;
  --dur-3: 360ms;
  --dur-4: 520ms;

  --ease: cubic-bezier(.32,.72,0,1);
  --ease-out: cubic-bezier(.22,1,.36,1);
  --ease-in-out: cubic-bezier(.4,0,.2,1);

  /* cubic-bezier fallbacks; replaced with true sampled springs below. */
  --ease-spring: cubic-bezier(.34,1.32,.64,1);
  --ease-spring-soft: cubic-bezier(.34,1.16,.64,1);
  --ease-spring-snap: cubic-bezier(.34,1.42,.64,1);

  /* `--desktop-ease` is deliberately NOT declared here: it is defined inside the
     `@media (min-width: 921px)` motion block further down, together with every
     rule that consumes it. Declaring a second value at the base level would
     silently override that tuned curve for anything outside the query. */

  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  background: var(--paper);
  color: var(--ink);
}

/* Real damped-spring curves, sampled from
   x(t) = 1 - e^(-ζωt)·(cos(ω_d t) + ζω/ω_d·sin(ω_d t)).
   `linear()` gives a genuine spring; the cubic-beziers above stay as the
   fallback for engines that do not support it yet. */
@supports (transition-timing-function: linear(0, 1)) {
  :root {
    /* ζ=0.78, 2.6Hz, settles ~236ms — the default for sheets and cards */
    --ease-spring: linear(0, 0.0044, 0.0168, 0.0359, 0.0607, 0.0901, 0.1232, 0.1593, 0.1976, 0.2374, 0.2783, 0.3197, 0.3611, 0.4023, 0.4429, 0.4826, 0.5213, 0.5586, 0.5946, 0.629, 0.6618, 0.693, 0.7224, 0.7502, 0.7762, 0.8005, 0.8231, 0.8441, 0.8635, 0.8814, 0.8978, 0.9128, 0.9265, 0.9388, 0.95, 0.9601, 0.9691, 0.9771, 0.9842, 0.9904, 1);
    /* ζ=0.92, 1.9Hz, settles ~491ms — long, soft, no overshoot */
    --ease-spring-soft: linear(0, 0.0098, 0.0359, 0.074, 0.1204, 0.1724, 0.2277, 0.2844, 0.3411, 0.3969, 0.4507, 0.5022, 0.5509, 0.5965, 0.6389, 0.678, 0.714, 0.7468, 0.7767, 0.8036, 0.8279, 0.8497, 0.8692, 0.8865, 0.9018, 0.9154, 0.9274, 0.9379, 0.947, 0.955, 0.962, 0.968, 0.9732, 0.9777, 0.9816, 0.9848, 0.9876, 0.99, 0.992, 0.9936, 1);
    /* ζ=0.62, 3.6Hz, settles ~125ms — snappy, for press and toggle feedback */
    --ease-spring-snap: linear(0, 0.0024, 0.0094, 0.0206, 0.0355, 0.0537, 0.075, 0.0988, 0.125, 0.1532, 0.1831, 0.2143, 0.2467, 0.28, 0.3139, 0.3483, 0.3829, 0.4175, 0.4521, 0.4863, 0.5201, 0.5534, 0.586, 0.6179, 0.6489, 0.679, 0.7081, 0.7362, 0.7631, 0.789, 0.8137, 0.8372, 0.8595, 0.8806, 0.9005, 0.9192, 0.9367, 0.9531, 0.9683, 0.9823, 1);
  }
}
.article-dialog > .dialog-close { display: grid !important; place-items: center; position: absolute; z-index: 20; top: 15px; left: 15px; right: auto; width: 38px; height: 38px; padding: 0; border: 1px solid rgba(255,255,255,.82); border-radius: 50%; color: #fff; background: rgba(18,47,42,.62); font-size: 25px; line-height: 1; cursor: pointer; }
.article-dialog-hero { position: relative; overflow: hidden; background: #18352e; }
.article-dialog-hero.has-source-thumbnail { background: #102823 center / cover var(--story-image); }
.article-dialog-hero.has-source-thumbnail::before { content: ""; position: absolute; z-index: 0; inset: -26px; background: center / cover var(--story-image); filter: blur(26px) saturate(.82) brightness(.66); }
.article-dialog-hero::after { content: ""; position: absolute; z-index: 2; inset: 0; pointer-events: none; background: linear-gradient(180deg, rgba(9,28,24,.34), transparent 40%); }
.article-dialog-hero > img { position: relative; z-index: 1; display: block; width: 100%; max-height: 320px; object-fit: cover; }
.article-dialog-hero > img.is-source-thumbnail { object-fit: contain; background: transparent; filter: saturate(.94) drop-shadow(0 12px 30px rgba(6,20,17,.38)); }
.profile-avatar .ui-icon { width: 24px; height: 24px; stroke: currentColor; }
.provider-map-label { display: inline-block; padding: 4px 7px; border: 1px solid rgba(47,105,92,.2); border-radius: 8px; color: #28453d; background: rgba(255,253,250,.94); box-shadow: 0 4px 12px rgba(32,59,51,.14); font-size: 11px; white-space: nowrap; }
.region-dot-marker { display: grid; place-items: center; background: transparent; border: 0; }
.region-dot { display: block; width: 13px; height: 13px; border: 2.5px solid #fffdfa; border-radius: 50%; background: #2f695c; box-shadow: 0 2px 7px rgba(21,60,53,.4); transition: transform 220ms var(--ease), background 220ms ease; }
.region-dot-marker:hover .region-dot { transform: scale(1.25); background: var(--accent); }
.region-dot-marker.is-selected .region-dot { background: var(--accent); box-shadow: 0 0 0 5px rgba(195,122,85,.24), 0 2px 8px rgba(21,60,53,.36); }
.region-dot-label { position: absolute; left: 50%; bottom: 20px; display: none; padding: 3px 8px; border: 1px solid rgba(47,105,92,.22); border-radius: 9px; color: #28453d; background: rgba(255,253,250,.96); box-shadow: 0 5px 14px rgba(32,59,51,.16); font-size: 10px; font-weight: 600; white-space: nowrap; transform: translateX(-50%); }
.region-dot-marker.is-selected .region-dot-label { display: block; }
.leaflet-tooltip.region-tooltip { padding: 3px 9px; border: 1px solid rgba(47,105,92,.22); border-radius: 9px; color: #28453d; background: rgba(255,253,250,.97); box-shadow: 0 6px 16px rgba(32,59,51,.18); font-size: 11px; font-weight: 600; }
.leaflet-tooltip.region-tooltip::before { border-top-color: rgba(255,253,250,.97); }
/* The place sheet overlaps the map bottom, so keep the required attribution visible. */
@media (max-width: 680px) {
  .mobile-map-canvas .leaflet-bottom { bottom: 100px; }
  .mobile-map-canvas .leaflet-control-attribution { padding: 1px 6px; border-radius: 7px; background: rgba(255,253,250,.86); font-size: 9px; }
}
.provider-map-mongolian { display: inline-block; margin-left: 7px; color: #8b6a4e; font-family: "Noto Sans Mongolian", "Mongolian Baiti", sans-serif; font-size: 11px; font-weight: 500; line-height: 1; white-space: nowrap; writing-mode: horizontal-tb; text-orientation: mixed; transform: rotate(90deg); transform-origin: center center; }

/* Desktop-only Apple-like finish; this block intentionally comes last. */
@media (min-width: 921px) {
  .app-shell { gap: 18px; padding: 14px; }
  .side-rail { top: 14px; height: calc(100svh - 28px); border-radius: 28px; background: linear-gradient(165deg, rgba(21,60,53,.98), rgba(15,45,40,.94)); box-shadow: 0 18px 52px rgba(24,53,46,.18), inset 0 1px 0 rgba(255,255,255,.1); }
  .nav-item { min-height: 58px; border-radius: 17px; transition: color 260ms var(--desktop-ease), background 320ms var(--desktop-ease), transform 320ms var(--desktop-ease), box-shadow 320ms var(--desktop-ease); }
  .nav-item:hover { transform: translateX(2px); background: rgba(211,234,219,.1); }
  .nav-item.is-active { background: rgba(235,246,237,.16); box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 8px 22px rgba(0,0,0,.08); }
  .desktop-view-context { min-width: 178px; }
  .desktop-view-context span { font-size: 8px; letter-spacing: .22em; }
  .desktop-view-context strong { font-size: 21px; }
  .search-box { height: 46px; border-color: rgba(32,59,51,.12); background: rgba(255,255,255,.58); box-shadow: 0 8px 26px rgba(32,59,51,.04); transition: width 360ms var(--desktop-ease), border-color 220ms ease, box-shadow 220ms ease; }
  .search-box:focus-within { width: min(420px, 48vw); border-color: rgba(32,59,51,.35); box-shadow: 0 12px 30px rgba(32,59,51,.1); }
  .desktop-layout, body[data-desktop-screen="map"] .desktop-layout #map, body[data-desktop-screen="guides"] .desktop-layout #guides, body[data-desktop-screen="vr"] .mobile-screen[data-screen="vr"], body[data-desktop-screen="profile"] .mobile-screen[data-screen="profile"] { animation: desktop-screen-in 520ms var(--desktop-ease) both; }
  .hero-story { box-shadow: 0 24px 70px rgba(23,53,45,.14), inset 0 1px 0 rgba(255,255,255,.18); }
  .hero-story img { transition: transform 900ms var(--desktop-ease), filter 600ms ease; }
  .hero-story:hover img { transform: scale(1.025); filter: saturate(.84) contrast(.97); }
  .story-card, .recommend-row, .quote-card, .explore-meter, .map-preview, .route-highlight, .profile-links button, .profile-links a { transition: transform 420ms var(--desktop-ease), box-shadow 420ms var(--desktop-ease), border-color 220ms ease, background 220ms ease; }
  .story-card:hover, .map-preview:hover, .quote-card:hover, .explore-meter:hover { transform: translateY(-4px); box-shadow: 0 22px 52px rgba(32,59,51,.13); }
  .recommend-row:hover { transform: translateX(4px); background: rgba(255,255,255,.74); box-shadow: 0 8px 24px rgba(32,59,51,.06); }
  .outline-button, .dark-button, .text-button { transition: transform 260ms var(--desktop-ease), background 220ms ease, border-color 220ms ease, color 220ms ease; }
  .outline-button:hover, .dark-button:hover, .text-button:hover { transform: translateY(-2px); }
  .reduce-motion *, .reduce-motion *::before, .reduce-motion *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
}

@keyframes desktop-screen-in { from { opacity: 0; transform: translateY(10px) scale(.992); } to { opacity: 1; transform: translateY(0) scale(1); } }

* { box-sizing: border-box; }
html { scroll-behavior: smooth; background: var(--paper); }
body { margin: 0; min-width: 320px; background: var(--paper); }
button, input { font: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
button { cursor: pointer; }
button:focus-visible, a:focus-visible, input:focus-visible { outline: 3px solid rgba(195, 122, 85, .6); outline-offset: 3px; }
img { display: block; max-width: 100%; }

.app-shell { display: grid; grid-template-columns: 112px minmax(0, 1fr); min-height: 100svh; }
.side-rail { position: sticky; top: 0; height: 100svh; display: flex; flex-direction: column; align-items: center; padding: 30px 12px 28px; background: var(--forest); color: #eff4ec; }
.brand-mark { display: grid; place-items: center; gap: 7px; color: inherit; text-decoration: none; font-size: 13px; letter-spacing: .12em; writing-mode: vertical-rl; }
.brand-dot { width: 22px; height: 22px; border: 1px solid rgba(255,255,255,.75); border-radius: 50%; position: relative; }
.brand-dot::after { content: ""; width: 7px; height: 7px; background: #d5e5d8; border-radius: 50%; position: absolute; left: 7px; top: 7px; }
.side-nav { display: grid; gap: 14px; margin-top: 78px; width: 100%; }
.nav-item { min-height: 48px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; border-radius: 11px; color: rgba(239,244,236,.7); text-decoration: none; font-size: 11px; transition: background 220ms var(--ease), color 220ms var(--ease), transform 220ms var(--ease); }
.nav-item:hover, .nav-item.is-active { background: rgba(211, 234, 219, .18); color: #fff; transform: translateY(-1px); }
.nav-icon { font-size: 20px; line-height: 1; }
.rail-note { margin-top: auto; font-family: serif; text-align: center; font-size: 11px; line-height: 1.8; color: rgba(239,244,236,.45); }

.content-area { min-width: 0; padding: 0 clamp(24px, 4vw, 76px) 72px; }
.topbar { height: 92px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.mobile-wordmark { display: none; font-family: serif; font-size: 20px; letter-spacing: .12em; }
.search-box { width: min(360px, 45vw); height: 42px; display: flex; align-items: center; gap: 10px; padding: 0 16px; border: 1px solid var(--line); border-radius: 22px; color: var(--muted); background: rgba(255,255,255,.35); transition: border-color 180ms ease, background 180ms ease; }
.search-box:focus-within { border-color: var(--forest); background: #fff; }
.search-box input { min-width: 0; flex: 1; border: 0; outline: 0; color: var(--ink); background: transparent; font-size: 13px; }
.search-box input::placeholder { color: #6c706e; }
.topbar-actions { display: flex; align-items: center; gap: 12px; }
.account-menu-wrap { position: relative; }
.account-menu { position: absolute; z-index: 20; top: calc(100% + 12px); right: 0; display: grid; min-width: 176px; padding: 10px; border: 1px solid var(--line); border-radius: 16px; background: rgba(255,255,255,.96); box-shadow: 0 18px 42px rgba(18,47,42,.16); backdrop-filter: blur(16px); }
.account-menu strong { padding: 8px 10px 10px; color: var(--ink); font-size: 12px; }
.account-menu button { padding: 10px; border: 0; border-radius: 10px; color: var(--ink); background: transparent; text-align: left; font: inherit; font-size: 12px; cursor: pointer; }
.account-menu button:hover { background: var(--paper); }
.account-menu[hidden] { display: none !important; }
.icon-button, .avatar-button { border: 0; background: transparent; color: var(--ink); }
.icon-button { width: 38px; height: 38px; border-radius: 50%; font-size: 22px; }
.icon-button:hover { background: #e7e9e3; }
.avatar-button { width: 34px; height: 34px; border-radius: 50%; color: #f7f8f3; background: var(--forest); font-size: 13px; }
.avatar-button { display: grid; place-items: center; padding: 0; }
.avatar-button .ui-icon { width: 18px; height: 18px; }

.desktop-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(272px, 320px); gap: clamp(24px, 3vw, 52px); max-width: 1440px; margin: 0 auto; }
.primary-column { min-width: 0; }
.hero-story { min-height: min(620px, calc(100svh - 150px)); position: relative; overflow: hidden; border-radius: var(--radius-lg); background: #274841; isolation: isolate; }
.hero-story img { width: 100%; height: 100%; min-height: 520px; object-fit: cover; object-position: center; filter: saturate(.75) contrast(.95); }
.hero-shade { position: absolute; inset: 0; background: linear-gradient(90deg, rgba(10,28,24,.72), rgba(10,28,24,.12) 68%), linear-gradient(0deg, rgba(10,28,24,.9), transparent 64%); }
.hero-copy { position: absolute; left: clamp(28px, 5vw, 72px); right: 28px; bottom: clamp(32px, 7vw, 76px); color: #fff; }
.eyebrow, .section-kicker, .feed-category { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; }
.hero-copy h1 { margin: 16px 0 8px; font-family: serif; font-weight: 400; font-size: clamp(38px, 5vw, 72px); line-height: .98; letter-spacing: .04em; }
.hero-copy p { margin: 0 0 26px; font-family: serif; font-size: clamp(15px, 1.4vw, 19px); }
.outline-button, .dark-button { min-height: 44px; padding: 0 20px; border-radius: 24px; color: #fff; border: 1px solid rgba(255,255,255,.65); background: transparent; transition: background 180ms ease, transform 180ms ease; }
.outline-button:hover { background: rgba(255,255,255,.16); transform: translateY(-1px); }
.hero-progress { position: absolute; bottom: 25px; right: 28px; display: flex; gap: 6px; }
.hero-progress span { width: 6px; height: 6px; background: rgba(255,255,255,.46); border-radius: 50%; }
.hero-progress .is-active { width: 25px; border-radius: 5px; background: #fff; }

.editor-picks { padding: 48px 0 56px; }
.section-heading, .rail-heading, .meter-row { display: flex; align-items: baseline; justify-content: space-between; gap: 18px; }
.section-heading h2, .rail-heading h2 { margin: 0; font-family: serif; font-size: 26px; font-weight: 400; letter-spacing: .08em; }
.section-heading p, .recommend-note { margin: 7px 0 0; color: var(--muted); font-size: 12px; }
.text-button { padding: 0; border: 0; color: var(--muted); background: transparent; font-size: 12px; white-space: nowrap; }
.text-button:hover { color: var(--forest); }
.story-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 16px; margin-top: 26px; }
.story-card { position: relative; min-width: 0; border-bottom: 1px solid var(--line); padding-bottom: 17px; }
.story-image-button { display: block; width: 100%; padding: 0; border: 0; border-radius: var(--radius-md); overflow: hidden; background: #dbe3df; }
.story-image-button img { aspect-ratio: 1.24; width: 100%; object-fit: cover; filter: saturate(.8); transition: transform 420ms var(--ease), filter 420ms ease; }
.media-image.is-source-thumbnail { object-fit: contain; background: linear-gradient(135deg, #dfe8e0, #cddbd2); }
.story-image-button:hover img { transform: scale(1.035); filter: saturate(1); }
.story-card-copy { padding: 15px 4px 0; }
.story-card-copy > span, .recommend-row span { color: var(--accent); font-size: 11px; letter-spacing: .08em; }
.story-card h3, .recommend-row h3 { margin: 7px 0 6px; font-family: serif; font-size: 17px; font-weight: 400; line-height: 1.25; }
.story-card p, .recommend-row p { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.55; }
.story-card small { display: block; margin-top: 14px; color: #6c706e; font-size: 10px; letter-spacing: .08em; }
.save-button { position: absolute; right: 3px; bottom: 14px; border: 0; color: #7f8984; background: transparent; font-size: 21px; line-height: 1; }
.save-button.is-saved { color: var(--accent); }

.map-preview { display: grid; grid-template-columns: minmax(0, .85fr) minmax(280px, 1.15fr); min-height: 270px; overflow: hidden; border-radius: var(--radius-lg); background: var(--sky); }
.map-copy { padding: 40px; }
.map-copy h2 { margin: 14px 0 12px; font-family: serif; font-size: clamp(29px, 3.2vw, 44px); font-weight: 400; line-height: 1.08; }
.map-copy p { max-width: 280px; color: #5d746d; font-size: 13px; line-height: 1.7; }
.dark-button { border-color: var(--forest); color: #fff; background: var(--forest); }
.dark-button:hover { transform: translateY(-1px); background: #1c4e44; }
.dark-button.is-saved { border-color: rgba(195,122,85,.55); color: var(--accent); background: rgba(195,122,85,.12); }
.dark-button.is-saved:hover { background: rgba(195,122,85,.2); }
.desktop-map-panel { display: grid; grid-template-rows: minmax(230px, 1fr) auto; gap: 12px; min-width: 0; padding: 18px; background: rgba(255,255,255,.18); }
.desktop-map-canvas { position: relative; min-height: 230px; overflow: hidden; border-radius: 18px; background: rgba(255,255,255,.2); }
.map-lines { position: absolute; inset: 0; min-height: 0; overflow: hidden; background: radial-gradient(circle at 72% 30%, rgba(255,255,255,.7), transparent 15%), linear-gradient(132deg, transparent 45%, rgba(21,60,53,.18) 45.4%, transparent 46%), linear-gradient(15deg, transparent 52%, rgba(21,60,53,.2) 52.4%, transparent 53%); }
.map-lines::before, .map-lines::after { content: ""; position: absolute; border: 1px solid rgba(21,60,53,.25); border-radius: 50%; transform: rotate(-22deg); }
.map-lines::before { width: 340px; height: 170px; left: 18%; top: 18%; }
.map-lines::after { width: 480px; height: 240px; left: 2%; top: -8%; }
.map-lines i { position: absolute; width: 10px; height: 10px; border: 3px solid var(--forest); background: var(--sky); border-radius: 50%; }
.map-lines i:nth-of-type(1) { left: 30%; top: 34%; }.map-lines i:nth-of-type(2) { left: 58%; top: 58%; }.map-lines i:nth-of-type(3) { left: 76%; top: 27%; }
.desktop-region-pins { position: absolute; z-index: 2; inset: 0; }
.desktop-region-pin { position: absolute; display: grid; grid-template-columns: auto auto; align-items: center; gap: 7px; min-width: 74px; min-height: 48px; padding: 6px 10px; border: 1px solid rgba(21,60,53,.55); border-radius: 15px; color: var(--forest); background: rgba(247,251,247,.9); box-shadow: 0 8px 18px rgba(21,60,53,.11); font-size: 10px; white-space: nowrap; transform: translate(-50%, -50%); transition: color 180ms ease, background 180ms ease, transform 180ms var(--ease), box-shadow 180ms ease; }
.map-pin-chinese { font-weight: 600; }
.map-pin-mongolian { writing-mode: vertical-lr; text-orientation: upright; letter-spacing: .06em; font-family: "Noto Sans Mongolian", "Mongolian Baiti", sans-serif; font-size: 12px; line-height: 1; }
.desktop-region-pin:hover, .desktop-region-pin:focus-visible { color: #fff; background: var(--forest); box-shadow: 0 10px 22px rgba(21,60,53,.2); transform: translate(-50%, -50%) scale(1.04); outline: none; }
.desktop-region-pin.is-selected { color: #fff; background: var(--forest); box-shadow: 0 0 0 7px rgba(21,60,53,.12), 0 10px 22px rgba(21,60,53,.2); }
.desktop-map-compass { position: absolute; z-index: 3; top: 16px; right: 16px; display: grid; justify-items: center; gap: 2px; color: rgba(21,60,53,.62); font: 500 9px/1 sans-serif; }
.desktop-map-compass i { display: block; width: 1px; height: 28px; background: linear-gradient(var(--accent), var(--forest)); transform: rotate(18deg); }
.desktop-map-selection { min-height: 64px; padding: 10px 12px; border: 1px solid rgba(21,60,53,.12); border-radius: 14px; background: rgba(255,255,255,.42); }
.desktop-map-selection > span { color: var(--forest); font-family: serif; font-size: 19px; }
.desktop-map-selection > p { margin: 4px 0 0; color: #5d746d; font-size: 11px; line-height: 1.5; }
.desktop-map-selection .map-selection-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.desktop-map-selection .map-selection-heading span { color: var(--forest); font-family: serif; font-size: 19px; }
.desktop-map-selection .map-selection-heading small { color: #5d746d; font-size: 10px; }
.desktop-map-selection .map-selection-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px; margin-top: 9px; }
.desktop-map-selection .map-selection-item { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; align-items: center; gap: 7px; min-width: 0; padding: 5px; border: 1px solid rgba(21,60,53,.12); border-radius: 10px; color: var(--ink); background: rgba(255,255,255,.62); text-align: left; }
.desktop-map-selection .map-selection-item:hover, .desktop-map-selection .map-selection-item:focus-visible { border-color: rgba(21,60,53,.4); outline: none; }
.desktop-map-selection .map-selection-item img { width: 34px; height: 34px; border-radius: 7px; object-fit: cover; }
.desktop-map-selection .map-selection-item strong, .desktop-map-selection .map-selection-item small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.desktop-map-selection .map-selection-item strong { font-size: 10px; font-weight: 500; }
.desktop-map-selection .map-selection-item small { margin-top: 2px; color: var(--muted); font-size: 9px; }
.desktop-map-selection .map-selection-item b { color: var(--forest); font-size: 14px; }
.provider-map { position: absolute; inset: 0; z-index: 2; overflow: hidden; border-radius: inherit; background: #dfe7e2; }
.provider-active .map-lines, .provider-active .desktop-region-pins, .provider-active .desktop-map-compass, .provider-active #mobileRegionPins, .provider-active .map-route-line { display: none; }
.map-provider-status { min-height: 15px; color: #5d746d; font-size: 10px; line-height: 1.5; }
.mongolian-leaflet-marker { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 5px; padding: 5px 8px; border: 1px solid rgba(32,59,51,.38); border-radius: 12px; color: var(--forest); background: rgba(255,253,250,.94); box-shadow: 0 7px 16px rgba(32,59,51,.16); font-size: 10px; white-space: nowrap; }
.mongolian-leaflet-marker b { writing-mode: vertical-lr; text-orientation: upright; font-family: "Noto Sans Mongolian", "Mongolian Baiti", sans-serif; font-size: 11px; font-weight: 500; line-height: 1; }
.desktop-map-panel .provider-map { min-height: 310px; }
.news-section { margin-top: 40px; padding-top: 34px; border-top: 1px solid var(--line); }.news-list { display: grid; gap: 0; }.news-row { display: grid; grid-template-columns: 84px minmax(0,1fr) auto; gap: 16px; align-items: center; padding: 16px 0; border-bottom: 1px solid var(--line); }.news-row img { width: 84px; height: 70px; object-fit: cover; border-radius: 12px; filter: saturate(.78); }.news-row span { color: var(--accent); font-size: 10px; }.news-row h3 { margin: 5px 0 4px; font-family: serif; font-size: 18px; font-weight: 400; }.news-row p { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.5; }.news-row time { color: var(--muted); font-size: 10px; white-space: nowrap; }

.recommend-rail { padding-top: 34px; }
.rail-heading h2 { font-size: 24px; }
.recommend-list { display: grid; gap: 22px; margin-top: 24px; }
.recommend-row { display: grid; grid-template-columns: 76px minmax(0,1fr) 20px; gap: 12px; position: relative; align-items: start; }
.recommend-row img { width: 76px; height: 88px; object-fit: cover; border-radius: 10px; filter: saturate(.76); }
.recommend-row h3 { margin-top: 6px; font-size: 15px; }
.recommend-row p { font-size: 11px; }
.recommend-row .save-button { position: static; font-size: 19px; }
.quote-card { margin-top: 38px; padding: 32px 24px; min-height: 188px; display: flex; flex-direction: column; justify-content: space-between; border-radius: var(--radius-lg); color: #f9fbf6; background: linear-gradient(140deg, rgba(17,53,47,.72), rgba(17,53,47,.28)), url('./media/culture-museum.jpeg') center/cover; }
.quote-card p { max-width: 210px; margin: 0; font-family: serif; font-size: 22px; line-height: 1.45; }.quote-card span { font-size: 11px; opacity: .7; }
.explore-meter { margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--line); }.explore-meter span, .explore-meter p { color: var(--muted); font-size: 12px; }.explore-meter strong { color: var(--ink); font-size: 12px; font-weight: 500; }.meter-track { height: 4px; overflow: hidden; margin-top: 12px; border-radius: 4px; background: #dde2dd; }.meter-track span { display: block; height: 100%; width: 42%; background: var(--accent); transition: width 500ms var(--ease); }.explore-meter p { margin: 11px 0 0; font-size: 11px; }

.mobile-feed, .mobile-tabbar { display: none; }
.mobile-screen { display: none; }
.toast { position: fixed; z-index: 20; left: 50%; bottom: 32px; transform: translate(-50%, 12px); opacity: 0; pointer-events: none; padding: 11px 17px; color: #fff; border-radius: 22px; background: rgba(16,34,30,.92); font-size: 13px; transition: opacity 200ms ease, transform 200ms var(--ease); }.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }
.feedback-dialog { width: min(420px, calc(100vw - 32px)); padding: 30px; border: 0; border-radius: 24px; color: var(--ink); background: var(--surface); box-shadow: 0 24px 80px rgba(18,47,42,.22); }.feedback-dialog::backdrop { background: rgba(18,47,42,.32); backdrop-filter: blur(4px); }.dialog-close { position: absolute; z-index: 5; top: 14px; right: 18px; display: grid; place-items: center; width: 38px; height: 38px; padding: 0; border: 1px solid rgba(21,60,53,.14); border-radius: 50%; color: var(--muted); background: rgba(255,255,255,.72); font-size: 21px; line-height: 1; cursor: pointer; transition: color 200ms ease, background 200ms ease, border-color 200ms ease; }
.dialog-close:hover { color: var(--ink); border-color: rgba(21,60,53,.3); background: #fff; }
.dialog-close:focus-visible { outline: 2px solid rgba(195,122,85,.6); outline-offset: 2px; border-radius: 50%; }.dialog-kicker { margin: 0 0 8px; color: var(--accent); font-size: 11px; letter-spacing: .14em; }.feedback-dialog h2 { margin: 0; font-family: serif; font-size: 28px; font-weight: 400; }.feedback-dialog > p:not(.dialog-kicker) { color: var(--muted); font-size: 13px; line-height: 1.6; }.feedback-actions { display: grid; gap: 9px; margin-top: 20px; }.feedback-actions button { min-height: 46px; border: 1px solid var(--line); border-radius: 15px; color: var(--ink); background: #fff; }.feedback-actions button:hover { border-color: var(--forest); background: #f3f6f1; }
.reduce-motion *, .reduce-motion *::before, .reduce-motion *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: .001ms !important; }

@media (max-width: 920px) { .app-shell { grid-template-columns: 82px minmax(0,1fr); }.content-area { padding-inline: 28px; }.desktop-layout { grid-template-columns: minmax(0, 1fr); }.recommend-rail { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; padding-top: 0; }.recommend-list { grid-column: 1 / -1; grid-template-columns: repeat(3, 1fr); }.quote-card, .explore-meter { margin-top: 0; } }

@media (max-width: 680px) {
  html, body { background: #111b19; overflow-x: hidden; }
  .app-shell { display: block; min-height: 100svh; }.side-rail, .desktop-layout, .news-section { display: none; }.content-area { padding: 0; }.topbar { position: absolute; z-index: 4; inset: 0 0 auto; height: 68px; padding: 0 18px; color: #fff; }.mobile-wordmark { display: block; }.search-box { width: 40px; height: 40px; padding: 0; justify-content: center; border: 0; color: #fff; background: rgba(10,20,18,.28); }.search-box input { display: none; }.topbar-actions { gap: 3px; }.icon-button { color: #fff; }.avatar-button { color: var(--forest); background: #f3eee4; }
  .mobile-feed { display: block; height: 100svh; overflow-y: auto; scroll-snap-type: y mandatory; overscroll-behavior-y: contain; }.mobile-feed-card { position: relative; height: 100svh; overflow: hidden; scroll-snap-align: start; isolation: isolate; background: center / cover var(--story-image); }.mobile-feed-card::before { content: ""; position: absolute; inset: 0; z-index: -1; background: center / cover var(--story-image); filter: saturate(.82) contrast(.95); transform: scale(1.015); }.feed-open-button { position: absolute; z-index: 1; top: 115px; right: 86px; left: 15px; bottom: 255px; border: 0; background: transparent; }.feed-shade { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(7,18,16,.35), transparent 32%, rgba(7,18,16,.78) 78%, rgba(7,18,16,.94)); }.feed-copy { position: absolute; left: 22px; right: 100px; bottom: 145px; color: #fff; pointer-events: none; }.feed-copy h2 { margin: 13px 0 7px; font-family: serif; font-size: clamp(32px, 10vw, 52px); font-weight: 400; line-height: 1.02; letter-spacing: .04em; }.feed-copy p { margin: 0; color: rgba(255,255,255,.85); font-family: serif; font-size: 15px; line-height: 1.5; }.feed-credit { display: flex; align-items: center; gap: 9px; margin-top: 22px; font-size: 12px; line-height: 1.45; }.feed-credit small { color: rgba(255,255,255,.68); font-size: 10px; }.credit-avatar { display: grid; place-items: center; width: 29px; height: 29px; border: 1px solid rgba(255,255,255,.72); border-radius: 50%; font-family: serif; }.feed-actions { position: absolute; z-index: 2; right: 17px; bottom: 145px; display: grid; gap: 18px; }.feed-action { display: grid; justify-items: center; gap: 5px; padding: 0; border: 0; color: #fff; background: transparent; text-shadow: 0 1px 12px rgba(0,0,0,.26); }.feed-action b { font-size: 27px; font-weight: 400; line-height: 1; }.feed-action span { font-size: 10px; }.feed-action.is-saved b { color: #f4b49a; }.feed-progress { position: absolute; left: 22px; right: 22px; bottom: 92px; color: rgba(255,255,255,.7); font-size: 11px; }.feed-progress strong { color: #fff; font-weight: 500; }.feed-progress i { display: block; height: 3px; margin-top: 8px; overflow: hidden; border-radius: 4px; background: rgba(255,255,255,.3); }.feed-progress em { display: block; height: 100%; border-radius: 4px; background: #f0b49a; transition: width 500ms var(--ease); }

.mobile-tabbar { position: fixed; z-index: 8; left: 0; right: 0; bottom: 0; display: grid; grid-template-columns: repeat(5, 1fr); height: calc(66px + env(safe-area-inset-bottom)); padding-bottom: env(safe-area-inset-bottom); color: rgba(255,255,255,.62); background: rgba(11,24,21,.92); backdrop-filter: blur(16px); }.mobile-tab { display: grid; place-content: center; justify-items: center; gap: 4px; color: inherit; text-decoration: none; font-size: 20px; }.mobile-tab small { font-size: 10px; }.mobile-tab.is-active { color: #f0b49a; }.toast { bottom: 85px; }.feedback-dialog { margin: auto; padding: 26px 22px; }
}
@media (max-width: 680px) {
  .mobile-feed.is-hidden { display: none; }
  .mobile-screen.is-visible { display: block; min-height: 100svh; padding: 92px 22px 92px; color: var(--ink); background: var(--paper); }
  .mobile-screen-header h1 { margin: 15px 0 11px; font-family: serif; font-size: 39px; font-weight: 400; line-height: 1.05; letter-spacing: .03em; }
  .mobile-screen-header p { max-width: 290px; margin: 0; color: var(--muted); font-size: 13px; line-height: 1.7; }
  .mobile-map-canvas { position: relative; height: 330px; margin: 34px -22px 24px; overflow: hidden; background: radial-gradient(circle at 72% 30%, rgba(255,255,255,.8), transparent 15%), linear-gradient(135deg, transparent 44%, rgba(21,60,53,.18) 44.4%, transparent 45%), linear-gradient(8deg, transparent 53%, rgba(21,60,53,.22) 53.4%, transparent 54%), var(--sky); }
  .mobile-map-canvas::before, .mobile-map-canvas::after { content: ""; position: absolute; border: 1px solid rgba(21,60,53,.28); border-radius: 50%; transform: rotate(-18deg); }
  .mobile-map-canvas::before { width: 420px; height: 210px; left: -32px; top: 72px; }.mobile-map-canvas::after { width: 520px; height: 260px; left: -76px; top: -35px; }
  .map-pin { position: absolute; z-index: 1; display: grid; place-items: center; width: 34px; height: 34px; border: 3px solid var(--forest); border-radius: 50%; color: var(--forest); background: var(--sky); font-family: serif; }.pin-a { left: 28%; top: 33%; }.pin-b { left: 61%; top: 56%; }.pin-c { left: 74%; top: 22%; }.map-route-line { position: absolute; left: 34%; top: 42%; width: 150px; border-top: 1px dashed var(--forest); transform: rotate(25deg); }
  .mobile-destination-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 17px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }.mobile-destination-row small, .route-list span, .route-list small { display: block; color: var(--muted); font-size: 11px; }.mobile-destination-row strong { display: block; margin-top: 4px; font-family: serif; font-size: 19px; font-weight: 400; }
  .mobile-list { display: grid; gap: 20px; margin-top: 30px; }.mobile-guide-row { display: grid; grid-template-columns: 102px minmax(0,1fr) 26px; gap: 13px; align-items: center; padding-bottom: 17px; border-bottom: 1px solid var(--line); }.mobile-guide-row img { width: 102px; height: 112px; object-fit: cover; border-radius: 13px; filter: saturate(.78); }.mobile-guide-row span { color: var(--accent); font-size: 10px; }.mobile-guide-row h2 { margin: 6px 0; font-family: serif; font-size: 18px; font-weight: 400; line-height: 1.2; }.mobile-guide-row p { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.45; }.mobile-guide-row button { padding: 0; border: 0; color: var(--forest); background: transparent; font-size: 20px; }
  .route-highlight { margin-top: 32px; min-height: 290px; padding: 26px; display: flex; flex-direction: column; justify-content: flex-end; border-radius: 23px; color: #fff; background: linear-gradient(0deg, rgba(8,28,24,.8), rgba(8,28,24,.08)), url('./media/culture-museum.jpeg') center/cover; }.route-highlight span { color: #f0b49a; font-size: 11px; }.route-highlight h2 { margin: 10px 0 6px; font-family: serif; font-size: 28px; font-weight: 400; }.route-highlight p { margin: 0 0 18px; color: rgba(255,255,255,.76); font-size: 12px; }.route-highlight .outline-button { align-self: flex-start; }.route-list { display: grid; gap: 6px; margin-top: 23px; padding: 18px 0; border-bottom: 1px solid var(--line); }.route-list strong { font-family: serif; font-size: 20px; font-weight: 400; }.profile-head { display: flex; align-items: center; gap: 13px; }.profile-head h1 { margin: 3px 0 0; font-family: serif; font-size: 30px; font-weight: 400; }.profile-head small { color: var(--muted); font-size: 11px; }.profile-head .icon-button { margin-left: auto; }.profile-avatar { display: grid; place-items: center; width: 50px; height: 50px; border-radius: 50%; color: #fff; background: var(--forest); font-family: serif; font-size: 21px; }.profile-meter { margin-top: 42px; padding: 22px; border-radius: 20px; background: #e9ece5; }.profile-meter > div:first-child { display: flex; justify-content: space-between; }.profile-meter span, .profile-meter p { color: var(--muted); font-size: 12px; }.profile-meter strong { font-size: 13px; font-weight: 500; }.profile-meter .meter-track { margin-top: 17px; }.profile-meter p { margin: 13px 0 0; font-size: 11px; }.profile-links { display: grid; margin-top: 28px; border-top: 1px solid var(--line); }.profile-links button { min-height: 58px; display: flex; justify-content: space-between; padding: 0; border: 0; border-bottom: 1px solid var(--line); color: var(--ink); background: transparent; text-align: left; font-size: 14px; }.profile-links button span { color: var(--muted); }
}

.story-dialog { width: min(560px, calc(100vw - 32px)); padding: 0; overflow: hidden; border: 0; border-radius: 24px; color: var(--ink); background: var(--surface); box-shadow: 0 24px 80px rgba(18,47,42,.24); }.story-dialog::backdrop { background: rgba(18,47,42,.38); backdrop-filter: blur(5px); }.story-dialog > img { width: 100%; max-height: 320px; object-fit: cover; }.story-dialog-copy { padding: 24px; }.story-dialog-copy > span { color: var(--accent); font-size: 11px; }.story-dialog-copy h2 { margin: 9px 0 6px; font-family: serif; font-size: 29px; font-weight: 400; }.story-dialog-copy p { color: var(--muted); font-size: 13px; }.story-dialog-copy .story-dialog-description { margin-top: 16px; color: var(--ink); font-size: 14px; line-height: 1.8; }.story-dialog-copy .dark-button { margin-top: 10px; }
.privacy-dialog { width: min(430px, calc(100vw - 32px)); padding: 29px; border: 0; border-radius: 24px; color: var(--ink); background: var(--surface); box-shadow: 0 24px 80px rgba(18,47,42,.22); }.privacy-dialog::backdrop { background: rgba(18,47,42,.32); backdrop-filter: blur(4px); }.privacy-dialog h2 { margin: 7px 0 10px; font-family: serif; font-size: 27px; font-weight: 400; line-height: 1.2; }.privacy-dialog > p:not(.dialog-kicker) { color: var(--muted); font-size: 13px; line-height: 1.7; }.privacy-dialog > small { display: block; margin-top: 15px; color: #6c706e; font-size: 10px; line-height: 1.5; }.privacy-actions { display: grid; gap: 9px; margin-top: 19px; }.privacy-actions button { min-height: 46px; border: 1px solid var(--line); border-radius: 15px; color: var(--ink); background: #fff; }.privacy-actions .privacy-primary { border-color: var(--forest); color: #fff; background: var(--forest); }
.auth-dialog { width: min(430px, calc(100vw - 32px)); padding: 30px; border: 0; border-radius: 24px; color: var(--ink); background: var(--surface); box-shadow: 0 24px 80px rgba(18,47,42,.22); }.auth-dialog::backdrop { background: rgba(18,47,42,.32); backdrop-filter: blur(4px); }.auth-dialog h2 { margin: 7px 0 20px; font-family: serif; font-size: 27px; font-weight: 400; line-height: 1.2; }.auth-form { display: grid; gap: 12px; }.auth-form label { display: grid; gap: 6px; color: var(--muted); font-size: 12px; }.auth-form input { min-height: 44px; box-sizing: border-box; padding: 0 13px; border: 1px solid var(--line); border-radius: 12px; color: var(--ink); background: #fff; font: inherit; }.auth-form input:focus { outline: 2px solid rgba(47,105,92,.24); border-color: var(--forest); }.auth-form .dark-button { margin-top: 6px; }.auth-status { min-height: 20px; margin: 14px 0 0; color: var(--accent); font-size: 12px; line-height: 1.5; }.auth-switch { margin-top: 12px; padding: 0; }
.story-dialog { max-height: min(88svh, 820px); }.story-dialog-copy { max-height: calc(88svh - 300px); overflow-y: auto; }.story-dialog-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 17px; }.story-dialog-actions .dark-button, .story-dialog-actions .outline-button { min-height: 44px; }.story-vr-link { display: inline-flex; align-items: center; padding: 0 15px; text-decoration: none; }.story-gallery { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 7px; margin-top: 18px; }.story-gallery:empty { display: none; }.story-gallery img { width: 100%; aspect-ratio: 1.25; object-fit: cover; border-radius: 10px; filter: saturate(.82); }.story-interactions { margin-top: 30px; padding-top: 22px; border-top: 1px solid var(--line); }.interaction-heading { display: flex; align-items: end; justify-content: space-between; gap: 12px; }.interaction-heading .dialog-kicker { margin: 0 0 5px; }.interaction-heading h3 { margin: 0; font-family: serif; font-size: 21px; font-weight: 400; }.interaction-count { color: var(--muted); font-size: 11px; }.story-comment-list, .story-question-list { display: grid; gap: 12px; margin-top: 15px; }.story-comment, .story-question { padding: 14px 15px; border-radius: 14px; background: #f3f5f1; }.comment-meta { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 11px; }.comment-meta time { margin-left: auto; color: #6c706e; font-size: 10px; }.comment-meta em { color: var(--accent); font-style: normal; }.story-comment > p, .story-question > p { margin: 9px 0 0; color: var(--ink); font-size: 13px; line-height: 1.65; }.story-reply { margin: 10px 0 0 15px; padding-left: 11px; border-left: 2px solid #d7ded8; }.story-reply span { color: var(--accent); font-size: 10px; }.story-reply p { margin: 4px 0 0; color: var(--muted); font-size: 12px; line-height: 1.55; }.question-answer { color: var(--muted) !important; }.interaction-empty, .interaction-hint, .interaction-status { color: var(--muted); font-size: 12px; line-height: 1.6; }
/* `.interaction-empty` is emitted by app.js and admin.js in 27 places (empty
   moderation queue, no drafts yet, no visits, load failures) and had colour and
   size but no layout at all — so every empty panel showed a bare line of text
   pinned to the top-left of a tall card, which reads as broken rather than as
   "nothing here yet". `:only-child` is the reliable signal that the message is
   the container's whole content. */
.interaction-empty { margin: 0; }
.interaction-empty:only-child { display: grid; place-content: center; min-height: 96px; padding: 16px; text-align: center; }
/* In the dashboard the cards in a grid row stretch to equal height, so an empty
   moderation queue left its message floating in the top third of ~400px of
   blank space. Making the card a column and letting the list take the slack
   centres the message in the space the panel actually occupies. `:has()` only
   gates the centring, so an unsupported engine degrades to the old position. */
.admin-dashboard-grid > .admin-card { display: flex; flex-direction: column; }
.admin-dashboard-grid > .admin-card > .admin-dashboard-list { flex: 1 1 auto; min-height: 0; }
.admin-dashboard-grid > .admin-card > .admin-dashboard-list:has(> .interaction-empty:only-child) { align-content: center; }
.admin-card .interaction-empty:only-child { min-height: 0; }.interaction-hint { margin: 14px 0 0; }.story-submit-form { display: grid; gap: 9px; margin-top: 13px; }.story-submit-form textarea, .reply-submit-form textarea { width: 100%; box-sizing: border-box; padding: 11px 12px; resize: vertical; border: 1px solid var(--line); border-radius: 12px; color: var(--ink); background: #fff; font: inherit; font-size: 12px; line-height: 1.55; }.story-submit-form textarea:focus, .reply-submit-form textarea:focus { outline: 2px solid rgba(47,105,92,.24); border-color: var(--forest); }.story-submit-form .dark-button { justify-self: start; min-height: 42px; padding-inline: 16px; }.reply-submit-form { display: flex; align-items: end; gap: 8px; margin: 12px 0 0 15px; }.reply-submit-form textarea { min-width: 0; min-height: 38px; }.reply-submit-form .text-button { min-height: 38px; }.interaction-status { min-height: 20px; margin: 17px 0 0; color: var(--accent); }.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; }
.story-reader-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 14px 0 8px; padding: 9px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); color: var(--muted); font-size: 11px; }.story-reader-toolbar .text-button { min-height: 36px; }.story-dialog.is-reading .story-dialog-description, .story-dialog.is-reading .story-dialog-documents, .story-dialog.is-reading .story-gallery, .story-dialog.is-reading .story-dialog-actions, .story-dialog.is-reading .story-interactions { display: none; }.story-dialog.is-reading .story-dialog-rich { margin-top: 0; }.story-dialog-rich .reader-loading, .story-dialog-rich .reader-empty, .story-dialog-rich .reader-error { padding: 22px 0; color: var(--muted); }.story-dialog-rich .reader-error strong { color: var(--ink); }.story-dialog-rich .reader-error p { margin-top: 8px; }
.vr-viewer { margin-top: 17px; padding: 13px; border: 1px solid var(--line); border-radius: 16px; background: #102823; }.vr-viewer-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; color: #f5f6ef; font-size: 12px; }.vr-viewer-head .text-button { color: rgba(255,255,255,.72); }.vr-frame { min-height: 360px; overflow: hidden; border-radius: 10px; background: #0b1714; }.vr-frame iframe { display: block; width: 100%; min-height: 360px; border: 0; }.vr-viewer-status { margin: 9px 0 0; color: rgba(255,255,255,.66); font-size: 10px; line-height: 1.5; }.vr-viewer-fallback { margin-top: 12px; padding: 13px; border-radius: 11px; color: #fff; background: rgba(255,255,255,.1); }.vr-viewer-fallback strong { font-size: 12px; }.vr-viewer-fallback p { margin: 6px 0 11px; color: rgba(255,255,255,.72); font-size: 11px; line-height: 1.5; }.vr-viewer-fallback .outline-button { min-height: 38px; padding-inline: 14px; color: #fff; font-size: 11px; }
@media (max-width: 680px) { .vr-viewer { margin-inline: -2px; }.vr-frame, .vr-frame iframe { min-height: min(62svh, 420px); }.vr-viewer::after { content: '横屏体验 VR 效果更好'; display: block; margin-top: 8px; color: rgba(255,255,255,.48); font-size: 10px; } }

/* Scenic detail: a calm, image-led sheet on mobile and a spacious reader on desktop. */
.story-dialog { width: min(760px, calc(100vw - 32px)); max-height: min(90svh, 900px); }
.story-dialog-hero { position: relative; height: clamp(240px, 34vw, 370px); overflow: hidden; background: #18352e; }
.story-dialog-hero.has-source-thumbnail { background: #102823 center / cover var(--story-image); }
.story-dialog-hero.has-source-thumbnail::before { content: ""; position: absolute; z-index: 0; inset: -26px; background: center / cover var(--story-image); filter: blur(26px) saturate(.82) brightness(.66); }
.story-dialog-hero::after { content: ""; position: absolute; z-index: 2; inset: 0; pointer-events: none; background: linear-gradient(180deg, rgba(9,28,24,.52), transparent 32%, rgba(9,28,24,.12)); }
.story-dialog-hero > img { position: relative; z-index: 1; display: block; width: 100%; height: 100%; max-height: none; object-fit: cover; filter: saturate(.88); }
.story-dialog-hero > img.is-source-thumbnail { object-fit: contain; background: transparent; filter: saturate(.94) drop-shadow(0 12px 34px rgba(6,20,17,.42)); }
.story-dialog-topbar { position: absolute; z-index: 3; top: 16px; left: 18px; right: 18px; display: flex; align-items: center; justify-content: space-between; gap: 12px; color: #fff; }
.story-dialog-brand { font-family: serif; font-size: 14px; letter-spacing: .12em; text-shadow: 0 1px 12px rgba(0,0,0,.28); }
.story-dialog-top-actions { display: flex; gap: 8px; }
.story-top-button { display: grid; place-items: center; width: 38px; height: 38px; padding: 0; border: 1px solid rgba(255,255,255,.32); border-radius: 50%; color: #fff; background: rgba(8,29,25,.35); backdrop-filter: blur(12px); font-size: 21px; line-height: 1; }
.story-top-button:hover, .story-top-button:focus-visible { background: rgba(8,29,25,.65); outline: 2px solid rgba(255,255,255,.7); outline-offset: 2px; }
.story-dialog > .dialog-close { display: none; }
.story-dialog-copy { max-height: calc(90svh - clamp(240px, 34vw, 370px)); padding: 24px 30px 30px; overflow-y: auto; overscroll-behavior: contain; }
.story-sheet-handle { display: none; }
.story-location-row { display: flex; align-items: center; gap: 8px; margin-top: 13px; color: var(--muted); font-size: 11px; }
.story-location-mark { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; color: var(--accent); background: #efe5d4; font-size: 14px; }
.story-dialog-actions { align-items: stretch; }
.story-dialog-actions .dark-button { flex: 0 0 auto; }
.story-vr-link { min-width: 218px; justify-content: center; border-color: #cf9e72; color: #4e2c20; background: linear-gradient(135deg, #f2d2a9, #e8b984); box-shadow: 0 10px 24px rgba(180,111,65,.16); font-weight: 600; }
.story-vr-link:hover, .story-vr-link:focus-visible { border-color: #b9794e; color: #3f251c; background: #f4c995; transform: translateY(-1px); }
.story-vr-external { align-self: center; }

@media (max-width: 680px) {
  .story-dialog { inset: auto 0 0; margin: 0; width: 100%; max-width: none; max-height: 94svh; border-radius: 28px 28px 0 0; }
  .story-dialog-hero { height: min(37svh, 310px); min-height: 226px; }
  .story-dialog-topbar { top: 14px; left: 16px; right: 16px; }
  .story-dialog-copy { max-height: calc(94svh - min(37svh, 310px)); padding: 0 20px calc(22px + env(safe-area-inset-bottom)); }
  .story-sheet-handle { display: block; width: 42px; height: 4px; margin: 11px auto 18px; border-radius: 99px; background: #c9c9bd; }
  .story-dialog-copy h2 { margin-top: 8px; font-size: clamp(25px, 7vw, 31px); line-height: 1.16; }
  .story-dialog-copy .story-dialog-description { margin-top: 14px; font-size: 14px; line-height: 1.75; }
  .story-dialog-actions { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 9px; margin-top: 19px; }
  .story-dialog-actions .dark-button { min-height: 46px; }
  .story-vr-link { grid-column: 1 / -1; order: -1; min-width: 0; min-height: 52px !important; border-radius: 15px; font-size: 13px; }
  .story-vr-external { justify-self: end; }
  .story-dialog-actions #storyDialogMap { justify-self: start; align-self: center; }
  .story-gallery { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@keyframes breathe { 0%,100% { transform: translateY(0); opacity: .45; } 50% { transform: translateY(-4px); opacity: 1; } }

@media (max-width: 680px) {
  .mobile-feed-card.is-source-thumbnail { background: #29483f; }
  .mobile-feed-card.is-source-thumbnail::before { background: radial-gradient(circle at 50% 36%, rgba(255,255,255,.18), transparent 38%), linear-gradient(160deg, #40695d, #102823); filter: none; transform: none; }
  .feed-media { display: none; }
  .mobile-feed-card.is-source-thumbnail .feed-media { position: absolute; inset: 0; z-index: -1; display: block; width: 100%; height: 100%; object-fit: contain; object-position: center 38%; opacity: .96; }
}

@media (max-width: 680px) {
  .feed-action { min-width: 48px; min-height: 48px; }
  .feed-reward { position: absolute; right: 22px; bottom: 59px; display: flex; align-items: center; gap: 6px; padding: 6px 10px; border: 1px solid rgba(255,255,255,.22); border-radius: 999px; color: rgba(255,255,255,.88); background: rgba(13,29,25,.36); backdrop-filter: blur(10px); font-size: 10px; letter-spacing: .04em; animation: reward-pop 560ms var(--ease) both; }
  .feed-reward span { color: #f0b49a; font-size: 13px; }
}

@keyframes reward-pop { from { opacity: 0; transform: translateY(5px) scale(.96); } to { opacity: 1; transform: translateY(0) scale(1); } }

.article-open { position: relative; cursor: pointer; transition: background 180ms ease; }.article-open:hover, .article-open:focus-within { background: #f3f6f1; }
/* Full-bleed real button keeps the row keyboard and screen-reader friendly
   without putting role="button" on an <article>, which ARIA does not allow. */
.row-open-button { position: absolute; z-index: 1; inset: 0; padding: 0; border: 0; border-radius: inherit; background: transparent; cursor: pointer; }
.row-open-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.article-arrow { color: var(--forest); font-size: 20px; }.story-dialog-rich { margin-top: 18px; color: var(--ink); font-size: 14px; line-height: 1.85; }.story-dialog-rich p { margin: 0 0 12px; }.story-dialog-rich h2, .story-dialog-rich h3, .story-dialog-rich h4 { margin: 19px 0 9px; font-family: serif; font-weight: 400; line-height: 1.3; }.story-dialog-rich img { max-width: 100%; height: auto; border-radius: 12px; }.story-dialog-rich a, .story-dialog-documents a { color: var(--forest); }.story-dialog-documents { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 15px; font-size: 12px; }.story-dialog-documents a { padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; text-decoration: none; }.article-dialog-author { margin: 20px 0 0; color: var(--muted); font-size: 11px; }
.admin-page { min-height: 100svh; color: var(--ink); background: var(--paper); }.admin-topbar { display: flex; align-items: center; justify-content: space-between; gap: 20px; min-height: 72px; padding: 0 clamp(22px, 6vw, 84px); border-bottom: 1px solid var(--line); background: rgba(250,249,245,.9); }.admin-topbar > div { display: flex; align-items: center; gap: 18px; color: var(--muted); font-size: 12px; }.admin-back { color: var(--forest); text-decoration: none; }.admin-main { width: min(980px, calc(100% - 44px)); margin: 0 auto; padding: 72px 0 100px; }.admin-intro h1 { margin: 12px 0 10px; font-family: serif; font-size: clamp(40px, 6vw, 64px); font-weight: 400; letter-spacing: .03em; }.admin-intro p { max-width: 480px; color: var(--muted); font-size: 14px; line-height: 1.7; }.admin-status { min-height: 20px; margin: 32px 0 14px; color: var(--accent); font-size: 12px; }.admin-status[data-tone="error"] { color: #a65b4d; }.admin-panel { padding: 24px; border: 1px solid var(--line); border-radius: 22px; background: rgba(255,255,255,.64); }.admin-tabs { display: flex; gap: 8px; padding-bottom: 17px; border-bottom: 1px solid var(--line); }.admin-tabs button { min-height: 40px; padding: 0 15px; border: 1px solid transparent; border-radius: 999px; color: var(--muted); background: transparent; font: inherit; font-size: 12px; }.admin-tabs button.is-active { border-color: var(--forest); color: #fff; background: var(--forest); }.moderation-queue { display: grid; gap: 12px; margin-top: 18px; }.moderation-item { padding: 17px; border: 1px solid var(--line); border-radius: 16px; background: #fff; }.moderation-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 9px; color: var(--muted); font-size: 11px; }.moderation-meta span:first-child { color: var(--ink); font-weight: 500; }.moderation-meta time { margin-left: auto; color: #6c706e; font-size: 10px; }.moderation-content { margin: 12px 0 0; color: var(--ink); font-size: 14px; line-height: 1.7; white-space: pre-wrap; }.moderation-answer { color: var(--muted); font-size: 12px; line-height: 1.6; }.admin-item-actions { display: flex; gap: 8px; margin-top: 15px; }.admin-item-actions .dark-button, .admin-item-actions .outline-button { min-height: 38px; padding-inline: 14px; }.admin-answer-form { display: grid; gap: 9px; margin-top: 15px; }.admin-answer-form textarea { width: 100%; box-sizing: border-box; padding: 11px 12px; resize: vertical; border: 1px solid var(--line); border-radius: 12px; font: inherit; font-size: 12px; }.admin-answer-form .dark-button { justify-self: start; min-height: 40px; padding-inline: 15px; }
.admin-main { width: min(1180px, calc(100% - 64px)); }
.admin-panel { box-shadow: 0 14px 38px rgba(32,59,51,.06); }
.admin-workspace-tabs, .admin-tabs { flex-wrap: wrap; }
.content-queue { display: grid; gap: 10px; margin-top: 18px; }
.content-item { display: grid; grid-template-columns: minmax(0,1fr) auto; align-items: center; gap: 18px; padding: 16px 18px; border: 1px solid var(--line); border-radius: 15px; background: #fff; }
.content-item h3 { margin: 0 0 5px; font-family: serif; font-size: 18px; font-weight: 400; }
.content-item p { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.5; }
.site-footer { display: flex; align-items: end; justify-content: space-between; gap: 28px; margin: 0 auto; padding: 54px clamp(22px, 6vw, 84px) 34px; color: var(--muted); border-top: 1px solid var(--line); background: var(--paper); }.site-footer small { font-size: 10px; }.related-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px; }.related-links a { color: var(--forest); font-size: 12px; text-decoration: none; }.related-links a:hover { color: var(--accent); }

.admin-workspace-tabs { display: flex; gap: 8px; margin: 28px 0 14px; }.admin-workspace-tabs button { min-height: 42px; padding: 0 17px; border: 1px solid var(--line); border-radius: 999px; color: var(--muted); background: transparent; font: inherit; font-size: 12px; }.admin-workspace-tabs button.is-active { border-color: var(--forest); color: #fff; background: var(--forest); }
.admin-page { background: radial-gradient(circle at 80% 0%, #fff 0, var(--paper) 42%, #edf1ec 100%); }
.admin-topbar { min-height: 78px; border: 0; background: rgba(255,253,250,.78); box-shadow: 0 1px 0 rgba(32,59,51,.08), 0 10px 30px rgba(32,59,51,.04); backdrop-filter: blur(18px); }
.admin-topbar .brand-mark { writing-mode: horizontal-tb; display: flex; flex-direction: row; gap: 10px; font-size: 15px; letter-spacing: .14em; }
.admin-topbar .brand-dot { width: 22px; height: 22px; border-color: var(--forest); }
.admin-topbar .brand-dot::after { background: var(--accent); }
.admin-topbar > div { gap: 14px; }
.admin-back { padding: 9px 13px; border: 1px solid var(--line); border-radius: 999px; background: rgba(255,255,255,.6); transition: transform 220ms ease, box-shadow 220ms ease, border-color 220ms ease; }
.admin-back:hover { border-color: rgba(32,59,51,.35); box-shadow: 0 8px 20px rgba(32,59,51,.08); transform: translateY(-1px); }
.admin-panel { border-color: rgba(32,59,51,.1); background: rgba(255,255,255,.72); backdrop-filter: blur(16px); }
.admin-workspace-tabs button, .admin-tabs button { transition: transform 220ms ease, background 220ms ease, border-color 220ms ease; }
.admin-workspace-tabs button:hover, .admin-tabs button:hover { transform: translateY(-1px); }
.content-toolbar { display: flex; align-items: end; flex-wrap: wrap; gap: 10px; padding-bottom: 18px; border-bottom: 1px solid var(--line); }.content-toolbar label { display: grid; gap: 6px; color: var(--muted); font-size: 11px; }.content-toolbar select, .content-toolbar input { min-height: 40px; box-sizing: border-box; padding: 0 11px; border: 1px solid var(--line); border-radius: 10px; color: var(--ink); background: #fff; font: inherit; font-size: 12px; }.content-toolbar select { min-width: 120px; }.content-search { min-width: min(280px, 100%); flex: 1; }.admin-small-button { min-height: 40px; padding-inline: 15px; }
.content-queue { display: grid; gap: 10px; margin-top: 18px; }.content-item { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 16px 17px; border: 1px solid var(--line); border-radius: 15px; background: #fff; }.content-item h3 { margin: 5px 0 4px; font-family: serif; font-size: 18px; font-weight: 400; }.content-item p { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.5; }.content-item-kind { color: var(--accent); font-size: 10px; letter-spacing: .08em; }.content-item-actions { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }.danger-button { color: #a65b4d; }
.content-editor-dialog { width: min(700px, calc(100vw - 32px)); max-height: min(88svh, 900px); overflow-y: auto; padding: 30px; border: 0; border-radius: 24px; color: var(--ink); background: var(--surface); box-shadow: 0 24px 80px rgba(18,47,42,.25); }.content-editor-dialog::backdrop { background: rgba(18,47,42,.38); backdrop-filter: blur(5px); }.content-editor-dialog h2 { margin: 7px 0 22px; font-family: serif; font-size: 29px; font-weight: 400; }.content-editor-form { display: grid; gap: 13px; }.content-editor-form label { display: grid; gap: 6px; color: var(--muted); font-size: 12px; }.content-editor-form input, .content-editor-form textarea { width: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid var(--line); border-radius: 11px; color: var(--ink); background: #fff; font: inherit; font-size: 12px; line-height: 1.55; }.content-editor-form textarea { resize: vertical; }.content-editor-form input:focus, .content-editor-form textarea:focus, .content-toolbar input:focus, .content-toolbar select:focus { outline: 2px solid rgba(47,105,92,.24); border-color: var(--forest); }.editor-check { display: flex !important; align-items: center; gap: 8px !important; }.editor-check input { width: 17px; height: 17px; }.editor-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }.editor-record-id { margin: -9px 0 0; color: #6c706e; font-size: 10px; }.editor-form-actions { display: flex; gap: 10px; margin-top: 6px; }.editor-form-actions .dark-button, .editor-form-actions .outline-button { min-height: 42px; padding-inline: 17px; }
.content-editor-dialog { width: min(920px, calc(100vw - 32px)); }
.rich-editor { display: grid; gap: 10px; padding: 14px; border: 1px solid var(--line); border-radius: 16px; background: #fbfcf8; }
.rich-editor-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.rich-editor-heading strong, .rich-editor-heading small { display: block; }.rich-editor-heading strong { color: var(--ink); font-size: 13px; }.rich-editor-heading small { margin-top: 3px; color: var(--muted); font-size: 10px; }
.template-select { display: flex !important; align-items: center; gap: 7px !important; white-space: nowrap; }.template-select select { padding: 7px 8px; border: 1px solid var(--line); border-radius: 9px; color: var(--forest); background: #fff; font: inherit; font-size: 11px; }
.rich-toolbar { display: flex; flex-wrap: wrap; gap: 5px; padding: 7px; border: 1px solid var(--line); border-radius: 11px; background: #fff; }.rich-toolbar button { min-height: 28px; padding: 0 9px; border: 1px solid transparent; border-radius: 7px; color: var(--ink); background: transparent; font: inherit; font-size: 11px; cursor: pointer; }.rich-toolbar button:hover, .rich-toolbar button:focus-visible { border-color: #cbd8cf; color: var(--forest); background: #edf4ef; outline: none; }.rich-toolbar span { flex: 1 1 auto; }
.rich-editor-surface { min-height: 300px; padding: 18px 20px; border: 1px solid var(--line); border-radius: 12px; outline: none; color: var(--ink); background: #fff; font-size: 14px; line-height: 1.85; }.rich-editor-surface:empty::before { content: attr(data-placeholder); color: #a7aea7; }.rich-editor-surface:focus { border-color: var(--forest); box-shadow: 0 0 0 3px rgba(23,63,55,.1); }.rich-editor-surface h2, .rich-editor-surface h3 { margin: 12px 0 6px; font-family: serif; font-weight: 500; }.rich-editor-surface p { margin: 0 0 12px; }.rich-editor-surface a { color: var(--forest); text-decoration: underline; }.rich-editor-surface img { display: block; max-width: 100%; height: auto; border-radius: 10px; cursor: grab; }.rich-editor-surface img:active { cursor: grabbing; }.rich-image-block { width: fit-content; max-width: 100%; padding: 5px; border: 1px dashed transparent; border-radius: 12px; cursor: grab; }.rich-image-block:hover { border-color: #d4a888; background: #fffaf5; }.rich-image-block small { display: block; color: #a8a095; font-size: 10px; }
.admin-map-picker-wrap { display: grid; gap: 10px; padding: 16px; border: 1px solid #dce4dc; border-radius: 16px; background: linear-gradient(145deg, #fbfdf9, #f2f6f1); }.admin-map-picker-wrap > div:first-child { display: grid; gap: 3px; }.admin-map-picker-wrap strong { color: var(--forest); font-family: serif; font-size: 17px; font-weight: 500; }.admin-map-picker-wrap small, .admin-map-picker-actions span { color: var(--muted); font-size: 11px; line-height: 1.5; }.admin-map-picker { height: 280px; overflow: hidden; border: 1px solid #cddbd2; border-radius: 12px; background: #dce8e8; }.admin-map-picker-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }.admin-map-picker-actions .outline-button { min-height: 34px; padding-inline: 12px; }.editor-password-toggle { justify-self: end; min-height: 30px; margin-top: 7px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; color: var(--forest); background: #fff; font: inherit; font-size: 11px; cursor: pointer; }.draft-preview { display: grid; gap: 12px; }.draft-preview h3 { margin: 0; color: var(--ink); font-family: serif; font-size: 24px; font-weight: 500; }.draft-preview-content { max-height: 46svh; margin: 0; overflow: auto; padding: 16px; border: 1px solid var(--line); border-radius: 12px; color: var(--ink); background: #fbfcf8; white-space: pre-wrap; font: 13px/1.75 ui-sans-serif, system-ui, sans-serif; }
@media (max-width: 680px) { .admin-main { width: min(100% - 32px, 980px); padding-top: 42px; }.content-item { align-items: flex-start; flex-direction: column; }.content-item-actions { width: 100%; justify-content: flex-start; }.content-toolbar { align-items: stretch; flex-direction: column; }.content-toolbar label, .content-search { min-width: 0; }.admin-small-button { align-self: flex-start; }.content-editor-dialog { padding: 24px 20px; }.editor-grid { grid-template-columns: 1fr; }.rich-editor-heading { align-items: flex-start; flex-direction: column; }.template-select { width: 100%; }.template-select select { flex: 1; }.rich-editor-surface { min-height: 260px; padding: 14px; } }

/* Admin-only redesign: intentionally scoped to .admin-page. */
.admin-page { background: #f7f6f2; color: #262321; }
.admin-page { --admin-forest: #173f37; --admin-forest-deep: #10332d; --admin-terracotta: #c47552; --admin-paper: #f7f6f0; --admin-ink: #24332f; }
.admin-page .admin-sidebar { background: linear-gradient(180deg, var(--admin-forest) 0%, var(--admin-forest-deep) 100%); box-shadow: 10px 0 32px rgba(16,51,45,.14); }
.admin-page .admin-brand-seal { color: #f5e8d7; border-color: rgba(245,232,215,.75); }
.admin-page .admin-nav button { color: rgba(245,248,242,.78); }
.admin-page .admin-nav button:hover { color: #fff; background: rgba(255,255,255,.10); }
.admin-page .admin-nav button.is-active { color: var(--admin-forest); background: #f7f2e9; box-shadow: 0 10px 24px rgba(7,34,29,.16); }
.admin-page .admin-nav button.is-active i { color: var(--admin-terracotta); }
.admin-page .admin-nav-count { color: #f4d8c2; }
.admin-page .admin-sidebar-bottom button, .admin-page .admin-platform-link { color: rgba(245,248,242,.78); }
.admin-page .admin-platform-link { border-color: rgba(245,248,242,.20); }
.admin-page .admin-main { background: radial-gradient(circle at 78% 0%, rgba(222,235,225,.46), transparent 35%), var(--admin-paper); }
.admin-page .admin-topbar { background: rgba(255,255,255,.78); }
.admin-page .admin-intro h1 { color: var(--admin-forest); }
.admin-page .admin-eyebrow { color: var(--admin-terracotta); }
.admin-page .admin-status { color: var(--admin-terracotta); }
.admin-page .admin-status[data-tone="error"] { color: #a8644e; background: transparent; }
.admin-page .admin-workspace-tabs button.is-active, .admin-page .admin-tabs button.is-active { border-color: var(--admin-forest); background: var(--admin-forest); }
.admin-page .dark-button { background: var(--admin-forest); }
.admin-page .dark-button:hover { background: #245b4e; }
.admin-page .outline-button, .admin-page .admin-link-button { color: var(--admin-forest); }
.admin-page .content-item-kind { color: var(--admin-terracotta); }
.admin-page .admin-stat-icon { color: var(--admin-terracotta); background: #f1e2d8; }
.admin-shell { display: grid; grid-template-columns: 244px minmax(0, 1fr); min-height: 100svh; }
.admin-sidebar { display: flex; flex-direction: column; padding: 28px 16px 20px; color: #fff; background: linear-gradient(180deg, #8f302d 0%, #762824 72%, #65231f 100%); box-shadow: 10px 0 32px rgba(77,27,23,.12); }
/* The sidebar used to stretch with the page, so the 系统设置 / 返回内容平台 block
   (pushed down by margin-top:auto) drifted to the bottom of the document and only
   appeared when the current panel happened to be short. Pinning it to the viewport
   keeps those global actions reachable from every panel. */
@media (min-width: 681px) {
  .admin-sidebar { position: sticky; top: 0; align-self: start; height: 100svh; max-height: 100svh; overflow: hidden; }
  /* Only the nav list scrolls on short viewports, so the brand and the
     系统设置 / 返回内容平台 block stay pinned and reachable. */
  /* `align-content: start` is required, not cosmetic. `.admin-nav` is a grid
     that stretches to fill the sidebar, and a grid's default `align-content`
     behaves as `stretch`, so the implicit rows grew to fill the whole column:
     each 46px nav button measured ~150px with ~100px of dead space between
     them. `start` keeps the rows at their intrinsic height. */
  .admin-nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
  .admin-sidebar-bottom { flex: 0 0 auto; }
}
.admin-brand { display: flex; align-items: center; gap: 12px; padding: 0 12px 30px; color: #fff; text-decoration: none; }
.admin-brand-seal { display: grid; place-items: center; width: 37px; height: 37px; border: 1px solid rgba(255,231,197,.65); border-radius: 50%; color: #f4d9b6; font-family: serif; font-size: 20px; }
.admin-brand strong, .admin-brand small { display: block; }.admin-brand strong { font-family: serif; font-size: 20px; font-weight: 500; letter-spacing: .12em; }.admin-brand small { margin-top: 4px; color: rgba(255,244,225,.72); font-size: 10px; letter-spacing: .08em; }
.admin-nav { display: grid; gap: 6px; align-content: start; }.admin-nav button, .admin-sidebar-bottom button { display: flex; align-items: center; gap: 13px; width: 100%; min-height: 46px; padding: 0 14px; border: 0; border-radius: 10px; color: rgba(255,249,237,.82); background: transparent; font: inherit; font-size: 13px; text-align: left; cursor: pointer; transition: background .2s ease, transform .2s ease, color .2s ease; }.admin-nav button:hover, .admin-sidebar-bottom button:hover { color: #fff; background: rgba(255,255,255,.1); transform: translateX(2px); }.admin-nav button.is-active { color: #762824; background: #fff9f1; box-shadow: 0 8px 18px rgba(62,20,17,.14); }.admin-nav-icon, .admin-nav i { width: 18px; color: inherit; font-size: 20px; font-style: normal; line-height: 1; text-align: center; }.admin-nav-count { margin-left: auto; color: #f4cf9d; font-size: 11px; }.admin-nav button.is-active .admin-nav-count { color: #9a3732; }.admin-sidebar-bottom { display: grid; gap: 10px; margin-top: auto; }.admin-platform-link { display: flex; justify-content: space-between; padding: 18px 14px 0; border-top: 1px solid rgba(255,255,255,.18); color: rgba(255,249,237,.7); font-size: 11px; text-decoration: none; }
.admin-main { min-width: 0; width: auto; margin: 0; padding: 0; }.admin-topbar { min-height: 68px; padding: 0 42px; border-bottom: 1px solid #ebe7df; background: rgba(255,255,255,.88); }.admin-topbar > div { font-size: 12px; }.admin-mobile-title { display: none; }.admin-breadcrumb { color: #9d9890; }.admin-breadcrumb strong { color: #4b4743; font-weight: 500; }.admin-top-actions { gap: 16px; }.admin-search { display: flex; align-items: center; gap: 8px; width: min(300px, 30vw); height: 34px; padding: 0 12px; border: 1px solid #e5e0d7; border-radius: 18px; color: #9a9187; background: #fff; }.admin-search input { min-width: 0; width: 100%; border: 0; outline: 0; background: transparent; font: inherit; font-size: 11px; }.admin-icon-button { border: 0; color: #8f302d; background: transparent; font-size: 21px; cursor: pointer; }.admin-user-avatar { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; color: #fff; background: #a67a57; font-size: 12px; }.admin-content { max-width: 1260px; margin: 0 auto; padding: 42px 42px 80px; }.admin-intro { display: flex; align-items: end; justify-content: space-between; gap: 20px; padding: 0 6px 26px; }.admin-eyebrow { margin: 0 0 8px; color: #a68b69; font-size: 10px; letter-spacing: .18em; }.admin-intro h1 { margin: 0 0 8px; color: #74302a; font-family: serif; font-size: clamp(34px, 4vw, 50px); font-weight: 500; letter-spacing: .04em; }.admin-intro p:last-child { margin: 0; color: #948e85; font-size: 13px; }.admin-date { color: #aaa29a; font-size: 12px; }.admin-date span { margin: 0 8px; color: #c59c69; }.admin-status { margin: 0 0 12px; min-height: 18px; color: #9a3732; font-size: 12px; }
.admin-stat-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 16px; }.admin-stat-card { display: flex; align-items: center; gap: 13px; min-height: 112px; padding: 18px; border: 1px solid #eee9e0; border-radius: 16px; background: #fff; box-shadow: 0 10px 24px rgba(87,61,40,.05); }.admin-stat-icon { display: grid; place-items: center; flex: 0 0 auto; width: 45px; height: 45px; border-radius: 50%; color: #9a3732; background: #f7eae4; font-size: 22px; }.admin-stat-icon.gold { color: #a87b2d; background: #f6eddc; }.admin-stat-icon.jade { color: #718577; background: #e8f0ea; }.admin-stat-icon.rose { color: #a66e62; background: #f3e9e6; }.admin-stat-card div { min-width: 0; }.admin-stat-card small, .admin-stat-card em { display: block; color: #9c958c; font-size: 11px; font-style: normal; }.admin-stat-card strong { display: block; margin: 3px 0; color: #282421; font-family: Georgia,serif; font-size: 28px; font-weight: 500; }.admin-stat-card b { margin-left: auto; color: #b9a898; font-size: 22px; font-weight: 400; }
.admin-dashboard-grid { display: grid; grid-template-columns: minmax(0,1.35fr) minmax(300px,.9fr); gap: 16px; margin-top: 16px; }.admin-card { min-width: 0; min-height: 210px; padding: 22px; border: 1px solid #eee9e0; border-radius: 17px; background: #fff; box-shadow: 0 10px 24px rgba(87,61,40,.04); }.admin-card-wide { min-height: 250px; }.admin-card-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 17px; }.admin-card-heading h2 { margin: 0; color: #332d29; font-family: serif; font-size: 20px; font-weight: 500; }.admin-link-button { padding: 0; border: 0; color: #9a6f57; background: transparent; font: inherit; font-size: 11px; cursor: pointer; }.admin-dashboard-list { display: grid; gap: 0; }.dashboard-row { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 18px; min-height: 48px; border-top: 1px solid #f1ede7; color: #5e5853; font-size: 12px; }.dashboard-row strong { overflow: hidden; color: #39332f; font-weight: 500; text-overflow: ellipsis; white-space: nowrap; }.dashboard-row small { color: #aca39a; }.dashboard-row button { padding: 6px 10px; border: 1px solid #e7c9b7; border-radius: 6px; color: #a14d3f; background: #fffaf7; font: inherit; font-size: 11px; cursor: pointer; }.admin-map-preview { position: relative; min-height: 210px; overflow: hidden; border-radius: 12px; background: linear-gradient(140deg,#e8eee7,#f5f1e8 50%,#dfebe9); }.admin-map-preview::before, .admin-map-preview::after { position: absolute; content: ''; border: 2px solid rgba(112,145,130,.27); border-radius: 50%; transform: rotate(-18deg); }.admin-map-preview::before { inset: 24px -30px 52px 34px; }.admin-map-preview::after { inset: 70px 42px 15px -38px; }.map-pin { position: absolute; z-index: 1; display: grid; place-items: center; width: 25px; height: 25px; border: 5px solid rgba(255,255,255,.8); border-radius: 50%; color: #fff; background: #a43f38; box-shadow: 0 4px 9px rgba(86,44,37,.22); font-size: 12px; }.pin-a { top: 35px; left: 34%; }.pin-b { top: 100px; left: 62%; }.pin-c { top: 132px; left: 24%; background: #708978; }.map-preview-label { position: absolute; z-index: 2; right: 16px; bottom: 14px; display: grid; gap: 4px; padding: 12px 14px; border: 1px solid rgba(255,255,255,.7); border-radius: 10px; background: rgba(255,255,255,.9); box-shadow: 0 8px 18px rgba(72,81,65,.1); }.map-preview-label strong { color: #54322c; font-family: serif; font-size: 15px; }.map-preview-label small { color: #a28f7b; font-size: 10px; }.admin-activity-list { display: grid; gap: 16px; margin: 3px 0 0; padding: 0; list-style: none; }.admin-activity-list li { display: grid; grid-template-columns: 9px 1fr auto; align-items: center; gap: 10px; color: #69615a; font-size: 11px; }.admin-activity-list time { color: #b1a9a1; }.activity-dot { width: 8px; height: 8px; border-radius: 50%; background: #9a3732; }.activity-dot.gold { background: #bb9461; }.activity-dot.jade { background: #7a9482; }.admin-workspace-tabs { margin-top: 30px; }.admin-workspace-tabs button { border-radius: 8px; }.admin-panel { background: #fff; }
@media (max-width: 980px) { .admin-shell { grid-template-columns: 76px minmax(0,1fr); }.admin-sidebar { padding-inline: 10px; }.admin-brand { justify-content: center; padding-inline: 0; }.admin-brand > span:last-child, .admin-nav button:not(.is-active)::after, .admin-nav button, .admin-sidebar-bottom button { font-size: 0; }.admin-nav button, .admin-sidebar-bottom button { justify-content: center; padding-inline: 0; }.admin-nav i { font-size: 20px; }.admin-platform-link { justify-content: center; font-size: 0; }.admin-platform-link span { font-size: 17px; }.admin-brand-seal { width: 40px; height: 40px; }.admin-stat-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 680px) { .admin-shell { display: block; }.admin-sidebar { position: fixed; z-index: 5; right: 0; bottom: 0; left: 0; display: grid; grid-template-columns: repeat(4,1fr); height: 66px; padding: 5px 8px; border-radius: 18px 18px 0 0; }.admin-brand, .admin-sidebar-bottom, .admin-nav button:nth-child(n+5) { display: none; }.admin-nav { display: contents; }.admin-nav button, .admin-sidebar-bottom button { display: grid; gap: 3px; min-height: 54px; color: rgba(255,249,237,.75); font-size: 10px; }.admin-nav button:first-child::after { content: '工作台'; font-size: 10px; }.admin-nav button:nth-child(2)::after { content: '审核'; font-size: 10px; }.admin-nav button:nth-child(3)::after { content: '内容'; font-size: 10px; }.admin-nav button.is-active { color: #fff; background: rgba(255,255,255,.14); }.admin-main { padding-bottom: 64px; }.admin-topbar { min-height: 60px; padding: 0 18px; }.admin-breadcrumb, .admin-search, .admin-icon-button, .admin-top-actions > #adminIdentity { display: none; }.admin-mobile-title { display: inline; color: #8f302d; font-family: serif; font-size: 18px; }.admin-content { padding: 28px 16px 42px; }.admin-intro { align-items: flex-start; padding-bottom: 20px; }.admin-intro h1 { font-size: 32px; }.admin-date { display: none; }.admin-stat-grid { gap: 10px; }.admin-stat-card { min-height: 92px; padding: 12px; gap: 8px; }.admin-stat-icon { width: 36px; height: 36px; font-size: 18px; }.admin-stat-card strong { font-size: 22px; }.admin-stat-card em { display: none; }.admin-dashboard-grid { grid-template-columns: 1fr; }.admin-card { padding: 17px; }.admin-dashboard-grid .admin-card-wide { min-height: 0; }.admin-workspace-tabs { margin-top: 20px; } }

/* Mobile admin navigation keeps every management area reachable instead of hiding
   users, maps, and system settings behind a desktop-only sidebar. */
@media (max-width: 680px) {
  /* Keep every management entry visible without horizontal scrolling. */
  .admin-sidebar {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-template-rows: repeat(2, 54px);
    gap: 4px;
    height: auto;
    min-height: 116px;
    padding: 7px 8px 9px;
    border-radius: 20px 20px 0 0;
    box-shadow: 0 -12px 32px rgba(16,51,45,.22);
  }
  .admin-nav { display: contents; }
  .admin-sidebar-bottom { display: contents; margin: 0; }
  .admin-platform-link { display: none; }
  .admin-nav button, .admin-sidebar-bottom button {
    position: relative;
    display: grid;
    grid-template-rows: 22px 16px;
    justify-items: center;
    align-content: center;
    gap: 2px;
    min-width: 0;
    min-height: 50px;
    padding: 4px 2px;
    border-radius: 14px;
    font-size: 0;
    text-align: center;
  }
  .admin-nav button:nth-child(n+5) { display: grid; }
  .admin-nav button i, .admin-sidebar-bottom button i { font-size: 19px; line-height: 22px; }
  .admin-nav button::after, .admin-sidebar-bottom button::after { font-size: 10px; line-height: 16px; }
  .admin-nav button:nth-child(1)::after { content: '工作台'; }
  .admin-nav button:nth-child(2)::after { content: '审核'; }
  .admin-nav button:nth-child(3)::after { content: '内容'; }
  .admin-nav button:nth-child(4)::after { content: '草稿'; }
  .admin-nav button:nth-child(5)::after { content: '发布'; }
  .admin-nav button:nth-child(6)::after { content: '用户'; }
  .admin-nav button:nth-child(7)::after { content: '地图'; }
  .admin-sidebar-bottom button::after { content: '设置'; }
  .admin-nav-count { position: absolute; margin: -4px 0 0 24px; font-size: 9px; }
  .admin-main { padding-bottom: 132px; }
}
.admin-settings-panel { display: grid; gap: 22px; }
.admin-panel-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; padding-bottom: 18px; border-bottom: 1px solid var(--line); }
.admin-panel-heading h2 { margin: 4px 0 7px; color: var(--admin-forest); font-family: serif; font-size: 30px; font-weight: 400; }
.admin-panel-heading p:last-child { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.6; }
.admin-settings-panel .content-item { background: #fffdfa; }
.runtime-config-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.runtime-config-group { padding: 18px; border: 1px solid var(--line); border-radius: 18px; background: #fffdfa; }
.runtime-config-group-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.runtime-config-group-heading h3 { margin: 0; color: var(--admin-forest); font-family: serif; font-size: 20px; font-weight: 500; }
.runtime-config-field { display: grid; gap: 7px; margin-top: 12px; color: var(--ink); font-size: 12px; }
.runtime-config-label { position: relative; display: grid; grid-template-columns: 8px auto; align-items: center; column-gap: 7px; row-gap: 3px; min-height: 20px; }
.runtime-config-label small { grid-column: 2; }
.runtime-status-dot { width: 7px; height: 7px; border-radius: 50%; background: #b9b4ad; box-shadow: 0 0 0 3px rgba(185,180,173,.16); }
.runtime-status-dot.is-on { background: #4f9a73; box-shadow: 0 0 0 3px rgba(79,154,115,.16); }
.runtime-config-field small { color: var(--muted); font-size: 10px; }
.runtime-secret-state { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); font-size: 10px; }
.runtime-secret-state::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #c9cfc9; }
.runtime-secret-state.is-set { color: #2f695c; }
.runtime-secret-state.is-set::before { background: #2f695c; }
.runtime-config-field input, .runtime-config-field select { box-sizing: border-box; width: 100%; min-height: 40px; padding: 0 12px; border: 1px solid var(--line); border-radius: 10px; color: var(--ink); background: #fff; font: inherit; outline: none; }
.runtime-config-field input:focus, .runtime-config-field select:focus { border-color: var(--admin-forest); box-shadow: 0 0 0 3px rgba(23,63,55,.10); }
.runtime-toggle { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; color: var(--muted); }
.runtime-toggle input { position: absolute; opacity: 0; pointer-events: none; }
.runtime-switch { position: relative; width: 42px; height: 24px; flex: 0 0 auto; border-radius: 999px; background: #d8d3cc; transition: background .22s ease, box-shadow .22s ease; cursor: pointer; }
.runtime-switch::after { content: ''; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 4px rgba(20,35,30,.18); transition: transform .22s ease; }
.runtime-toggle input:checked + .runtime-switch { background: var(--admin-forest); box-shadow: 0 0 0 3px rgba(23,63,55,.10); }
.runtime-toggle input:checked + .runtime-switch::after { transform: translateX(18px); }
.runtime-toggle input:focus-visible + .runtime-switch { outline: 2px solid var(--admin-terracotta); outline-offset: 3px; }
.runtime-toggle-state { min-width: 42px; }
.runtime-config-field[data-detail]::after { content: attr(data-detail); position: absolute; z-index: 5; left: 18px; right: 18px; bottom: calc(100% + 8px); padding: 10px 12px; border: 1px solid rgba(23,63,55,.12); border-radius: 10px; color: var(--ink); background: rgba(255,253,250,.98); box-shadow: 0 12px 30px rgba(20,35,30,.14); font-size: 11px; line-height: 1.55; opacity: 0; visibility: hidden; transform: translateY(4px); transition: opacity .18s ease, transform .18s ease, visibility 0s linear .7s; pointer-events: none; }
.runtime-config-field[data-detail]:hover::after, .runtime-config-field[data-detail]:focus-within::after { opacity: 1; visibility: visible; transform: translateY(0); transition-delay: .7s, .7s, 0s; }
.runtime-config-error { padding: 11px 13px; border: 1px solid rgba(168,100,78,.28); border-radius: 10px; color: #9a513d; background: #fff6f1; font-size: 12px; line-height: 1.55; }
.runtime-config-note { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.6; }
.runtime-advanced { border-top: 1px solid var(--line); padding-top: 16px; }
.runtime-advanced summary { color: var(--admin-forest); font-size: 13px; cursor: pointer; }
.runtime-advanced p { margin: 10px 0; color: var(--muted); font-size: 11px; line-height: 1.6; }
.runtime-advanced textarea { box-sizing: border-box; width: 100%; min-height: 190px; padding: 12px; border: 1px solid var(--line); border-radius: 12px; color: var(--ink); background: #fbfaf7; font: 12px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; resize: vertical; }
.runtime-advanced textarea:focus { border-color: var(--admin-forest); outline: none; box-shadow: 0 0 0 3px rgba(23,63,55,.10); }
.runtime-advanced-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
@media (max-width: 680px) { .admin-panel-heading { flex-direction: column; } .admin-panel-heading .admin-small-button { align-self: flex-start; } }
@media (max-width: 680px) { .runtime-config-grid { grid-template-columns: 1fr; gap: 10px; }.runtime-config-group { padding: 15px; }.runtime-config-group-heading h3 { font-size: 18px; } }

/* Final admin palette alignment: match the public platform's forest / clay system. */
.password-field { display: flex; align-items: center; gap: 6px; }.password-field input { min-width: 0; flex: 1; }.password-field button { flex: 0 0 auto; min-height: 34px; padding: 0 10px; border: 1px solid var(--line); border-radius: 9px; color: var(--forest); background: #fff; font-size: 12px; cursor: pointer; }.password-form-hint { margin: -4px 0 2px; color: var(--muted); font-size: 11px; line-height: 1.55; }
.admin-page { --admin-forest: #173f37; --admin-forest-deep: #10332d; --admin-terracotta: #c47552; }
.admin-page .admin-sidebar { background: linear-gradient(180deg, var(--admin-forest) 0%, var(--admin-forest-deep) 100%); }
.admin-page .admin-nav button.is-active { color: var(--admin-forest); background: #f7f2e9; }
.admin-page .admin-nav button.is-active i { color: var(--admin-terracotta); }
.admin-page .admin-intro h1 { color: var(--admin-forest); }
.admin-page .admin-eyebrow, .admin-page .admin-status { color: var(--admin-terracotta); }
.admin-page .admin-status[data-tone="error"] { color: #a8644e; background: transparent; }
.admin-page .admin-workspace-tabs button.is-active, .admin-page .admin-tabs button.is-active, .admin-page .dark-button { background: var(--admin-forest); border-color: var(--admin-forest); }
.admin-page .outline-button, .admin-page .admin-link-button { color: var(--admin-forest); }
/* Old cinnabar brand colour still leaking into the forest-green admin. These
   four are in the working UI, not the decorative/semantic reds (map pins,
   activity dots, the access-denied page), which keep their red on purpose. */
.admin-page .admin-icon-button { color: var(--admin-forest); }
.admin-page .admin-mobile-title { color: var(--admin-forest); }
.admin-page .admin-nav button.is-active .admin-nav-count { color: var(--admin-terracotta); }
.admin-page .admin-nav button.is-active { box-shadow: 0 8px 18px rgba(16,51,45,.16); }

/* ---------------------------------------------------------------- admin icons
   The sidebar, the search field, the notification button and the four
   dashboard stat cards used Unicode dingbats (⌂ ▤ □ ◇ ↗ ♙ ⌖ ⚙ ♧ ⌕) rather than
   the inline SVG set the public site uses. Dingbats are font-dependent, so
   they arrived at inconsistent weights and optical sizes: □ (U+25A1) reads as
   a missing icon, and ♙ (U+2659, a white chess pawn) was the icon for
   "用户管理". They are now the same stroke icons as the rest of the product,
   which is why each one needs a real box to sit in. */
.admin-nav i, .admin-sidebar-bottom i { display: grid; place-items: center; flex: 0 0 auto; width: 20px; height: 20px; }
.admin-nav i .ui-icon, .admin-sidebar-bottom i .ui-icon { width: 20px; height: 20px; }
.admin-search .ui-icon { width: 16px; height: 16px; }
.admin-icon-button { display: grid; place-items: center; width: 34px; height: 34px; padding: 0; border-radius: 50%; transition: background-color var(--dur-1) var(--ease), transform var(--dur-3) var(--ease-spring); }
.admin-icon-button .ui-icon { width: 21px; height: 21px; }
.admin-icon-button:hover { background: rgba(23,63,55,.07); }
.admin-icon-button:active { transform: scale(.94); }
.admin-stat-icon .ui-icon { width: 22px; height: 22px; }
.article-dialog > .dialog-close { display: grid; place-items: center; position: absolute; z-index: 3; top: 15px; left: 15px; right: auto; width: 38px; height: 38px; border: 1px solid rgba(255,255,255,.72); border-radius: 50%; color: #fff; background: rgba(18,47,42,.52); font-size: 25px; line-height: 1; cursor: pointer; backdrop-filter: blur(8px); }.article-dialog > .dialog-close:hover, .article-dialog > .dialog-close:focus-visible { background: rgba(18,47,42,.78); outline: 2px solid rgba(255,255,255,.7); outline-offset: 2px; }
.admin-access-denied { min-height: 100svh; background: #f7f6f2; }.admin-denied { display: grid; grid-template-columns: 1fr; justify-items: center; align-content: center; width: 100%; min-height: 100svh; padding: 32px; box-sizing: border-box; text-align: center; }.admin-denied-seal { display: grid; place-items: center; width: 64px; height: 64px; border: 1px solid #d9b6a4; border-radius: 50%; color: #9a3732; background: #fff8f4; font-family: Georgia,serif; font-size: 30px; }.admin-denied h1 { margin: 16px 0 8px; color: #74302a; font-family: serif; font-size: 42px; font-weight: 500; }.admin-denied p:not(.admin-eyebrow) { margin: 0; color: #6f675f; font-size: 15px; }.admin-denied small { margin-top: 8px; color: #a39a91; font-size: 12px; }.admin-denied-actions { display: flex; gap: 10px; margin-top: 24px; }.admin-denied-actions a { display: inline-flex; align-items: center; min-height: 40px; padding: 0 16px; border-radius: 9px; text-decoration: none; }.admin-denied-actions .outline-button { border: 1px solid #d9cec0; color: #8d8176; background: #fff; }

/* Final desktop polish overrides: kept after the shared rules so mobile remains untouched. */
@media (min-width: 921px) {
  .app-shell { gap: 18px; padding: 14px; }
  .side-rail { top: 14px; height: calc(100svh - 28px); border: 1px solid rgba(255,255,255,.14); border-radius: 28px; background: linear-gradient(165deg, rgba(21,60,53,.98), rgba(15,45,40,.94)); box-shadow: 0 18px 52px rgba(24,53,46,.18), inset 0 1px 0 rgba(255,255,255,.1); }
  .side-nav { gap: 8px; margin-top: 70px; }
  .nav-item { position: relative; min-height: 58px; border-radius: 17px; transition: color 260ms var(--desktop-ease), background 320ms var(--desktop-ease), transform 320ms var(--desktop-ease), box-shadow 320ms var(--desktop-ease); }
  .nav-item::before { content: ""; position: absolute; left: -12px; width: 3px; height: 0; border-radius: 4px; background: #f0b49a; transition: height 300ms var(--desktop-ease); }
  .nav-item:hover { transform: translateX(2px); background: rgba(211,234,219,.1); }
  .nav-item.is-active { background: rgba(235,246,237,.16); box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 8px 22px rgba(0,0,0,.08); }
  .nav-item.is-active::before { height: 22px; }
  .desktop-view-context { min-width: 178px; padding-left: 4px; }
  .desktop-view-context span { font-size: 8px; letter-spacing: .22em; }
  .desktop-view-context strong { font-size: 21px; }
  .search-box { height: 46px; border-color: rgba(32,59,51,.12); background: rgba(255,255,255,.58); box-shadow: 0 8px 26px rgba(32,59,51,.04); transition: width 360ms var(--desktop-ease), border-color 220ms ease, box-shadow 220ms ease, background 220ms ease; }
  .search-box:focus-within { width: min(420px, 48vw); border-color: rgba(32,59,51,.35); box-shadow: 0 12px 30px rgba(32,59,51,.1); }
  .icon-button, .avatar-button { transition: transform 240ms var(--desktop-ease), background 220ms ease, box-shadow 220ms ease; }
  .icon-button:hover, .avatar-button:hover { transform: translateY(-2px); }
  .avatar-button { box-shadow: 0 6px 15px rgba(21,60,53,.16); }
  .desktop-layout { animation: desktop-screen-in 560ms var(--desktop-ease) both; }
  .hero-story { box-shadow: 0 24px 70px rgba(23,53,45,.14), inset 0 1px 0 rgba(255,255,255,.18); }
  .hero-story img { transition: transform 900ms var(--desktop-ease), filter 600ms ease; }
  .hero-story:hover img { transform: scale(1.025); filter: saturate(.84) contrast(.97); }
  .hero-story:hover { box-shadow: 0 30px 84px rgba(23,53,45,.2), inset 0 1px 0 rgba(255,255,255,.22); }
  .story-card, .recommend-row, .quote-card, .explore-meter, .map-preview, .route-highlight, .profile-links button, .profile-links a { transition: transform 420ms var(--desktop-ease), box-shadow 420ms var(--desktop-ease), border-color 220ms ease, background 220ms ease; }
  .story-card:hover { transform: translateY(-5px); box-shadow: 0 16px 34px rgba(32,59,51,.09); }
  .story-card:hover .story-image-button img { transform: scale(1.045); }
  .map-preview:hover, .quote-card:hover, .explore-meter:hover { transform: translateY(-3px); box-shadow: 0 22px 52px rgba(32,59,51,.13); }
  .recommend-row:hover { transform: translateX(4px); background: rgba(255,255,255,.74); box-shadow: 0 8px 24px rgba(32,59,51,.06); }
  .outline-button, .dark-button, .text-button { transition: transform 260ms var(--desktop-ease), background 220ms ease, border-color 220ms ease, color 220ms ease; }
  .outline-button:hover, .dark-button:hover, .text-button:hover { transform: translateY(-2px); }
  body[data-desktop-screen="map"] .desktop-layout #map,
  body[data-desktop-screen="guides"] .desktop-layout #guides,
  body[data-desktop-screen="vr"] .mobile-screen[data-screen="vr"],
  body[data-desktop-screen="profile"] .mobile-screen[data-screen="profile"] { animation: desktop-screen-in 520ms var(--desktop-ease) both; }
  body[data-desktop-screen="vr"] .route-highlight:hover { transform: translateY(-4px); box-shadow: 0 34px 76px rgba(32,59,51,.24); }
  body[data-desktop-screen="profile"] .profile-links button:hover, body[data-desktop-screen="profile"] .profile-links a:hover { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(32,59,51,.08); }
  .reduce-motion *, .reduce-motion *::before, .reduce-motion *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
}

@media (max-width: 680px) {
  .mobile-feed { height: 100dvh; }
  .mobile-feed-card { height: 100dvh; min-height: 100dvh; }
  .feed-open-button { top: calc(104px + env(safe-area-inset-top)); bottom: 255px; touch-action: pan-y; }
  .feed-topline { position: absolute; z-index: 2; top: calc(77px + env(safe-area-inset-top)); left: 22px; right: 22px; display: flex; align-items: center; justify-content: space-between; color: rgba(255,255,255,.72); font-size: 10px; letter-spacing: .08em; pointer-events: none; }
  .feed-topline strong { color: rgba(255,255,255,.94); font-size: 11px; font-weight: 500; letter-spacing: .12em; }
  .feed-copy { bottom: calc(170px + env(safe-area-inset-bottom)); }
  .feed-actions { right: 16px; bottom: calc(169px + env(safe-area-inset-bottom)); gap: 11px; }
  .feed-progress { right: 22px; bottom: calc(102px + env(safe-area-inset-bottom)); }
  .feed-reward { right: 22px; bottom: calc(136px + env(safe-area-inset-bottom)); opacity: 0; transform: translateY(5px) scale(.96); animation: none; pointer-events: none; }
  .mobile-feed-card.is-active .feed-reward { opacity: 1; transform: translateY(0) scale(1); animation: reward-pop 560ms var(--ease) both; }
  .feed-reward.is-celebrating { animation: reward-pulse 680ms var(--ease) both; }

  .feed-heart-burst { position: absolute; z-index: 3; left: 50%; top: 44%; color: #f3b29b; font-size: clamp(70px, 23vw, 116px); line-height: 1; text-shadow: 0 12px 40px rgba(8, 24, 20, .34); pointer-events: none; transform: translate(-50%, -50%) scale(.48) rotate(-8deg); animation: heart-burst 720ms var(--ease) both; }
}

/* Desktop motion system: restrained, tactile, and intentionally separate from mobile. */
@media (min-width: 921px) {
  :root { --desktop-ease: cubic-bezier(.22, .7, .18, 1); }
  html { scroll-behavior: auto; }
  body { background: radial-gradient(circle at 76% 0%, #ffffff 0, var(--paper) 42%, #eef1ec 100%); }
  .app-shell { gap: 18px; padding: 14px; }
  .side-rail { position: sticky; top: 14px; height: calc(100svh - 28px); border: 1px solid rgba(255,255,255,.14); border-radius: 28px; padding: 28px 12px; background: linear-gradient(165deg, rgba(21,60,53,.98), rgba(15,45,40,.94)); box-shadow: 0 18px 52px rgba(24,53,46,.18), inset 0 1px 0 rgba(255,255,255,.1); }
  .brand-mark { transition: transform 420ms var(--desktop-ease), opacity 240ms ease; }
  .brand-mark:hover { transform: translateY(-2px); opacity: .88; }
  .side-nav { gap: 8px; margin-top: 70px; }
  .nav-item { position: relative; min-height: 58px; border-radius: 17px; transition: color 260ms var(--desktop-ease), background 320ms var(--desktop-ease), transform 320ms var(--desktop-ease), box-shadow 320ms var(--desktop-ease); }
  .nav-item::before { content: ""; position: absolute; left: -12px; width: 3px; height: 0; border-radius: 4px; background: #f0b49a; transition: height 300ms var(--desktop-ease); }
  .nav-item:hover { transform: translateX(2px); background: rgba(211,234,219,.1); }
  .nav-item.is-active { background: rgba(235,246,237,.16); box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 8px 22px rgba(0,0,0,.08); }
  .nav-item.is-active::before { height: 22px; }
  .nav-icon .ui-icon { transition: transform 360ms var(--desktop-ease); }
  .nav-item:hover .ui-icon, .nav-item.is-active .ui-icon { transform: scale(1.08); }
  .content-area { min-width: 0; padding: 0 clamp(22px, 4vw, 74px) 62px; }
  .topbar { position: relative; height: 94px; }
  .desktop-view-context { min-width: 178px; padding-left: 4px; transform-origin: left center; animation: desktop-context-in 520ms var(--desktop-ease) both; }
  .desktop-view-context span { font-size: 8px; letter-spacing: .22em; }
  .desktop-view-context strong { font-size: 21px; }
  .search-box { height: 46px; border-color: rgba(32,59,51,.12); background: rgba(255,255,255,.58); box-shadow: 0 8px 26px rgba(32,59,51,.04); transition: width 360ms var(--desktop-ease), border-color 220ms ease, box-shadow 220ms ease, background 220ms ease; }
  .search-box:focus-within { width: min(420px, 48vw); border-color: rgba(32,59,51,.35); box-shadow: 0 12px 30px rgba(32,59,51,.1); }
  .icon-button, .avatar-button { transition: transform 240ms var(--desktop-ease), background 220ms ease, box-shadow 220ms ease; }
  .icon-button:hover, .avatar-button:hover { transform: translateY(-2px); }
  .avatar-button { box-shadow: 0 6px 15px rgba(21,60,53,.16); }
  .desktop-layout { animation: desktop-screen-in 560ms var(--desktop-ease) both; }
  .hero-story, .map-preview, .story-card, .recommend-row, .quote-card, .explore-meter, .route-highlight, .profile-meter, .profile-links button, .profile-links a { transition: transform 420ms var(--desktop-ease), box-shadow 420ms var(--desktop-ease), border-color 220ms ease, background 220ms ease; }
  .hero-story { box-shadow: 0 24px 70px rgba(23,53,45,.14), inset 0 1px 0 rgba(255,255,255,.18); }
  .hero-story:hover { box-shadow: 0 30px 84px rgba(23,53,45,.2), inset 0 1px 0 rgba(255,255,255,.22); }
  .hero-story img { transition: transform 900ms var(--desktop-ease), filter 600ms ease; }
  .hero-story:hover img { transform: scale(1.025); filter: saturate(.84) contrast(.97); }
  .outline-button, .dark-button, .text-button { transition: transform 260ms var(--desktop-ease), background 220ms ease, border-color 220ms ease, color 220ms ease; }
  .outline-button:hover, .dark-button:hover, .text-button:hover { transform: translateY(-2px); }
  .story-card { padding: 0 10px 22px; border-radius: 20px; }
  .story-card:hover { transform: translateY(-5px); box-shadow: 0 16px 34px rgba(32,59,51,.09); }
  .story-card:hover .story-image-button img { transform: scale(1.045); }
  .map-preview { box-shadow: 0 16px 42px rgba(50,82,85,.1); }
  .map-preview:hover { transform: translateY(-3px); box-shadow: 0 22px 52px rgba(50,82,85,.14); }
  .desktop-region-pin { transition: transform 300ms var(--desktop-ease), background 220ms ease, box-shadow 300ms var(--desktop-ease); }
  .recommend-row { padding: 9px; border-radius: 16px; }
  .recommend-row:hover { transform: translateX(4px); background: rgba(255,255,255,.74); box-shadow: 0 8px 24px rgba(32,59,51,.06); }
  .quote-card:hover, .explore-meter:hover { transform: translateY(-3px); box-shadow: 0 18px 36px rgba(32,59,51,.13); }
  body[data-desktop-screen="map"] .desktop-layout #map,
  body[data-desktop-screen="guides"] .desktop-layout #guides,
  body[data-desktop-screen="vr"] .mobile-screen[data-screen="vr"],
  body[data-desktop-screen="profile"] .mobile-screen[data-screen="profile"] { animation: desktop-screen-in 520ms var(--desktop-ease) both; }
  body[data-desktop-screen="map"] #map .desktop-map-panel { box-shadow: inset 1px 0 0 rgba(255,255,255,.35); }
  body[data-desktop-screen="vr"] .route-highlight { box-shadow: 0 26px 64px rgba(32,59,51,.18); }
  body[data-desktop-screen="vr"] .route-highlight:hover { transform: translateY(-4px); box-shadow: 0 34px 76px rgba(32,59,51,.24); }
  body[data-desktop-screen="profile"] .profile-links button:hover, body[data-desktop-screen="profile"] .profile-links a:hover { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(32,59,51,.08); }
  .reduce-motion *, .reduce-motion *::before, .reduce-motion *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
}

@keyframes desktop-screen-in {
  from { opacity: 0; transform: translateY(10px) scale(.992); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes desktop-context-in {
  from { opacity: 0; transform: translateX(-8px); }
  to { opacity: 1; transform: translateX(0); }
}

@keyframes reward-pulse {
  0% { opacity: 1; transform: translateY(0) scale(1); }
  35% { opacity: 1; transform: translateY(-3px) scale(1.045); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes heart-burst {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.48) rotate(-8deg); }
  24% { opacity: 1; transform: translate(-50%, -50%) scale(1.08) rotate(4deg); }
  100% { opacity: 0; transform: translate(-50%, -58%) scale(.84) rotate(0); }
}

.privacy-account-actions { display: grid; gap: 9px; margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line); }.privacy-account-actions button { min-height: 44px; border: 1px solid var(--line); border-radius: 13px; color: var(--ink); background: #fff; }.privacy-account-actions .privacy-danger { color: #a65b4d; }.privacy-account-note, .privacy-action-status { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.6; }.privacy-action-status { min-height: 18px; color: var(--accent); }
.article-dialog-references { display: grid; gap: 8px; margin-top: 18px; }.article-dialog-references a { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 11px 13px; border: 1px solid var(--line); border-radius: 12px; color: var(--ink); background: rgba(247, 244, 237, .7); text-decoration: none; font-size: 13px; }.article-dialog-references a:hover, .article-dialog-references a:focus-visible { border-color: rgba(47, 105, 92, .45); outline: none; }.article-dialog-references span { color: var(--forest); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; }
.mobile-map-selection { margin: 0 -2px 24px; padding: 15px 16px; border: 1px solid var(--line); border-radius: 17px; background: rgba(255,255,255,.68); }.mobile-map-selection > span { color: var(--forest); font-family: serif; font-size: 21px; }.mobile-map-selection > p { margin: 6px 0 0; color: var(--muted); font-size: 11px; line-height: 1.6; }.map-selection-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }.map-selection-heading span { color: var(--forest); font-family: serif; font-size: 21px; }.map-selection-heading small { color: var(--muted); font-size: 11px; }.map-selection-list { display: grid; gap: 8px; margin-top: 12px; }.map-selection-item { display: grid; grid-template-columns: 48px 1fr auto; align-items: center; gap: 10px; min-width: 0; padding: 7px; border: 1px solid rgba(47,105,92,.12); border-radius: 12px; color: var(--ink); background: rgba(255,255,255,.78); text-align: left; }.map-selection-item img { width: 48px; height: 48px; border-radius: 9px; object-fit: cover; }.map-selection-item span { min-width: 0; }.map-selection-item strong, .map-selection-item small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.map-selection-item strong { font-size: 13px; font-weight: 500; }.map-selection-item small { margin-top: 4px; color: var(--muted); font-size: 10px; }.map-selection-item b { color: var(--forest); font-size: 17px; }.map-pin.is-selected { color: #fff; background: var(--forest); box-shadow: 0 0 0 7px rgba(47,105,92,.13); }.route-highlight .is-saved { color: var(--forest); background: #f5e2bd; border-color: #f5e2bd; }

/* Approved concept direction: editorial discovery, real map canvas, quiet surfaces. */
:root { --paper: #f7f5ef; --surface: #fffdfa; --ink: #16231f; --muted: #6a716d; --line: #e2e3dc; --forest: #203b33; --accent: #9c6144; --sand: #d39a56; --map-blue: #dce8eb; }
.brand-mark, .section-heading h2, .rail-heading h2, .hero-copy h1, .map-copy h2, .mobile-screen-header h1, .story-ranking h2 { letter-spacing: .025em; }
.topbar { height: 86px; }
.search-box { border-color: #d7ddd7; background: rgba(255,255,255,.68); }
.hero-story { border-radius: 30px; box-shadow: 0 18px 48px rgba(23,53,45,.12); }
.map-preview { border-radius: 30px; background: var(--map-blue); box-shadow: 0 12px 34px rgba(50,82,85,.08); }
.desktop-map-canvas { border-radius: 22px; background: #d3e1e5; }
.story-grid { gap: 22px; }
.story-card { border-bottom: 0; }
.story-card-copy { padding-left: 0; }
.story-image-button { border-radius: 18px; }
.recommend-row img, .news-row img { border-radius: 14px; }
.story-ranking { display: flex; align-items: end; justify-content: space-between; gap: 18px; margin: 26px 0 16px; }
.story-ranking h2 { margin: 7px 0 0; font-family: serif; font-size: 28px; font-weight: 400; }
.map-search-shell, .map-filter-row { display: none; }
.map-empty { margin: 11px 0 0; color: var(--muted); font-size: 12px; line-height: 1.6; }
.ui-icon { display: block; width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
/* Sizing for the icons that replaced Unicode dingbats (⌕ ⌂ ⌖ ⚙ ◌). Each
   container used to size its glyph with `font-size`, which does not apply to an
   inline SVG, so every one of these needs an explicit box. */
.icon-button { display: grid; place-items: center; padding: 0; }
.icon-button .ui-icon { width: 21px; height: 21px; }
/* The reduced-motion control is a toggle, so its "on" state has to be visible
   as well as announced (app.js mirrors state.reducedMotion into aria-pressed). */
.icon-button[aria-pressed="true"] { color: var(--forest); background: rgba(21,60,53,.10); }
.search-box > span, .map-search-shell > span { display: grid; place-items: center; flex: 0 0 auto; }
.search-box > span .ui-icon, .map-search-shell > span .ui-icon { width: 17px; height: 17px; }
.story-top-button .ui-icon { width: 19px; height: 19px; }
.story-location-mark .ui-icon { width: 13px; height: 13px; stroke-width: 2; }
.auth-dialog [hidden], .story-dialog [hidden], .admin-page [hidden] { display: none !important; }
.mobile-tab .ui-icon { width: 21px; height: 21px; }
.quick-icon { display: grid; place-items: center; height: 23px; margin-bottom: 5px; color: var(--accent); }
.quick-icon .ui-icon { width: 21px; height: 21px; }
.nav-icon { display: grid; place-items: center; height: 22px; }
.nav-icon .ui-icon { width: 21px; height: 21px; }
.desktop-view-context { display: grid; gap: 4px; min-width: 138px; margin-right: auto; }
.desktop-view-context span { color: var(--muted); font-size: 9px; letter-spacing: .18em; }
.desktop-view-context strong { color: var(--ink); font-family: serif; font-size: 19px; font-weight: 400; letter-spacing: .08em; }

@media (min-width: 921px) {
  .content-area { min-height: 100svh; }
  .desktop-layout { min-height: calc(100svh - 150px); }
  body[data-desktop-screen="map"] .desktop-layout,
  body[data-desktop-screen="guides"] .desktop-layout { display: block; max-width: 1440px; }
  body[data-desktop-screen="map"] .desktop-layout .primary-column > section,
  body[data-desktop-screen="guides"] .desktop-layout .primary-column > section { display: none; }
  body[data-desktop-screen="map"] .desktop-layout .recommend-rail,
  body[data-desktop-screen="guides"] .desktop-layout .recommend-rail { display: none; }
  body[data-desktop-screen="map"] .desktop-layout #map {
    display: grid;
    /* .62fr starved the copy column: the track came out 362px wide while
       `.map-copy`'s padding and the 44px heading both scale with the viewport,
       leaving a 160px text box — so 「把远方，放进 / 下一段路线。」 wrapped to one
       character per line (measured 4-5 lines instead of 2). .74fr plus the
       smaller padding above keeps the heading at its intended two lines from
       921px through 1920px. */
    grid-template-columns: minmax(260px, .74fr) minmax(0, 1.26fr);
    min-height: calc(100svh - 150px);
  }
  body[data-desktop-screen="map"] #map .map-copy { display: flex; flex-direction: column; justify-content: center; padding: clamp(26px, 3vw, 58px); }
  body[data-desktop-screen="map"] #map .map-copy p { max-width: 330px; }
  body[data-desktop-screen="map"] #map .desktop-map-panel { grid-template-rows: minmax(0, 1fr) auto; min-height: calc(100svh - 186px); padding: 24px; }
  body[data-desktop-screen="map"] #map .desktop-map-canvas { min-height: 0; }
  body[data-desktop-screen="guides"] .desktop-layout #guides {
    display: block;
    min-height: calc(100svh - 150px);
    padding: 38px 0 70px;
  }
  body[data-desktop-screen="guides"] #guides .story-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; margin-top: 34px; }
  body[data-desktop-screen="guides"] #guides .story-card { padding: 0 0 24px; border: 1px solid var(--line); border-radius: 20px; overflow: hidden; background: var(--surface); box-shadow: 0 12px 30px rgba(32,59,51,.06); }
  body[data-desktop-screen="guides"] #guides .story-card-copy { padding: 18px 18px 20px; }
  body[data-desktop-screen="guides"] #guides .story-image-button { border-radius: 0; }
  body[data-desktop-screen="guides"] #guides .save-button { right: 16px; bottom: 18px; }
  body[data-desktop-screen="vr"] .desktop-layout,
  body[data-desktop-screen="profile"] .desktop-layout { display: none; }
  body[data-desktop-screen="vr"] .mobile-screen[data-screen="vr"],
  body[data-desktop-screen="profile"] .mobile-screen[data-screen="profile"] {
    display: block;
    width: min(1180px, 100%);
    min-height: calc(100svh - 150px);
    margin: 0 auto;
    padding: 42px 0 72px;
  }
  body[data-desktop-screen="vr"] .mobile-screen-header,
  body[data-desktop-screen="profile"] .profile-head { max-width: 760px; }
  body[data-desktop-screen="vr"] .mobile-screen-header h1 { max-width: 560px; margin: 15px 0 14px; font-family: serif; font-size: clamp(48px, 6vw, 82px); font-weight: 400; line-height: .98; letter-spacing: .02em; }
  body[data-desktop-screen="vr"] .mobile-screen-header p { max-width: 370px; color: var(--muted); font-size: 14px; line-height: 1.7; }
  body[data-desktop-screen="vr"] .route-highlight { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 18px 40px; min-height: 300px; margin-top: 44px; padding: 46px 52px; border-radius: 28px; color: #f7f5ef; background: linear-gradient(120deg, rgba(20,60,52,.96), rgba(39,91,77,.75)), url('./media/culture-museum.jpeg') center/cover; box-shadow: 0 20px 48px rgba(32,59,51,.15); }
  body[data-desktop-screen="vr"] .route-highlight h2 { grid-column: 1 / -1; max-width: 650px; margin: 0; font-family: serif; font-size: clamp(36px, 5vw, 68px); font-weight: 400; line-height: 1.02; }
  body[data-desktop-screen="vr"] .route-highlight p { grid-column: 1; max-width: 420px; margin: 0; color: rgba(247,245,239,.76); font-size: 14px; line-height: 1.7; }
  body[data-desktop-screen="vr"] .route-highlight .outline-button { grid-column: 2; grid-row: 3; }
  body[data-desktop-screen="vr"] .route-list { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-top: 22px; padding: 22px 26px; border: 1px solid var(--line); border-radius: 19px; background: var(--surface); }
  body[data-desktop-screen="vr"] .route-list span { color: var(--accent); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; }
  body[data-desktop-screen="vr"] .route-list strong { margin-left: auto; font-family: serif; font-size: 21px; font-weight: 400; }
  body[data-desktop-screen="vr"] .route-list small { color: var(--muted); font-size: 12px; }
  body[data-desktop-screen="profile"] .mobile-screen[data-screen="profile"] { padding-top: 64px; }
  body[data-desktop-screen="profile"] .profile-head { display: flex; align-items: center; gap: 18px; padding-bottom: 30px; border-bottom: 1px solid var(--line); }
  body[data-desktop-screen="profile"] .profile-head h1 { margin: 4px 0 0; font-family: serif; font-size: 48px; font-weight: 400; }
  body[data-desktop-screen="profile"] .profile-head .icon-button { margin-left: auto; }
  body[data-desktop-screen="profile"] .profile-meter { max-width: 760px; margin: 34px 0 0; padding: 24px 0 30px; border-bottom: 1px solid var(--line); }
  body[data-desktop-screen="profile"] .profile-links { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; max-width: 760px; margin-top: 26px; }
  body[data-desktop-screen="profile"] .profile-links button,
  body[data-desktop-screen="profile"] .profile-links a { display: flex; align-items: center; justify-content: space-between; min-height: 58px; padding: 0 18px; border: 1px solid var(--line); border-radius: 15px; color: var(--ink); background: var(--surface); text-decoration: none; }
  body[data-desktop-screen="profile"] .profile-links button:hover,
  body[data-desktop-screen="profile"] .profile-links a:hover { border-color: rgba(32,59,51,.42); transform: translateY(-1px); }
}

@media (max-width: 680px) {
  body { background: var(--paper); }
  .content-area { padding: 0; }
  .topbar { position: fixed; z-index: 9; top: 0; left: 0; right: 0; height: calc(66px + env(safe-area-inset-top)); padding: env(safe-area-inset-top) 20px 0; color: var(--ink); background: rgba(247,245,239,.88); backdrop-filter: blur(18px); }
  .mobile-wordmark { display: block; font-size: 19px; }
  .desktop-view-context { display: none; }
  .search-box { display: none; }
  .topbar-actions { gap: 4px; }
  .icon-button { width: 36px; height: 36px; font-size: 19px; }
  .avatar-button { width: 32px; height: 32px; color: var(--forest); background: #e8eee6; }
  .mobile-feed { height: 100dvh; padding-top: calc(66px + env(safe-area-inset-top)); color: var(--ink); background: var(--paper); }
  /* Home hero is a flex column: the media stays behind, while the copy, quick
     actions and controls stack up from the bottom so they can never overlap. */
  .mobile-feed-card, .mobile-feed-card.modern-home-hero { display: flex; flex-direction: column; height: calc(100dvh - env(safe-area-inset-bottom)); min-height: calc(100dvh - env(safe-area-inset-bottom)); padding: calc(74px + env(safe-area-inset-top)) 22px calc(92px + env(safe-area-inset-bottom)); color: var(--ink); background: var(--paper); }
  .mobile-feed-card::before { display: none; }
  .mobile-feed-card .feed-media { position: absolute; z-index: 0; top: 0; left: 0; display: block; width: 100%; height: 48%; object-fit: cover; object-position: center 38%; opacity: 1; }
  .mobile-feed-card.is-source-thumbnail { background: var(--paper); }
  .mobile-feed-card.is-source-thumbnail .feed-media { z-index: 0; width: 100%; height: 48%; object-fit: contain; object-position: center; background: var(--paper); opacity: 1; }
  .feed-shade { position: absolute; z-index: 1; inset: 0; height: auto; background: linear-gradient(180deg, rgba(13,32,27,.14) 0%, rgba(13,32,27,0) 20%, rgba(247,245,239,.55) 38%, var(--paper) 52%); }
  .feed-open-button { position: absolute; z-index: 2; inset: 0; border: 0; background: transparent; }
  .feed-topline { z-index: 3; top: calc(21px + env(safe-area-inset-top)); left: 22px; right: 22px; color: rgba(22,35,31,.72); letter-spacing: .06em; }
  .feed-topline strong { color: var(--ink); }
  .feed-copy { position: relative; z-index: 3; flex: 0 0 auto; top: auto; right: auto; bottom: auto; left: auto; height: auto; margin-top: auto; color: var(--ink); }
  /* A paper scrim follows the copy block, so headlines stay readable on top of
     the photo even on short screens where the copy reaches into the image. */
  .feed-copy::before { content: ""; position: absolute; z-index: -1; top: -92px; right: -22px; bottom: -6px; left: -22px; background: linear-gradient(180deg, rgba(245,243,238,0) 0%, rgba(245,243,238,.72) 30%, rgba(245,243,238,.96) 52%, var(--paper) 72%); pointer-events: none; }
  .feed-copy h2 { max-width: 88%; margin: 13px 0 8px; color: var(--ink); font-size: clamp(29px, 8.4vw, 42px); line-height: 1.08; }
  .feed-copy p { max-width: 88%; color: var(--muted); font-family: inherit; font-size: 13px; line-height: 1.65; }
  .feed-category { color: var(--accent); opacity: 1; }
  .feed-credit { color: var(--ink); margin-top: 15px; }
  .feed-credit small { color: var(--muted); }
  .credit-avatar { border-color: #abbab0; color: var(--forest); }
  .home-quick-actions { position: relative; right: auto; bottom: auto; left: auto; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 18px; pointer-events: auto; }
  .home-quick-actions button { min-height: 56px; padding: 6px 4px; border: 1px solid #e4e5dd; border-radius: 18px; color: var(--ink); background: rgba(255,253,250,.94); box-shadow: 0 8px 20px rgba(23,53,45,.06); font-size: 11px; pointer-events: auto; }
  .home-quick-actions span { display: block; margin-bottom: 5px; color: var(--accent); font-size: 20px; }
  .feed-actions { position: relative; z-index: 3; flex: 0 0 auto; right: auto; bottom: auto; display: flex; gap: 8px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
  .feed-action { display: inline-flex; align-items: center; gap: 6px; min-width: 0; min-height: 40px; padding: 0 13px; border: 1px solid #e4e5dd; border-radius: 999px; color: var(--forest); background: rgba(255,253,250,.9); text-shadow: none; font-size: 12px; }
  .feed-action b { font-size: 16px; font-weight: 400; line-height: 1; }
  .feed-action span { display: inline; font-size: 11px; }
  .feed-action.is-saved { border-color: var(--accent); color: var(--accent); background: rgba(195,122,85,.1); }
  .feed-action.is-saved b { color: var(--accent); }
  .feed-progress { position: relative; z-index: 3; flex: 0 0 auto; left: auto; right: auto; bottom: auto; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 10px; margin-top: 13px; color: var(--muted); pointer-events: none; }
  .feed-progress > span { flex: 0 0 auto; }
  .feed-progress i { flex: 1 1 100%; }
  .feed-swipe-hint { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; color: var(--muted); font-size: 10px; letter-spacing: .04em; }
  .feed-swipe-hint b { color: var(--accent); font-size: 14px; font-weight: 400; line-height: 1; animation: breathe 1.8s ease-in-out infinite; }
  .feed-progress strong { color: var(--ink); }
  .feed-progress i { background: #dce2dc; }
  .feed-progress em { background: var(--accent); }
  .feed-reward { display: none; }
  .mobile-tabbar { height: calc(69px + env(safe-area-inset-bottom)); color: #6b716d; background: rgba(255,253,250,.94); border-top: 1px solid #e2e3dc; box-shadow: 0 -8px 24px rgba(32,59,51,.06); }
  .mobile-tab { color: inherit; font-size: 20px; }
  .mobile-tab small { font-size: 10px; }
  .mobile-tab.is-active { color: var(--forest); }
  .mobile-screen.is-visible { min-height: 100dvh; padding: calc(88px + env(safe-area-inset-top)) 20px calc(98px + env(safe-area-inset-bottom)); background: var(--paper); }
  .mobile-screen-header h1 { margin-top: 13px; font-size: 38px; line-height: 1.06; }
  .mobile-screen-header p { max-width: 310px; color: var(--muted); }
  .map-search-shell { display: flex; align-items: center; gap: 9px; height: 48px; margin-top: 23px; padding: 0 12px 0 15px; border: 1px solid #dfe3dc; border-radius: 16px; color: var(--muted); background: #fffdfa; box-shadow: 0 7px 22px rgba(31,60,53,.06); }
  .map-search-shell input { min-width: 0; flex: 1; border: 0; outline: 0; color: var(--ink); background: transparent; font-size: 13px; }
  .map-filter-button { width: 32px; height: 32px; border: 0; border-radius: 10px; color: var(--forest); background: #e9eee8; font-size: 18px; }
  .map-filter-row { display: flex; gap: 8px; overflow-x: auto; margin: 13px -20px 0; padding: 0 20px 3px; scrollbar-width: none; }
  .map-filter-row::-webkit-scrollbar { display: none; }
  .map-filter { flex: 0 0 auto; min-height: 33px; padding: 0 13px; border: 1px solid #dfe3dc; border-radius: 999px; color: var(--muted); background: transparent; font-size: 11px; }
  .map-filter.is-active { border-color: var(--forest); color: #fff; background: var(--forest); }
  .mobile-map-canvas { height: min(34svh, 280px); margin: 18px -20px 0; border-radius: 0; background: var(--map-blue); }
  .map-place-sheet { position: relative; z-index: 4; max-height: 245px; overflow-y: auto; margin: -96px 0 18px; padding: 19px 16px 16px; border: 0; border-radius: 25px; background: #fffdfa; box-shadow: 0 13px 34px rgba(31,60,53,.12); }
  .map-place-sheet::before { content: ""; display: block; width: 38px; height: 4px; margin: -8px auto 16px; border-radius: 99px; background: #ccd4cd; }
  .mobile-map-selection > span, .map-selection-heading span { font-size: 21px; }
  .mobile-destination-row { margin: 0; padding: 16px 0; }
  .mobile-destination-row .dark-button { min-height: 40px; padding: 0 13px; font-size: 11px; }
  .story-ranking { margin: 25px 0 8px; }
  .story-ranking h2 { font-size: 29px; }
  .mobile-list { gap: 12px; margin-top: 17px; }
  .mobile-guide-row { grid-template-columns: 94px minmax(0,1fr) 20px; gap: 12px; align-items: start; padding: 11px; border: 1px solid #e5e5de; border-radius: 19px; background: #fffdfa; box-shadow: 0 8px 20px rgba(31,60,53,.04); }
  .mobile-guide-row img { width: 94px; height: 98px; border-radius: 13px; }
  .mobile-guide-row h2 { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; font-size: 17px; }
  .mobile-guide-row p { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 3; font-size: 10px; }
  .route-highlight { min-height: 320px; padding: 28px 24px; }
  .route-highlight h2 { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 3; font-size: 27px; }
  .route-highlight p { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 4; margin-bottom: 16px; font-size: 12px; line-height: 1.6; }
  .route-list { align-items: flex-start; flex-direction: column; gap: 6px; }
  .route-list strong { margin-left: 0; }
}

@media (max-width: 680px) and (max-height: 740px) {
  .mobile-feed-card .feed-media, .mobile-feed-card.is-source-thumbnail .feed-media { height: 40%; }
  .feed-copy h2 { font-size: clamp(25px, 7.4vw, 33px); }
  .feed-credit { margin-top: 12px; }
  .home-quick-actions { margin-top: 15px; }
  .home-quick-actions button { min-height: 50px; }
  .feed-actions { margin-top: 13px; padding-top: 12px; }
}

@media (min-width: 921px) {
  /* Discover is the editorial home; map is intentionally kept in its own workspace. */
  body[data-desktop-screen="discover"] .desktop-layout { grid-template-columns: minmax(0, 1fr) minmax(280px, 330px); gap: clamp(30px, 4vw, 64px); }
  body[data-desktop-screen="discover"] .primary-column { display: grid; align-content: start; gap: 32px; }
  body[data-desktop-screen="discover"] .hero-story { min-height: min(570px, calc(100svh - 185px)); }
  body[data-desktop-screen="discover"] .editor-picks { padding: 8px 0 0; }
  body[data-desktop-screen="discover"] .story-grid { margin-top: 20px; }
  body[data-desktop-screen="discover"] .map-preview { display: none; }
  body[data-desktop-screen="discover"] .news-section { margin-top: 4px; padding-top: 28px; }
  body[data-desktop-screen="discover"] .recommend-rail { padding-top: 8px; }
  body[data-desktop-screen="discover"] .recommend-list { gap: 14px; margin-top: 18px; }
  body[data-desktop-screen="discover"] .quote-card { margin-top: 26px; }
  body[data-desktop-screen="discover"] .explore-meter { margin-top: 16px; }
}

@media (min-width: 921px) {
  .app-shell { gap: 18px; padding: 14px; }
  .side-rail { top: 14px; height: calc(100svh - 28px); border-radius: 28px; background: linear-gradient(165deg, rgba(21,60,53,.98), rgba(15,45,40,.94)); box-shadow: 0 18px 52px rgba(24,53,46,.18), inset 0 1px 0 rgba(255,255,255,.1); }
  .nav-item { min-height: 58px; border-radius: 17px; transition: color 260ms var(--desktop-ease), background 320ms var(--desktop-ease), transform 320ms var(--desktop-ease), box-shadow 320ms var(--desktop-ease); }
  .nav-item:hover { transform: translateX(2px); background: rgba(211,234,219,.1); }
  .nav-item.is-active { background: rgba(235,246,237,.16); box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 8px 22px rgba(0,0,0,.08); }
  .desktop-view-context { min-width: 178px; }
  .desktop-view-context span { font-size: 8px; letter-spacing: .22em; }
  .desktop-view-context strong { font-size: 21px; }
  .search-box { height: 46px; border-color: rgba(32,59,51,.12); background: rgba(255,255,255,.58); box-shadow: 0 8px 26px rgba(32,59,51,.04); transition: width 360ms var(--desktop-ease), border-color 220ms ease, box-shadow 220ms ease; }
  .search-box:focus-within { width: min(420px, 48vw); border-color: rgba(32,59,51,.35); box-shadow: 0 12px 30px rgba(32,59,51,.1); }
  .desktop-layout, body[data-desktop-screen="map"] .desktop-layout #map, body[data-desktop-screen="guides"] .desktop-layout #guides, body[data-desktop-screen="vr"] .mobile-screen[data-screen="vr"], body[data-desktop-screen="profile"] .mobile-screen[data-screen="profile"] { animation: desktop-screen-in 520ms var(--desktop-ease) both; }
  .hero-story { box-shadow: 0 24px 70px rgba(23,53,45,.14), inset 0 1px 0 rgba(255,255,255,.18); }
  .hero-story img { transition: transform 900ms var(--desktop-ease), filter 600ms ease; }
  .hero-story:hover img { transform: scale(1.025); filter: saturate(.84) contrast(.97); }
  .story-card, .recommend-row, .quote-card, .explore-meter, .map-preview, .route-highlight, .profile-links button, .profile-links a { transition: transform 420ms var(--desktop-ease), box-shadow 420ms var(--desktop-ease), border-color 220ms ease, background 220ms ease; }
  .story-card:hover, .map-preview:hover, .quote-card:hover, .explore-meter:hover { transform: translateY(-4px); box-shadow: 0 22px 52px rgba(32,59,51,.13); }
  .recommend-row:hover { transform: translateX(4px); background: rgba(255,255,255,.74); box-shadow: 0 8px 24px rgba(32,59,51,.06); }
  .outline-button, .dark-button, .text-button { transition: transform 260ms var(--desktop-ease), background 220ms ease, border-color 220ms ease, color 220ms ease; }
  .outline-button:hover, .dark-button:hover, .text-button:hover { transform: translateY(-2px); }
  .reduce-motion *, .reduce-motion *::before, .reduce-motion *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
}

/* ==========================================================================
   Motion & interaction polish
   --------------------------------------------------------------------------
   Layered last on purpose: these rules adjust timing and add gesture behaviour
   to components defined above, so they need to win by source order.
   Everything here is transform/opacity only, and everything is neutralised by
   `.reduce-motion` and by `prefers-reduced-motion` (see the end of the file).
   ========================================================================== */

/* ------------------------------------------------------------- presentation
   `<dialog>` gets its `[open]` attribute synchronously, so a plain transition
   has no previous state to move from. Keyframes are used instead, applied via
   a temporary class that JS removes on `animationend` — keeping a filled
   animation on the element would otherwise out-rank the inline transform used
   by the drag-to-dismiss gesture. */
dialog[open] {
  transition: opacity var(--dur-3) var(--ease-spring), transform var(--dur-3) var(--ease-spring);
}
dialog::backdrop { transition: opacity var(--dur-2) var(--ease-out); }
/* `@starting-style` gives the opening state for a `display`/top-layer change,
   which a plain transition cannot see. Using it instead of a filled keyframe
   animation matters here: a filled animation keeps re-applying `transform`,
   which would out-rank the inline transform the drag gesture writes. */
@starting-style {
  dialog[open] { opacity: 0; transform: translateY(16px) scale(.965); }
  dialog[open]::backdrop { opacity: 0; }
}
/* Closing has to be driven by JS (the element leaves the top layer as soon as
   `close()` runs), so it is expressed as a target state instead. */
dialog.is-dismissing { opacity: 0; transform: translateY(12px) scale(.97); }
dialog.is-dismissing::backdrop { opacity: 0; }

/* On mobile the same dialogs are bottom sheets, so they rise from the edge. */
@media (max-width: 680px) {
  @starting-style {
    dialog[open] { opacity: 1; transform: translateY(100%); }
  }
  dialog.is-dismissing { opacity: 1; transform: translateY(100%); }
}

/* ---------------------------------------------------------- press feedback
   `:active` only overrides the timing, never the base transition list. That is
   what makes the press feel attached to the finger: the finger-down state lands
   in ~90ms, while the release keeps whatever slower spring the component
   already declares. */
.story-card:active, .recommend-row:active, .quote-card:active, .explore-meter:active,
.map-preview:active, .route-highlight:active, .story-image-button:active,
.outline-button:active, .dark-button:active, .text-button:active, .nav-item:active,
.map-selection-item:active, .mobile-guide-row:active, .home-quick-actions button:active,
.feed-action:active, .save-button:active, .mobile-tab:active, .icon-button:active,
.avatar-button:active, .dialog-close:active, .map-filter:active, .map-pin:active,
.privacy-actions button:active, .profile-links button:active, .profile-links a:active,
.story-top-button:active, .map-filter-button:active, .feedback-actions button:active,
.article-dialog-references a:active, .privacy-account-actions button:active,
.mobile-destination-row .dark-button:active {
  transition-duration: var(--dur-press);
  transition-timing-function: var(--ease-out);
}

/* Cards and rows sink slightly rather than shrinking evenly — a uniform scale
   on a large surface reads as a rendering glitch. */
.story-card:active, .quote-card:active, .explore-meter:active, .map-preview:active,
.map-selection-item:active, .mobile-guide-row:active, .recommend-row:active,
.article-dialog-references a:active, .profile-links button:active, .profile-links a:active {
  transform: scale(.982);
}
/* Controls shrink a little more, which is what sells a tap. */
.outline-button:active, .dark-button:active, .text-button:active, .icon-button:active,
.avatar-button:active, .dialog-close:active, .story-top-button:active, .map-filter:active,
.map-filter-button:active, .feedback-actions button:active, .privacy-actions button:active,
.privacy-account-actions button:active, .home-quick-actions button:active,
.mobile-destination-row .dark-button:active {
  transform: scale(.955);
}
.feed-action:active, .save-button:active, .mobile-tab:active, .nav-item:active, .map-pin:active {
  transform: scale(.9);
}

/* Components above that declared no transition of their own. Without these the
   release would snap instead of springing back. */
.story-card, .recommend-row, .quote-card, .explore-meter, .map-preview, .route-highlight,
.map-selection-item, .mobile-guide-row, .home-quick-actions button, .feed-action,
.save-button, .mobile-tab, .map-filter, .map-pin, .story-top-button, .map-filter-button,
.feedback-actions button, .privacy-actions button, .privacy-account-actions button,
.article-dialog-references a, .story-image-button {
  transition: transform var(--dur-3) var(--ease-spring),
              box-shadow var(--dur-2) var(--ease),
              border-color var(--dur-1) var(--ease),
              background-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease);
}
.icon-button, .avatar-button, .dialog-close {
  transition: transform var(--dur-3) var(--ease-spring),
              background-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease),
              border-color var(--dur-1) var(--ease);
}
.profile-links button, .profile-links a {
  transition: transform var(--dur-3) var(--ease-spring),
              border-color var(--dur-1) var(--ease),
              background-color var(--dur-1) var(--ease);
}

/* --------------------------------------------------------------- toast
   A toast is transient, so it gets a spring and a touch of scale — it should
   feel like it was tossed onto the screen, not faded in. */
.toast {
  transform: translate(-50%, 18px) scale(.94);
  transition: opacity var(--dur-2) var(--ease-out),
              transform var(--dur-3) var(--ease-spring);
  will-change: transform, opacity;
}
.toast.is-visible { transform: translate(-50%, 0) scale(1); }

/* ------------------------------------------------------- saved-state pop
   Filling the heart is the one place a visible overshoot is welcome. */
@keyframes save-pop {
  0% { transform: scale(1); }
  38% { transform: scale(1.34); }
  100% { transform: scale(1); }
}
.save-button.is-popping, .feed-action.is-popping b { animation: save-pop 460ms var(--ease-spring) both; }

/* ---------------------------------------------------- scroll-driven effects
   Reveal-on-enter, staggered by index so a grid arrives as a wave.

   The hidden state is gated behind `.motion-ready`, which JS adds only after
   the observer is actually running. Without that gate a script error (or an
   engine without IntersectionObserver) would leave every card at opacity 0 —
   content invisible because an animation failed to start. */
.reveal { opacity: 1; }
.motion-ready .reveal { opacity: 0; transform: translateY(18px); }
.motion-ready .reveal.is-revealed {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-4) var(--ease-out), transform var(--dur-4) var(--ease-spring);
  transition-delay: var(--reveal-delay, 0ms);
}

/* Parallax on the hero photograph. The image is oversized so translating it
   never exposes an edge.

   The 900ms transform transition declared for the hover zoom has to be
   overridden: a scroll-driven transform with a 900ms tail visibly lags the
   page. 120ms linear keeps the parallax tracking the scroll while still
   easing the hover change. */
.hero-story img {
  transform: translate3d(0, var(--hero-parallax, 0px), 0) scale(1.08);
  transition: transform 120ms linear, filter 700ms ease;
  will-change: transform;
}
@media (min-width: 921px) {
  .hero-story:hover img { transform: translate3d(0, var(--hero-parallax, 0px), 0) scale(1.1); }
}

/* The mobile tab bar retracts while scrolling down and returns on the way up,
   the way iOS hides chrome to give content the screen. */
@media (max-width: 680px) {
  .mobile-tabbar {
    transition: transform var(--dur-3) var(--ease-spring), opacity var(--dur-2) var(--ease);
    will-change: transform;
  }
  .mobile-tabbar.is-retracted { transform: translate3d(0, calc(100% + 1px), 0); }
}

/* --------------------------------------------------- mobile sheet gestures
   While a finger is down the sheet must track it exactly, so transitions are
   switched off entirely; they come back for the settle. */
@media (max-width: 680px) {
  .story-dialog { will-change: transform; }
  .story-dialog.is-dragging { transition: none; }
  .story-dialog.is-settling { transition: transform var(--dur-3) var(--ease-spring); }
  /* The grab area: the handle plus the top of the copy block. */
  .story-sheet-handle { touch-action: none; cursor: grab; }
  .story-sheet-handle::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -14px;
    height: 46px;
  }
  .story-dialog-copy { position: relative; }

  .map-place-sheet {
    will-change: transform;
    transition: transform var(--dur-3) var(--ease-spring);
  }
  .map-place-sheet.is-dragging { transition: none; }
  .map-place-sheet::before { cursor: grab; }
}

/* ------------------------------------------------- interactive discover rail
   `row-open-button` is a transparent full-bleed overlay (z-index 1). Anything
   inside the same row that must stay tappable has to be lifted above it, or the
   overlay swallows the click. */
/* The full-bleed `row-open-button` sits at z-index 1, so the heart has to be
   lifted above it or the overlay swallows the click.
   The two cards need *different* positioning though: `.recommend-row`'s heart is
   `static` in its own rule, while `.story-card`'s is `absolute; right; bottom`.
   Forcing `position: relative` on both un-pinned the story-card heart and it
   drifted into the text — which is what "赞的按钮漂移了" was. */
.recommend-row .save-button {
  position: relative;
  z-index: 2;
}
.story-card .save-button {
  /* Keep the base `absolute` placement; only raise the stacking order. */
  z-index: 2;
}
.story-card-copy { position: relative; }

/* Both cards previously looked inert. Give them the same affordance the news
   rows already had, so it is obvious they respond. */
.quote-card.is-interactive,
.explore-meter.is-interactive {
  cursor: pointer;
}
.explore-meter.is-interactive { border-radius: var(--radius-md); }
.quote-card.is-interactive p,
.quote-card p {
  transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.quote-card.is-swapping p { opacity: 0; transform: translateY(-6px); }
.quote-card.is-interactive::after {
  content: "换一句 ↻";
  position: absolute;
  right: 20px;
  bottom: 18px;
  color: rgba(249, 251, 246, .62);
  font-size: 10px;
  letter-spacing: .08em;
}
.quote-card { position: relative; }
.explore-meter.is-interactive::after {
  content: "查看进度 →";
  display: block;
  margin-top: 10px;
  color: var(--accent);
  font-size: 11px;
  letter-spacing: .06em;
}
.explore-meter.is-interactive:hover { border-color: rgba(32, 59, 51, .3); }

/* Admin map picker: the unavailable state must look deliberate rather than
   like a broken empty box. */
.admin-map-picker.is-unavailable {
  display: grid;
  place-items: center;
  border-style: dashed;
  background: repeating-linear-gradient(45deg, #eef2ee, #eef2ee 10px, #e6ece7 10px, #e6ece7 20px);
}
.admin-map-picker-fallback { margin: 0; padding: 0 18px; color: var(--muted); font-size: 12px; line-height: 1.6; text-align: center; }

/* Hypertext disabled by the administrator: the editors say so in place, rather
   than offering tools whose output would never be rendered. */
.hypertext-disabled-note {
  margin: 0;
  padding: 10px 12px;
  border: 1px dashed rgba(156, 97, 68, .45);
  border-radius: 12px;
  color: #7a4a33;
  background: rgba(211, 154, 86, .1);
  font-size: 12px;
  line-height: 1.6;
}
.rich-editor.is-hypertext-disabled .rich-editor-heading { margin-bottom: 8px; }
.rich-editor-plain {
  width: 100%;
  min-height: 220px;
  padding: 12px 13px;
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--ink);
  background: #fff;
  font: inherit;
  font-size: 13px;
  line-height: 1.7;
  resize: vertical;
}
.rich-editor-plain:focus { outline: 2px solid rgba(47, 105, 92, .24); border-color: var(--forest); }

/* ------------------------------------------------ shared editor: VR + preview
   Used by both the admin console and the public publish form. */
.vr-link-field { display: grid; gap: 6px; }
.vr-link-field input.is-invalid { border-color: #b4543f; background: rgba(180, 84, 63, .06); }
.field-hint { color: var(--muted); font-size: 11px; line-height: 1.55; }
.field-error { min-height: 15px; color: #b4543f; font-size: 11px; line-height: 1.5; }

.content-preview-wrap {
  display: grid;
  gap: 10px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.content-preview-heading { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.content-preview-heading strong { color: var(--forest); font-family: serif; font-size: 17px; font-weight: 500; }
.content-preview-heading small { color: var(--muted); font-size: 11px; }
.content-preview-body { max-height: 420px; overflow-y: auto; overscroll-behavior: contain; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); }

.content-preview { display: grid; }
.preview-cover { aspect-ratio: 16 / 9; overflow: hidden; background: #e8ece7; }
.preview-cover img { width: 100%; height: 100%; object-fit: cover; }
.preview-cover.is-empty { display: grid; place-items: center; color: var(--muted); font-size: 12px; }
.preview-body { display: grid; gap: 8px; padding: 16px 18px 20px; }
.preview-kind { color: var(--accent); font-size: 11px; letter-spacing: .1em; }
.preview-title { margin: 0; font-family: serif; font-size: 23px; font-weight: 400; line-height: 1.25; }
.preview-summary { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.6; }
.preview-content { color: var(--ink); font-size: 14px; line-height: 1.8; }
.preview-content h2 { margin: 16px 0 8px; font-family: serif; font-size: 20px; font-weight: 400; }
.preview-content h3 { margin: 14px 0 6px; font-size: 15px; }
.preview-content img { max-width: 100%; border-radius: 10px; }
.preview-content a { color: var(--forest); }
.preview-placeholder { margin: 0; color: var(--muted); font-size: 12px; }
.preview-vr { display: flex; align-items: center; gap: 10px; padding: 11px 12px; border: 1px solid rgba(47, 105, 92, .22); border-radius: 12px; background: rgba(47, 105, 92, .06); }
.preview-vr-mark { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 9px; color: #fff; background: var(--forest); font-size: 11px; letter-spacing: .04em; }
.preview-vr strong { display: block; font-size: 12px; }
.preview-vr small { color: var(--muted); font-size: 11px; word-break: break-all; }

/* ------------------------------------------------------------ reset password
   Standalone page reached from the link in the reset e-mail. Deliberately
   minimal: it must work for someone who is locked out and has no session. */
.reset-page { min-height: 100svh; background: radial-gradient(circle at 76% 0%, #ffffff 0, var(--paper) 46%, #eef1ec 100%); }
.reset-shell { display: grid; gap: 18px; align-content: start; justify-items: center; width: min(460px, calc(100vw - 32px)); margin: 0 auto; padding: clamp(40px, 12svh, 120px) 0 60px; }
.reset-brand { color: var(--forest); font-family: serif; font-size: 20px; letter-spacing: .12em; text-decoration: none; }
.reset-card { width: 100%; padding: 30px; border: 1px solid var(--line); border-radius: 24px; background: var(--surface); box-shadow: 0 24px 80px rgba(18, 47, 42, .14); }
.reset-card h1 { margin: 7px 0 10px; font-family: serif; font-size: 27px; font-weight: 400; line-height: 1.2; }
.reset-lead { margin: 0 0 20px; color: var(--muted); font-size: 13px; line-height: 1.7; }
.reset-card .auth-status[data-tone="error"] { color: #b4543f; }
.reset-card .auth-status[data-tone="ok"] { color: var(--forest); }
.reset-back { display: inline-block; margin-top: 16px; padding: 0; }

/* Settings that are stored and rendered but not yet read by any code. Shown
   rather than hidden: an administrator who flips a switch and sees nothing
   happen deserves to know it was never wired up. */
.runtime-not-implemented {
  display: inline-block;
  margin-right: 6px;
  padding: 1px 7px;
  border: 1px solid rgba(156, 97, 68, .45);
  border-radius: 999px;
  color: #7a4a33;
  background: rgba(211, 154, 86, .12);
  font-size: 10px;
  letter-spacing: .04em;
  vertical-align: 1px;
}
/* `.runtime-config-label` is a 2-column grid that pins `<small>` to column 2, so
   the badge — a fourth child — would otherwise be auto-placed into column 1,
   which is the 8px status-dot track: it measured 16px wide and wrapped to one
   character per line. `justify-self` keeps it hugging the label text. */
.runtime-config-label .runtime-not-implemented { grid-column: 2; display: inline-block; justify-self: start; margin-right: 0; }

/* Multi-select chips for the resource-type picker. */
.check-chip-set {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #fff;
}
.check-chip-set legend { padding: 0 6px; color: var(--muted); font-size: 12px; }
.check-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font-size: 12px;
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.check-chip:has(input:checked) { border-color: var(--forest); color: var(--forest); background: rgba(47, 105, 92, .1); }
.check-chip:active { transform: scale(.97); }
.check-chip input { margin: 0; }

/* ------------------------------------------------------- submissions & review
   Author-facing progress list, and the decision bar inside a draft preview. */
.submissions-lead { margin: 0 0 16px; color: var(--muted); font-size: 12px; line-height: 1.6; }
.submissions-list { display: grid; gap: 10px; max-height: min(60svh, 520px); overflow-y: auto; overscroll-behavior: contain; }
.submission-row { padding: 13px 14px; border: 1px solid var(--line); border-radius: 14px; background: #fff; }
.submission-row h3 { margin: 8px 0 4px; font-family: serif; font-size: 17px; font-weight: 400; }
.submission-meta { margin: 0; color: var(--muted); font-size: 11px; }
.submission-note { margin: 9px 0 0; padding: 8px 10px; border-radius: 10px; color: #7a4a33; background: rgba(211, 154, 86, .12); font-size: 12px; line-height: 1.6; }
.submission-status { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 10px; letter-spacing: .06em; }
.submission-status.is-draft { color: var(--muted); background: #eef0ec; }
.submission-status.is-pending { color: #8a6320; background: rgba(211, 154, 86, .18); }
.submission-status.is-published { color: #1f5b4a; background: rgba(47, 105, 92, .14); }
.submission-status.is-rejected { color: #9c3f2c; background: rgba(180, 84, 63, .14); }

.draft-preview-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.draft-preview .content-preview { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.draft-preview .preview-body { padding: 16px; }

/* VR reference rows: guides and routes carry a list, not a single link. */
.vr-ref-set { display: grid; gap: 10px; margin: 0; padding: 14px; border: 1px solid var(--line); border-radius: 14px; background: #fff; }
.vr-ref-set legend { padding: 0 6px; color: var(--forest); font-family: serif; font-size: 16px; }
.vr-ref-set .field-hint { margin: 0; }
.vr-ref-rows { display: grid; gap: 10px; }
.vr-ref-row { display: grid; gap: 8px; padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.vr-ref-row label { display: grid; gap: 5px; color: var(--muted); font-size: 12px; }
.vr-ref-row input[type="text"], .vr-ref-row input:not([type]) { min-height: 38px; padding: 0 11px; border: 1px solid var(--line); border-radius: 10px; color: var(--ink); background: #fff; font: inherit; font-size: 13px; }
.vr-ref-row-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.vr-ref-row .editor-check { display: inline-flex; align-items: center; gap: 6px; }
.vr-ref-add { justify-self: start; min-height: 36px; padding-inline: 14px; font-size: 12px; }
.preview-vr-list { display: grid; gap: 8px; }

/* -------------------------------------------------------------- VR attractions
   The catalogue is 85 attractions that each carry a 360° tour, so VR is the
   main asset. The grid is deliberately image-led and the badge is the only
   chrome on the card. */
.vr-screen-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 22px 0 12px; }
.vr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.vr-strip-track { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; margin-top: 18px; }
.vr-strip { margin-top: 34px; }

.vr-card {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--surface);
  text-align: left;
  cursor: pointer;
}
.vr-card img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; filter: saturate(.86); }
.vr-card-badge {
  position: absolute;
  top: 9px;
  left: 9px;
  display: grid;
  place-items: center;
  min-width: 30px;
  height: 21px;
  padding: 0 7px;
  border-radius: 7px;
  color: #fff;
  background: rgba(11, 24, 21, .78);
  backdrop-filter: blur(8px);
  font-size: 10px;
  letter-spacing: .08em;
}
.vr-card-copy { display: block; padding: 10px 11px 12px; }
.vr-card-copy strong { display: block; overflow: hidden; color: var(--ink); font-family: serif; font-size: 14px; font-weight: 400; line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; }
.vr-card-copy small { display: block; margin-top: 4px; overflow: hidden; color: var(--muted); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
.vr-card::after {
  content: "进入 VR";
  position: absolute;
  right: 10px;
  top: 9px;
  padding: 2px 8px;
  border-radius: 999px;
  color: #fff;
  background: rgba(47, 105, 92, .86);
  font-size: 10px;
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease);
}
.vr-card:hover::after, .vr-card:focus-visible::after { opacity: 1; }

/* Admin content pager: the list endpoint caps at 50 per page. */
.content-pager { display: flex; align-items: center; gap: 12px; margin-top: 14px; }
.content-pager .outline-button { min-height: 36px; padding-inline: 16px; font-size: 12px; }
.content-page-info { color: var(--muted); font-size: 11px; }

/* ------------------------------------------------------------- reduced motion
   The existing `.reduce-motion` rule collapses durations; this also stops the
   transforms from being applied at all, so nothing shifts position for someone
   who asked for stillness. */
@media (prefers-reduced-motion: reduce) {
  .motion-ready .reveal { opacity: 1; transform: none; }
  .toast, .toast.is-visible { transform: translate(-50%, 0); }
  .hero-story img { transform: none; }
  .mobile-tabbar.is-retracted { transform: none; }
}
.reduce-motion .motion-ready .reveal { opacity: 1 !important; transform: none !important; }
.reduce-motion .hero-story img { transform: none !important; }
.reduce-motion .mobile-tabbar.is-retracted { transform: none !important; }
.reduce-motion .toast, .reduce-motion .toast.is-visible { transform: translate(-50%, 0) !important; }

/* ------------------------------------------------- dashboard analytics
   The 访问量统计 card lives inside the existing 工作台 grid and reuses
   .admin-card / .admin-dashboard-list / .dashboard-row so it matches the
   neighbouring panels. Bars are plain elements, no charting library. */
.admin-analytics-range { color: #aca39a; font-size: 11px; }
.admin-analytics-totals { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 12px; margin-bottom: 18px; }
.admin-analytics-totals > div { min-width: 0; padding: 12px 14px; border: 1px solid #f1ede7; border-radius: 12px; background: #fdfbf8; }
.admin-analytics-totals small { display: block; color: #9c958c; font-size: 11px; }
.admin-analytics-totals strong { display: block; margin-top: 4px; color: #282421; font-family: Georgia,serif; font-size: 24px; font-weight: 500; }
.admin-analytics-columns { display: grid; grid-template-columns: minmax(0,1.25fr) minmax(0,1fr); gap: 22px; }
.admin-analytics-subheading { margin: 0 0 8px; color: #6d655e; font-size: 12px; font-weight: 600; letter-spacing: .04em; }
.admin-analytics-bar { display: block; width: 90px; height: 6px; border-radius: 3px; background: #f1ede7; overflow: hidden; }
.admin-analytics-bar i { display: block; height: 100%; border-radius: 3px; background: #c98a6f; }
/* The trend and path lists reuse `.dashboard-row` (min-height 48px) from the
   moderation list, so 14 days alone cost 672px and made 访问量统计 the tallest
   card on the dashboard even when every day was zero. Scoped to the analytics
   columns so the moderation rows keep their comfortable height, and set in a
   tabular figure so the PV/UV columns line up down the list. */
.admin-analytics-columns .dashboard-row { min-height: 32px; gap: 12px; }
.admin-analytics-columns .dashboard-row strong { color: #8d857c; font-size: 11px; font-weight: 400; }
.admin-analytics-columns .dashboard-row small { font-size: 11px; font-variant-numeric: tabular-nums; }
.admin-analytics-columns .admin-analytics-bar { width: 72px; }
.admin-analytics-columns .dashboard-row + .dashboard-row { border-top-color: #f6f3ee; }
@media (max-width: 920px) {
  .admin-analytics-totals { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .admin-analytics-columns { grid-template-columns: 1fr; }
}
