/* ============================================================================
   Voyscout — app.css
   Single, self-contained, framework-agnostic stylesheet for the Cloudflare
   Worker. Drop this one file in; theme via CSS variables + prefers-color-scheme
   with a manual [data-theme] override on <html>. No web fonts, no build step.
   (This is the productionized form of the design-system tokens in /tokens.)
   ============================================================================ */

/* ── 1. Design tokens ─────────────────────────────────────────────────────── */
:root {
  color-scheme: light dark;

  /* iOS safe-area insets, read through CSS vars so the visual harness can SHIM them. Headless
     Chromium resolves env() to 0, and the env() fallback arg fires only when env() is UNSUPPORTED
     (never at a real 0), so raw env() is untestable. Every consumer uses var(--sa-*) — NEVER raw
     env() — and guards with max(token, var) so a 0 inset is a strict no-op. Prod resolves each to
     the real device inset; desktop / non-notched → 0px → zero visual change. */
  --sa-top:    env(safe-area-inset-top, 0px);
  --sa-right:  env(safe-area-inset-right, 0px);
  --sa-bottom: env(safe-area-inset-bottom, 0px);
  --sa-left:   env(safe-area-inset-left, 0px);

  /* neutral ramp (Apple grays) */
  --c-white:   #ffffff;
  --c-gray-50: #f5f5f7;
  --c-gray-100:#ebebef;
  --c-gray-150:#dcdce1;
  --c-gray-200:#d2d2d7;
  --c-ink:     #1d1d1f;
  --c-ink-2:   #6e6e73;
  --c-ink-3:   #86868b;
  --c-ink-4:   #a1a1a6;

  /* accent */
  --c-blue:    #0071e3;
  --c-blue-2:  #2997ff;

  /* verdict */
  --c-green:   #1d8a4e;  --c-green-fill:#e3f5ea;
  --c-amber:   #9a6700;  --c-amber-fill:#fff4d6;
  --c-red:     #d70015;  --c-red-fill:  #ffe5e7;

  /* ── semantic aliases — LIGHT (default) ── */
  --bg:            #ffffff;
  --bg-elevated:   #ffffff;
  --surface:       #f5f5f7;   /* cards, fills */
  --surface-2:     #ebebef;
  --sidebar-bg:    #fbfbfd;
  --border:        #d2d2d7;
  --hairline:      #e3e3e8;
  --text:          #1d1d1f;
  --text-2:        #6e6e73;
  --text-3:        #86868b;
  --text-4:        #a1a1a6;
  --accent:        #0071e3;
  --accent-soft:   rgba(0,113,227,0.10);
  --on-accent:     #ffffff;

  --buy:      #1d8a4e;  --buy-fill: #e3f5ea;
  --wait:     #9a6700;  --wait-fill:#fff4d6;
  /* re-scan NOTICE semantic (light) — saturated amber accent (stripe/icon/border) + warm-dark body text
     readable on the cream fill. Distinct from the verdict --wait, which has no contrast on light. */
  --notice:#c77a00; --notice-fill:#fdf1cd; --notice-border:#ecc56a; --notice-text:#5c4608;
  --watch:    #6e6e73;  --watch-fill:#ebebef;
  --alert:    #d70015;  --alert-fill:#ffe5e7;
  --skeleton: linear-gradient(90deg,#ececf0 25%,#f5f5f7 37%,#ececf0 63%);

  /* type */
  --font: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  --font-mono: var(--mono);   /* alias used by §27/§28 (analytics dtable mono cells) */

  /* radii */
  --r-sm: 8px;  --r-md: 10px;  --r-lg: 12px;  --r-xl: 18px;  --r-pill: 980px;

  /* spacing */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:24px; --s7:30px; --s8:40px;

  /* depth — restrained */
  --shadow-pop: 0 4px 24px rgba(0,0,0,.10), 0 1px 3px rgba(0,0,0,.06);
  --shadow-raise: 0 1px 2px rgba(0,0,0,.06);
  --shadow-seg: 0 1px 3px rgba(0,0,0,.12);

  /* motion */
  --ease: cubic-bezier(.4,0,.2,1);
  --dur: 200ms; --dur-fast: 120ms;

  /* layout */
  --sidebar-w: 248px;
  --rail-w: 312px;
  --focus: 0 0 0 3px var(--accent-soft);
}

/* dark token set, shared by forced-dark and system-dark */
:root[data-theme="dark"]                                  { color-scheme: dark; }
@media (prefers-color-scheme: dark) { :root[data-theme="system"] { color-scheme: dark; } }

:root[data-theme="dark"],
:root[data-theme="system"] { /* values applied in the two rules below */ }

:root[data-theme="dark"] {
  --bg:            #000000;
  --bg-elevated:   #1c1c1e;
  --surface:       #1c1c1e;
  --surface-2:     #2c2c2e;
  --sidebar-bg:    #0a0a0b;
  --border:        #38383a;
  --hairline:      #2a2a2c;
  --text:          #f5f5f7;
  --text-2:        #a1a1a6;
  --text-3:        #8e8e93;
  --text-4:        #6e6e73;
  --accent:        #2997ff;
  --accent-soft:   rgba(41,151,255,0.16);
  --buy:  #30d158;  --buy-fill: rgba(48,209,88,.16);
  --wait: #ffd60a;  --wait-fill:rgba(255,214,10,.16);
  --notice:#ffd60a; --notice-fill:rgba(255,214,10,.13); --notice-border:rgba(255,214,10,.30); --notice-text:#f1e7c4;
  --watch:#a1a1a6;  --watch-fill:#2c2c2e;
  --alert:#ff453a;  --alert-fill:rgba(255,69,58,.16);
  --skeleton: linear-gradient(90deg,#1c1c1e 25%,#2a2a2c 37%,#1c1c1e 63%);
  --shadow-pop: 0 4px 24px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.4);
  --shadow-raise: none;
  --shadow-seg: 0 1px 2px rgba(0,0,0,.5);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] {
    --bg:#000000; --bg-elevated:#1c1c1e; --surface:#1c1c1e; --surface-2:#2c2c2e;
    --sidebar-bg:#0a0a0b; --border:#38383a; --hairline:#2a2a2c;
    --text:#f5f5f7; --text-2:#a1a1a6; --text-3:#8e8e93; --text-4:#6e6e73;
    --accent:#2997ff; --accent-soft:rgba(41,151,255,0.16);
    --buy:#30d158; --buy-fill:rgba(48,209,88,.16);
    --wait:#ffd60a; --wait-fill:rgba(255,214,10,.16);
    --notice:#ffd60a; --notice-fill:rgba(255,214,10,.13); --notice-border:rgba(255,214,10,.30); --notice-text:#f1e7c4;
    --watch:#a1a1a6; --watch-fill:#2c2c2e;
    --alert:#ff453a; --alert-fill:rgba(255,69,58,.16);
    --skeleton: linear-gradient(90deg,#1c1c1e 25%,#2a2a2c 37%,#1c1c1e 63%);
    --shadow-pop: 0 4px 24px rgba(0,0,0,.5), 0 1px 3px rgba(0,0,0,.4);
    --shadow-raise:none; --shadow-seg:0 1px 2px rgba(0,0,0,.5);
  }
}

/* ── 2. Base / reset ──────────────────────────────────────────────────────── */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: none; opacity: .8; }
button { font-family: inherit; }
h1,h2,h3,p { margin: 0; }
:focus-visible { outline: none; box-shadow: var(--focus); border-radius: var(--r-sm); }

.eyebrow {
  font-size: 11px; font-weight: 600; letter-spacing: 1.1px; text-transform: uppercase;
  color: var(--text-3);
}
.muted { color: var(--text-3); }
.tnum { font-variant-numeric: tabular-nums; }

/* ── 3. App shell (the BASE LAYOUT: sidebar | main[ topbar + content + rail ]) ── */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0,1fr);
  min-height: 100vh;
}
.main { display: flex; flex-direction: column; min-width: 0; }
.content-wrap {
  display: grid;
  grid-template-columns: minmax(0,1fr) var(--rail-w);
  gap: var(--s8);
  align-items: start;
  /* right/bottom insets for landscape-notch + home indicator (desktop → the original --s8). The
     ≤860 block re-pads all sides to --s5 and overrides padding-bottom to 66px + var(--sa-bottom) for
     the fixed tab bar, so this base rule only bites on wide (desktop / iPad-landscape) viewports. */
  padding: var(--s7) max(var(--s8), var(--sa-right)) max(var(--s8), var(--sa-bottom)) var(--s8);
  max-width: 1280px;
  width: 100%;
}
.content-wrap.no-rail { grid-template-columns: minmax(0,1fr); max-width: 920px; }
.content { min-width: 0; }

/* ── 4. Sidebar ───────────────────────────────────────────────────────────── */
.sidebar {
  background: var(--sidebar-bg);
  border-right: 1px solid var(--hairline);
  display: flex; flex-direction: column;
  /* landscape-notch safe area: pad the LEFT (wordmark + nav + account row) past a left-edge cutout,
     and top/bottom past the island / home indicator — the mobile drawer (≤860, position:fixed
     left:0 top:0) inherits this so its brand clears the notch too. Right stays the interior --s4
     edge (never against a cutout). All max()'d so non-notched → the original var(--s5)/var(--s4). */
  padding: max(var(--s5), var(--sa-top)) var(--s4) max(var(--s5), var(--sa-bottom)) max(var(--s4), var(--sa-left));
  position: sticky; top: 0; height: 100vh;
  overflow: hidden;
}
/* faint breathing accent glow behind the wordmark — ambient, never loud */
.sidebar::before {
  content: ""; position: absolute; left: -25%; top: -8%; width: 150%; height: 280px;
  background: radial-gradient(58% 60% at 42% 0%, var(--accent) 0%, transparent 70%);
  opacity: .05; filter: blur(22px); pointer-events: none; z-index: 0;
}
.sidebar > * { position: relative; z-index: 1; }
@media (prefers-reduced-motion: no-preference) {
  .sidebar::before { animation: tb-breathe 14s ease-in-out infinite; }
}
@keyframes tb-breathe {
  0%,100% { opacity: .045; transform: translateY(0); }
  50%     { opacity: .10;  transform: translateY(10px); }
}
/* functional emoji that gently "breathes" (Sledované meta row) — subtle scale/opacity, never loud.
   Display-inline-block so the transform applies to the emoji glyph. */
.breathe { display: inline-block; transform-origin: 50% 60%; }
@media (prefers-reduced-motion: no-preference) {
  .breathe { animation: vs-breathe 4.5s ease-in-out infinite; }
}
@keyframes vs-breathe {
  0%,100% { transform: scale(1);    opacity: .85; }
  50%     { transform: scale(1.12); opacity: 1; }
}
/* date + party meta items (Sledované watch-meta) sit on a subtle rounded pill — mirrors the DS
   alerts.html .watch-meta .chip (surface-2 / r-pill). Inline-flex so the breathing emoji + text
   share one pill. */
.meta-pill {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--surface-2); border-radius: var(--r-pill); padding: 5px 11px;
}
.brand {
  display: flex; align-items: center; gap: 9px;
  font-size: 19px; font-weight: 600; letter-spacing: -.3px; color: var(--text);
  padding: 8px 10px 18px;
}
.brand .glyph {
  width: 26px; height: 26px; border-radius: 7px; flex: none;
  background: url("/assets/logo/voyscout-favicon.svg") center / 100% 100% no-repeat;
  color: transparent; font-size: 0;
}
.nav { display: flex; flex-direction: column; gap: 2px; }
.nav-label { padding: 14px 10px 6px; }
.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border-radius: var(--r-md);
  color: var(--text-2); font-size: 14px; font-weight: 500;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.nav-item .ni-ico { width: 18px; text-align: center; opacity: .85; font-size: 15px; display: inline-block; transition: transform var(--dur-fast) var(--ease); }
.nav-item .ni-badge {
  margin-left: auto; font-size: 11px; font-weight: 600; color: var(--text-3);
  background: var(--surface-2); border-radius: var(--r-pill); padding: 1px 8px;
}
/* amber "needs a fresh scan" dot on the Letenky nav item — same cue as the glowing Skenovat-teď button,
   shown only when the active profile's party differs from the 2A+2C scan (flightsMismatch). */
.nav-item .ni-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%; vertical-align: middle;
  background: var(--notice); box-shadow: 0 0 0 3px var(--notice-fill);
}
.nav-item:hover { background: var(--surface); color: var(--text); }
.nav-item.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.nav-item.active .ni-ico { opacity: 1; }
.sidebar-foot { margin-top: auto; padding-top: var(--s4); }
.account {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: var(--r-md); cursor: pointer;
  border: 1px solid var(--hairline);
}
.account:hover { background: var(--surface); }
.avatar {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: var(--surface-2); color: var(--text-2);
  display: grid; place-items: center; font-size: 13px; font-weight: 600;
}
.account .acc-email { font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account .acc-sub { font-size: 11px; color: var(--text-3); }
.account .chev { margin-left: auto; color: var(--text-4); }

/* ── 5. Topbar ────────────────────────────────────────────────────────────── */
.topbar {
  display: flex; align-items: center; gap: var(--s4);
  /* iOS standalone-PWA safe area. With apple-mobile-web-app-status-bar-style=black-translucent +
     viewport-fit=cover (ui.js <head>), web content extends under the status bar / Dynamic Island.
     Add the TOP inset ON TOP of the 60px bar (height bumped by the same var(--sa-top)) so the blurred
     bar background fills the notch region edge-to-edge while the row — hamburger, crumb, centered
     profile picker, CS/theme toggles — sits below it and stays tappable. Under box-sizing:border-box
     the padding+height cancel, keeping the usable content height at 60px. var(--sa-top) resolves to
     0 on desktop / non-notched devices → zero visual change there. padding-right is max()'d with the
     right inset for landscape-notch phones. Mirrors the .tabbar bottom-inset idiom (§30). Sticky
     top:0 still pins the bar (now taller) flush to the viewport top, so it stays covering the
     status-bar region on scroll — no detach, no gap. */
  padding: var(--sa-top) max(var(--s8), var(--sa-right)) 0 var(--s8);
  height: calc(60px + var(--sa-top));
  border-bottom: 1px solid var(--hairline);
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
}
.topbar .crumb { font-size: 15px; font-weight: 600; color: var(--text); }
.topbar .crumb .sep { color: var(--text-4); font-weight: 400; margin: 0 8px; }
.topbar .spacer { flex: 1; }
.topbar-actions { display: flex; align-items: center; gap: var(--s3); }
/* lang + theme toggle group. Lives in the topbar on desktop/landscape (>860px); on phones (≤860)
   it is hidden here and re-shown in the sidebar/drawer footer (.sidebar-toggles) so the narrow bar
   keeps only [☰ · crumb · profile pill] (Option-B declutter). */
.topbar-toggles { display: inline-flex; align-items: center; gap: var(--s3); }
.sidebar-toggles { display: none; }
.hamburger { display: none; background: none; border: 0; color: var(--text-2); cursor: pointer; font-size: 20px; padding: 4px; }

.helplink { color: var(--text-2); font-size: 13px; font-weight: 500; padding: 6px 10px; border-radius: var(--r-md); }
.helplink:hover { background: var(--surface); color: var(--text); opacity: 1; }

/* search */
.search {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid transparent;
  border-radius: var(--r-md); padding: 7px 12px; min-width: 220px;
  color: var(--text-3);
}
.search:focus-within { border-color: var(--accent); background: var(--bg-elevated); box-shadow: var(--focus); }
.search input { border: 0; background: none; outline: none; font: inherit; color: var(--text); width: 100%; }
.search .kbd { font-size: 11px; color: var(--text-4); border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px; }

/* ── 6. Theme toggle (segmented, tiny) ────────────────────────────────────── */
.seg {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--surface); border-radius: var(--r-pill);
}
.seg button {
  border: 0; cursor: pointer; background: none;
  font: inherit; font-size: 13px; font-weight: 500; color: var(--text-3);
  padding: 6px 14px; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; gap: 6px;
  transition: color var(--dur-fast) var(--ease);
}
.seg button[aria-pressed="true"], .seg button[aria-selected="true"] {
  background: var(--bg-elevated); color: var(--text); box-shadow: var(--shadow-seg);
}
.seg.icononly button { padding: 6px 10px; }

/* ── 6b. Profile switch — global active-profile picker (topbar, right) ─────────
   Switch the active profile from anywhere, no trip to Account settings. Shows
   the current profile + a dropdown of the rest; picking one switches instantly. */
.pp { position: relative; }
.pp-trigger {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-pill); padding: 5px 10px 5px 6px; cursor: pointer;
  font: inherit; color: var(--text); max-width: 230px;
}
.pp-trigger:hover { background: var(--surface-2); }
.pp-trigger .pp-flag {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-size: 14px;
  background: var(--accent-soft);
}
.pp-trigger .pp-cur { min-width: 0; text-align: left; line-height: 1.25; }
.pp-trigger .pp-cur b { display: block; font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-trigger .pp-cur small { font-size: 10.5px; color: var(--text-3); letter-spacing: .2px; }
.pp-trigger .pp-caret { color: var(--text-4); font-size: 12px; margin-left: 2px; flex: none; }

.pp-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  width: 320px; max-width: calc(100vw - 32px);
  background: var(--bg-elevated); border: 1px solid var(--hairline);
  border-radius: var(--r-lg); box-shadow: var(--shadow-pop);
  padding: 7px; opacity: 0; transform: translateY(-4px) scale(.99);
  transform-origin: top right; pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.pp.is-open .pp-menu { opacity: 1; transform: none; pointer-events: auto; }
.pp.is-open .pp-caret { color: var(--text-2); }
.pp-menu-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 7px 9px 9px; gap: 8px;
}
.pp-menu-head .ppm-title { font-size: 11px; font-weight: 600; letter-spacing: .5px; text-transform: uppercase; color: var(--text-3); }
.pp-menu-head .ppm-tier { font-size: 11px; color: var(--text-4); font-variant-numeric: tabular-nums; }

.pp-item {
  display: flex; align-items: center; gap: 11px; width: 100%;
  background: none; border: 0; cursor: pointer; text-align: left;
  padding: 9px 9px; border-radius: var(--r-md); font: inherit; color: var(--text);
}
.pp-item:hover { background: var(--surface); }
.pp-item .pp-flag {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-size: 15px; background: var(--surface-2);
}
.pp-item.is-active .pp-flag { background: var(--accent-soft); }
.pp-item .pp-body { min-width: 0; flex: 1; }
.pp-item .pp-name { font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 7px; }
.pp-item .pp-meta { font-size: 12px; color: var(--text-3); margin-top: 1px; font-variant-numeric: tabular-nums; }
.pp-item .pp-check { flex: none; color: var(--buy); font-size: 15px; opacity: 0; }
.pp-item.is-active .pp-check { opacity: 1; }
.pp-item.is-active .pp-name { color: var(--accent); }
.pp-badge-active {
  font-size: 10px; font-weight: 600; letter-spacing: .3px; color: var(--buy);
  background: var(--buy-fill); border-radius: var(--r-pill); padding: 1px 7px;
}
.pp-hint { font-size: 11.5px; color: var(--text-4); padding: 4px 10px 9px; line-height: 1.45; }
.pp-foot {
  display: flex; align-items: center; gap: 8px; margin-top: 4px;
  border-top: 1px solid var(--hairline); padding: 8px 6px 4px;
}
.pp-foot a {
  flex: 1; display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 500; color: var(--text-2);
  padding: 8px 9px; border-radius: var(--r-md);
}
.pp-foot a:hover { background: var(--surface); color: var(--text); }
.pp-foot a .ppf-ico { color: var(--text-4); }
/* each .pp-item is its own POST form so the switch works without JS — keep the wrapper transparent */
.pp-form { margin: 0; display: block; }

/* ── 7. Buttons ───────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font: inherit; font-weight: 600; font-size: 14px;
  padding: 10px 18px; border-radius: var(--r-md); border: 1px solid transparent;
  cursor: pointer; white-space: nowrap;
  transition: filter var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.btn:active { transform: scale(.98); }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { filter: brightness(.94); }
.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--border); }
.btn-secondary:hover { background: var(--surface-2); }
.btn-ghost { background: none; color: var(--accent); padding: 8px 10px; }
.btn-ghost:hover { background: var(--accent-soft); }
.btn-sm { padding: 7px 13px; font-size: 13px; }
.btn-lg { padding: 13px 22px; font-size: 15px; }
.btn-full { width: 100%; }
.btn:disabled { opacity: .4; cursor: default; }

/* ── 8. Inputs / forms ────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 7px; }
.field > label { font-size: 13px; font-weight: 600; color: var(--text); }
.field .hint { font-size: 12px; color: var(--text-3); }
.input, select.input {
  width: 100%; font: inherit; font-size: 15px; color: var(--text);
  background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: 11px 13px; outline: none;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.input::placeholder { color: var(--text-4); }
.input:focus { border-color: var(--accent); box-shadow: var(--focus); }
.input.invalid { border-color: var(--alert); }
/* required fields glow red ONLY while EMPTY (invalid) — a filled required field looks normal, not alarming.
   Focus still wins (accent) so typing is calm. */
.input:required:invalid { border-color: var(--alert); box-shadow: 0 0 0 2px color-mix(in srgb, var(--alert) 18%, transparent); }
.input:required:invalid:focus { border-color: var(--accent); box-shadow: var(--focus); }
select.input { appearance: none; -webkit-appearance: none; background-image: none; cursor: pointer; }
.select-wrap { position: relative; }
.select-wrap::after { content: "⌄"; position: absolute; right: 13px; top: 46%; transform: translateY(-50%); color: var(--text-3); pointer-events: none; }

/* ── 9. Cards & generic surfaces ──────────────────────────────────────────── */
.card { background: var(--surface); border-radius: var(--r-xl); padding: var(--s7); }
.card.raised { background: var(--bg-elevated); border: 1px solid var(--hairline); box-shadow: var(--shadow-raise); }
.panel { background: var(--bg-elevated); border: 1px solid var(--hairline); border-radius: var(--r-xl); padding: 22px 24px; }
.divider { height: 1px; background: var(--hairline); border: 0; margin: var(--s5) 0; }

/* ── 10. Page header (title + actions) ────────────────────────────────────── */
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s5); }
.page-head h1 { font-size: 30px; font-weight: 700; letter-spacing: -.8px; }
.page-head .lede { font-size: 16px; color: var(--text-2); margin-top: 6px; max-width: 52ch; }

/* ── 11. Segmented control (profile switch) ───────────────────────────────── */
.profile-seg { /* alias of .seg for larger control */ }
.seg.lg button { font-size: 14px; padding: 8px 16px; }

/* ── 12. Filter bar ───────────────────────────────────────────────────────── */
.filters { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; margin: var(--s5) 0; }
.chip-select {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--surface); border: 1px solid transparent; border-radius: var(--r-pill);
  padding: 7px 14px; font-size: 13px; font-weight: 500; color: var(--text); cursor: pointer;
}
.chip-select:hover { background: var(--surface-2); }
.chip-select .cs-label { color: var(--text-3); }
.chip-select .cs-caret { color: var(--text-4); margin-left: 2px; }

/* ── 13. Deal list / cards ────────────────────────────────────────────────── */
.deal-list { display: flex; flex-direction: column; gap: var(--s4); }

.deal {
  background: var(--surface); border-radius: var(--r-xl);
  padding: var(--s6) var(--s7); border: 1px solid transparent;
  display: grid; grid-template-columns: 34px minmax(0,1fr) auto; gap: var(--s5);
  align-items: start;
  transition: background var(--dur-fast) var(--ease);
}
.deal:hover { background: var(--surface-2); }
.deal.is-emergency { background: var(--alert-fill); }
.deal .rank {
  width: 30px; height: 30px; border-radius: 50%; margin-top: 2px;
  background: var(--surface-2); color: var(--text);
  display: grid; place-items: center; font-size: 13px; font-weight: 600;
}
.deal.is-emergency .rank { background: var(--alert); color: #fff; }

.deal-body { min-width: 0; }
.deal-titlerow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.deal-title { font-size: 21px; font-weight: 700; letter-spacing: -.4px; color: var(--text); }
.deal-place { font-size: 14px; color: var(--text-2); margin-top: 3px; }
.deal-place b { color: var(--text); font-weight: 600; }
.deal-meta { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 13px; }

.deal-aside { text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: 8px; min-width: 150px; }
.price-big { font-size: 28px; font-weight: 700; letter-spacing: -1px; color: var(--text); white-space: nowrap; }
.price-base { font-size: 13px; color: var(--text-3); white-space: nowrap; }
.price-base s { color: var(--text-4); }
.deal-aside .btn { margin-top: 4px; }

/* meta chips */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12.5px; font-weight: 500; color: var(--text-2);
  background: var(--bg-elevated); border: 1px solid var(--hairline);
  border-radius: var(--r-pill); padding: 4px 11px; white-space: nowrap;
}
.deal.is-emergency .chip { background: color-mix(in srgb, var(--bg-elevated) 70%, transparent); }

/* verdict pill */
.verdict {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 600; letter-spacing: .3px;
  border-radius: var(--r-pill); padding: 5px 12px; white-space: nowrap;
}
.verdict .dot { width: 8px; height: 8px; border-radius: 50%; }
.verdict.buy   { background: var(--buy-fill);   color: var(--buy); }
.verdict.buy .dot { background: var(--buy); }
.verdict.wait  { background: var(--wait-fill);  color: var(--wait); }
.verdict.wait .dot { background: var(--wait); }
.verdict.watch { background: var(--watch-fill); color: var(--watch); }
.verdict.watch .dot { background: var(--watch); }

/* re-scan NOTICE — its OWN semantic, NOT the verdict --wait token (which is muted brown #9a6700 on the cream
   light surface = no contrast). Yellow lives in the stripe/icon/border; the body text stays warm-dark for AA
   on the fill. On dark it keeps the bright-yellow glow. Source: Voyscout Design System (.notice). */
.notice {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 13px 16px;
  background: var(--notice-fill);
  border: 1px solid var(--notice-border);
  border-left: 3px solid var(--notice);
  border-radius: var(--r-md);
  color: var(--notice-text);
  font-size: 13.5px; line-height: 1.5; max-width: 640px;
}
.notice .notice-ico { flex: none; color: var(--notice); font-size: 15px; line-height: 1.4; }
.notice .notice-body { min-width: 0; }
.notice b, .notice strong { color: var(--notice-text); font-weight: 700; }
.notice a { color: var(--notice); font-weight: 600; text-decoration: none; }
.notice a:hover { text-decoration: underline; }
.notice .notice-actions { margin-top: 10px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* inline "?" chip in the notice body, revealing a one-line detail on hover/focus — amber OUTLINE (legible on
   both themes; a filled chip would swallow its glyph against the dark bright-yellow). */
.pax-mismatch-q {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; margin-left: 4px; border-radius: 50%;
  font-size: 11px; font-weight: 700; cursor: help; position: relative;
  border: 1px solid var(--notice); color: var(--notice); background: transparent;
}
.pax-mismatch-q[data-tip]:hover::after, .pax-mismatch-q[data-tip]:focus::after {
  content: attr(data-tip); position: absolute; left: 50%; bottom: calc(100% + 8px); transform: translateX(-50%);
  white-space: normal; width: max-content; max-width: 280px; z-index: 50;
  background: var(--surface-2, #222); color: var(--text, #fff); border: 1px solid var(--border, #444);
  border-radius: var(--r-sm); padding: 7px 10px; font-size: 12px; font-weight: 500; line-height: 1.4;
  letter-spacing: 0; box-shadow: 0 6px 22px rgba(0,0,0,.28);
}

/* attention CTA — the re-scan button wears an amber RING (notice accent), not a solid fill. Replaces the old
   pulsing scan-glow; same DS notice tokens, so it reads correctly on both themes. */
.btn.btn-attention {
  background: var(--notice-fill); color: var(--notice-text);
  border-color: var(--notice);
}
.btn.btn-attention:hover { background: color-mix(in srgb, var(--notice) 18%, var(--notice-fill)); }
.btn.btn-attention .lead { color: var(--notice); }

/* quota / count pill that needs attention (e.g. scans 3/10) */
.quota-pill {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
  color: var(--notice-text); background: var(--notice-fill);
  border: 1px solid var(--notice-border);
  border-radius: var(--r-pill); padding: 4px 11px;
  font-variant-numeric: tabular-nums;
}
.quota-pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--notice); }

.emergency-badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 700; letter-spacing: .3px;
  color: var(--alert); background: color-mix(in srgb, var(--alert) 14%, transparent);
  border-radius: var(--r-pill); padding: 4px 10px;
}

/* ── 14. Deal table (the alternative row presentation) ────────────────────── */
.deal-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.deal-table th {
  text-align: left; font-size: 11px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase;
  color: var(--text-3); padding: 0 14px 12px; border-bottom: 1px solid var(--hairline);
}
.deal-table th.r, .deal-table td.r { text-align: right; }
.deal-table td { padding: 14px; border-bottom: 1px solid var(--hairline); vertical-align: middle; }
.deal-table tr:last-child td { border-bottom: 0; }
.deal-table tbody tr { transition: background var(--dur-fast) var(--ease); }
.deal-table tbody tr:hover { background: var(--surface); }
.deal-table .t-dest { font-weight: 600; color: var(--text); }
.deal-table .t-sub { color: var(--text-3); font-size: 12.5px; }
.deal-table .t-price { font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ── 15. Stat row (UPPERCASE label + big value) ───────────────────────────── */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px,1fr)); gap: var(--s2); }
.stat { padding: var(--s4) var(--s5); }
.stat .stat-label { font-size: 11px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--text-3); }
.stat .stat-value { font-size: 26px; font-weight: 700; letter-spacing: -.6px; margin-top: 8px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.stat .stat-sub { font-size: 12.5px; color: var(--text-3); margin-top: 4px; }

/* ── 16. Right-rail explainer (the resend pattern) ────────────────────────── */
.rail { position: sticky; top: 84px; display: flex; flex-direction: column; gap: var(--s4); }
.explainer { background: var(--surface); border-radius: var(--r-xl); padding: var(--s6); }
.explainer.raised { background: var(--bg-elevated); border: 1px solid var(--hairline); }
.explainer h3 { font-size: 11px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--text-3); margin-bottom: 12px; }
.explainer p { font-size: 13px; line-height: 1.6; color: var(--text-2); margin-bottom: 12px; }
.explainer p:last-child { margin-bottom: 0; }
.explainer b { color: var(--text); font-weight: 600; }
.explainer .formula { font-family: var(--mono); font-size: 12px; color: var(--text); background: var(--bg-elevated); border: 1px solid var(--hairline); border-radius: var(--r-sm); padding: 8px 10px; display: block; margin-bottom: 12px; }
.explainer.raised .formula { background: var(--surface); }
.exp-verdict { display: flex; align-items: flex-start; gap: 9px; margin-bottom: 12px; }
.exp-verdict .verdict { flex: none; }
.exp-verdict span { font-size: 12.5px; color: var(--text-2); line-height: 1.5; }
.exp-foot { font-size: 12px; color: var(--text-3); line-height: 1.6; padding: 0 2px; }
.dl { display: grid; grid-template-columns: auto 1fr; gap: 8px 14px; font-size: 13px; }
.dl dt { font-weight: 600; color: var(--text); }
.dl dd { margin: 0; color: var(--text-2); }

/* ── 17. Sparkline ────────────────────────────────────────────────────────── */
.spark { display: block; width: 100%; height: 56px; }
.spark .line { fill: none; stroke: var(--accent); stroke-width: 2; vector-effect: non-scaling-stroke; }
.spark .area { fill: var(--accent-soft); }
.spark .pt { fill: var(--accent); }
.spark .now { fill: var(--buy); }
/* sparkline hover: vertical guide + focus dot + price/date tooltip (nearest sample) — ported from DS-6 deal-detail.html */
.spark .sp-guide { stroke: var(--text-4); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0; vector-effect: non-scaling-stroke; }
.spark .sp-focus { fill: var(--accent); stroke: var(--surface); stroke-width: 2; opacity: 0; }
.spark.is-hover .sp-guide, .spark.is-hover .sp-focus { opacity: 1; }
.sp-tip {
  position: absolute; pointer-events: none; z-index: 5; opacity: 0;
  transform: translate(-50%, -100%); transition: opacity var(--dur-fast) var(--ease);
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--shadow-raise); padding: 7px 11px; white-space: nowrap; text-align: center;
}
.sp-tip.show { opacity: 1; }
.sp-tip .sp-tip-price { font-size: 14px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.2px; }
.sp-tip .sp-tip-date { font-size: 11px; font-weight: 500; color: var(--text-3); margin-top: 2px; }

/* ── 17b. „Další termíny v okně" — per-row horizontal bar chart (flight detail + Letenky, DS-7 §7) ─── */
/* date + price-proportional bar + price + →; bar length grows with price (cheapest = shortest, 54% floor);
   cheapest tinted green with the ✓ tag inside; hover → price + Δ-vs-cheapest tooltip (app.client.txt). */
.terms { position: relative; }
.term-row {
  display: grid; grid-template-columns: 104px 1fr auto 16px;
  align-items: center; gap: 16px; padding: 13px 8px;
  border-radius: var(--r-md); text-decoration: none; color: inherit;
  transition: background var(--dur-fast) var(--ease);
}
.term-row + .term-row { box-shadow: 0 -1px 0 var(--hairline); }
.term-row:hover { background: var(--surface-2); }
.term-date { font-size: 14px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* origin chip under the date in a flight strip row (flag + IATA; hover title = "odlet z <city>") */
.term-origin { display: block; margin-top: 2px; font-size: 11px; font-weight: 500; color: var(--text-3); letter-spacing: .01em; white-space: nowrap; cursor: default; }
.term-track {
  position: relative; height: 28px; background: var(--surface-2);
  border-radius: var(--r-sm); overflow: hidden;
}
.term-row:hover .term-track { background: var(--surface); }
.term-fill {
  height: 100%; border-radius: var(--r-sm); background: var(--accent);
  display: flex; align-items: center; padding: 0 11px;
  transition: filter var(--dur-fast) var(--ease);
}
.term-fill.cheapest { background: var(--buy); }
/* the user's preferred (or nearest-available) departure day — ringed so it reads even on a cheapest bar */
.term-fill.pref { box-shadow: inset 0 0 0 2px var(--accent); }
.term-fill.cheapest.pref { box-shadow: inset 0 0 0 2px var(--accent); }
.term-row:hover .term-fill { filter: brightness(1.06); }
.term-tag {
  font-size: 11px; font-weight: 600; letter-spacing: .2px; white-space: nowrap;
  color: #04130a;
}
.term-price { font-size: 14px; font-weight: 600; color: var(--text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.term-price.cheapest { color: var(--buy); }
.term-go { color: var(--text-4); font-size: 15px; text-align: right; transition: transform var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease); }
.term-row:hover .term-go { color: var(--text-2); transform: translateX(2px); }
.term-tip {
  position: absolute; pointer-events: none; z-index: 5; opacity: 0;
  transform: translate(-50%, -100%); transition: opacity var(--dur-fast) var(--ease);
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--shadow-raise); padding: 8px 12px; white-space: nowrap; text-align: center;
}
.term-tip.show { opacity: 1; }
.term-tip .tt-price { font-size: 14px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.2px; }
.term-tip .tt-delta { font-size: 11px; font-weight: 500; margin-top: 2px; }
.term-tip .tt-delta.cheapest { color: var(--buy); }
.term-tip .tt-delta.more { color: var(--text-3); }
@media (max-width: 720px) {
  .term-row { grid-template-columns: 80px 1fr auto; gap: 12px; }
  .term-go { display: none; }
}
a.ss-row:hover .ss-go { color: var(--accent); }
.ss-tag { display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: var(--r-pill);
  font-size: 11px; font-weight: 600; vertical-align: middle; }
.ss-tag.low { background: var(--buy-fill); color: var(--buy); }
.ss-tag.hero { background: var(--accent-soft); color: var(--accent); }

/* ── 18. Breakdown bars ───────────────────────────────────────────────────── */
.breakdown { display: flex; flex-direction: column; gap: 12px; }
.bd-row { display: grid; grid-template-columns: 178px 1fr auto; gap: 12px; align-items: center; font-size: 13px; }
/* min-width:0 lets the label shrink to its 178px track (grid items default to min-content = the full
   nowrap string, which overflowed a long label like "Doprava na letiště Praha (PRG)" straight over the
   bar). The text now WRAPS inside the track — the chip (.bd-ico flex:none) never shrinks, the bar stays
   put. overflow-wrap guards a hypothetical unbreakable token. */
.bd-row .bd-label { display: flex; align-items: center; gap: 10px; color: var(--text-2); min-width: 0; overflow-wrap: anywhere; }
/* category chip — tint + glyph share the row's bar-fill hue via currentColor (same pattern as .emergency-badge);
   colours are 1:1 with .bd-fill.* below so the chip and the bar always speak the same colour. */
.bd-ico { flex: none; width: 26px; height: 26px; display: grid; place-items: center; border-radius: var(--r-sm); color: var(--text-3); background: color-mix(in srgb, currentColor 15%, transparent); }
.bd-ico svg { width: 15px; height: 15px; display: block; }
.bd-ico.catalog   { color: var(--accent); }
.bd-ico.transport { color: #5e5ce6; }
.bd-ico.food      { color: #ff9f0a; }
.bd-ico.bags      { color: var(--text-3); }
/* subtle neutral track so the proportional COLOURED fill is what reads (a prominent track looked like a
   full bar → "all the same"); min-width keeps a small segment visible without faking its proportion. */
.bd-track { height: 8px; background: rgba(128,128,128,0.16); border-radius: var(--r-pill); overflow: hidden; }
/* display:block is load-bearing: width/height are IGNORED on inline spans, so without it the
   coloured fill rendered 0px and only the grey track showed (persona finding 2026-07-10). */
.bd-fill { display: block; height: 100%; min-width: 3px; border-radius: var(--r-pill); background: var(--accent); }
.bd-fill.catalog { background: var(--accent); }
.bd-fill.transport { background: #5e5ce6; }
.bd-fill.food { background: #ff9f0a; }
.bd-fill.bags { background: var(--text-3); }
.bd-row .bd-val { font-variant-numeric: tabular-nums; color: var(--text); font-weight: 600; }
/* total row: no chip — indent the label by 36px (26 chip + 10 gap) so "Reálně celkem" lines up with the item TEXT */
.bd-row.bd-total .bd-label { padding-left: 36px; }
/* zero-cost line (e.g. transfer already in the price) reads muted: dim the chip + soften the amount, still documented */
.bd-row.is-zero .bd-ico { opacity: .55; }
.bd-row.is-zero .bd-val { color: var(--text-3); font-weight: 500; }
/* narrow viewport: a 178px label column starves the bar (it collapsed to a sliver on phones), so
   stack — the label takes its own full-width line ABOVE the bar+amount. The bar then spans the row. */
@media (max-width: 560px) {
  .bd-row { grid-template-columns: 1fr auto; row-gap: 5px; }
  .bd-row .bd-label { grid-column: 1 / -1; }
  .bd-row.bd-total .bd-label { padding-left: 0; }
}

/* ── 19. States: empty / loading / error ──────────────────────────────────── */
.state { text-align: center; padding: var(--s8) var(--s6); max-width: 420px; margin: 40px auto; }
.state .state-ico { font-size: 40px; margin-bottom: 14px; }
.state h2 { font-size: 19px; font-weight: 600; margin-bottom: 8px; }
.state p { font-size: 14px; color: var(--text-2); line-height: 1.6; margin-bottom: 18px; }
/* out-of-window package offers shown on the date-filtered empty state */
.offwin-list { list-style: none; padding: 0; margin: 12px 0 0; text-align: left; }
.offwin-list li { display: flex; gap: 10px; align-items: baseline; padding: 6px 0; border-bottom: 1px solid var(--hairline); font-size: 13px; }
.offwin-list .ow-title { font-weight: 600; }
.offwin-list .ow-date { color: var(--text-2); }
.offwin-list .ow-price { margin-left: auto; color: var(--text-2); }

.skeleton { background: var(--skeleton); background-size: 400% 100%; border-radius: var(--r-sm); animation: shimmer 1.4s infinite linear; }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
.skel-deal { background: var(--surface); border-radius: var(--r-xl); padding: var(--s6) var(--s7); display: grid; grid-template-columns: 34px 1fr auto; gap: var(--s5); align-items: center; }
.skel-line { height: 12px; }

.banner-error {
  display: flex; align-items: flex-start; gap: 12px;
  background: var(--alert-fill); border-radius: var(--r-lg); padding: 14px 16px;
  font-size: 13.5px; color: var(--text);
}
.banner-error .be-ico { color: var(--alert); font-size: 16px; }
.banner-error b { color: var(--alert); }

/* ── 20. Pagination ───────────────────────────────────────────────────────── */
.pager { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: var(--s7); }
.pager a, .pager span {
  min-width: 32px; height: 32px; padding: 0 8px; border-radius: var(--r-md);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 500; color: var(--text-2);
}
.pager a:hover { background: var(--surface); color: var(--text); opacity: 1; }
.pager .current { background: var(--accent); color: #fff; }
.pager .gap { color: var(--text-4); }

/* ── 21. Modal ────────────────────────────────────────────────────────────── */
.modal-scrim {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(0,0,0,.4); backdrop-filter: blur(4px);
  display: grid; place-items: center; padding: 20px;
}
[data-theme="dark"] .modal-scrim { background: rgba(0,0,0,.6); }
.modal {
  background: var(--bg-elevated); border: 1px solid var(--hairline);
  border-radius: var(--r-xl); box-shadow: var(--shadow-pop);
  width: 100%; max-width: 440px; padding: var(--s7);
}
.modal h2 { font-size: 20px; font-weight: 700; letter-spacing: -.4px; margin-bottom: 8px; }
.modal p { font-size: 14px; color: var(--text-2); line-height: 1.6; margin-bottom: 20px; }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; }

/* ── 22. Auth / centered layout ───────────────────────────────────────────── */
.auth { position: relative; z-index: 1; min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.auth-card { width: 100%; max-width: 360px; text-align: center; }
.auth .brand { flex-direction: column; gap: 16px; padding: 0 0 8px; font-size: 30px; letter-spacing: -.5px; }
.auth .brand .glyph { width: 66px; height: 66px; border-radius: 16px; }
.auth .auth-tag { font-size: 14px; color: var(--text-3); margin-bottom: 28px; }
.auth form { display: flex; flex-direction: column; gap: 12px; text-align: left; }
.auth .auth-note { font-size: 13px; color: var(--text-3); text-align: center; margin-top: 2px; }

/* ── 23. Travel ambient background (login) ─────────────────────────────────────
   Heavily-blurred drifting glow + flowing dotted flight routes + pulsing "found"
   blips. Ambient only — sits behind content, low opacity, slow. Reduced-motion
   freezes it to a calm still. */
.travel-bg { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.tb-blob { position: absolute; border-radius: 50%; filter: blur(64px); will-change: transform; }
.tb-blob.b1 { width: 46vmax; height: 46vmax; left: -10vmax; top: -14vmax; opacity: .36;
  background: radial-gradient(circle, var(--accent) 0%, transparent 70%); }
.tb-blob.b2 { width: 40vmax; height: 40vmax; right: -12vmax; top: 18vmax; opacity: .24;
  background: radial-gradient(circle, #1f8a5b 0%, transparent 70%); }
.tb-blob.b3 { width: 38vmax; height: 38vmax; left: 22vmax; bottom: -16vmax; opacity: .22;
  background: radial-gradient(circle, #5e5ce6 0%, transparent 70%); }
.tb-arcs { position: absolute; inset: 0; width: 100%; height: 100%; filter: blur(.5px); }
.tb-arc { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-linecap: round;
  stroke-dasharray: 2 16; opacity: .28; vector-effect: non-scaling-stroke; }
.tb-blip { fill: var(--accent); opacity: .5; transform-box: fill-box; transform-origin: center; }
.tb-blip.g { fill: #1f8a5b; }
:root[data-theme="dark"] .tb-arc, :root[data-theme="system"] .tb-arc { opacity: .34; }
:root[data-theme="dark"] .tb-blob.b1 { opacity: .5; }
:root[data-theme="dark"] .tb-blob.b2 { opacity: .34; }
:root[data-theme="dark"] .tb-blob.b3 { opacity: .3; }
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] .tb-blob.b1 { opacity: .5; }
  :root[data-theme="system"] .tb-blob.b2 { opacity: .34; }
  :root[data-theme="system"] .tb-blob.b3 { opacity: .3; }
}

@media (prefers-reduced-motion: no-preference) {
  .tb-blob.b1 { animation: tb-drift1 34s ease-in-out infinite; }
  .tb-blob.b2 { animation: tb-drift2 44s ease-in-out infinite; }
  .tb-blob.b3 { animation: tb-drift3 52s ease-in-out infinite; }
  .tb-arc { animation: tb-flow linear infinite; }
  .tb-arc.a1 { animation-duration: 9s; }
  .tb-arc.a2 { animation-duration: 13s; animation-direction: reverse; }
  .tb-arc.a3 { animation-duration: 16s; }
  .tb-blip { animation: tb-pulse 3.4s ease-in-out infinite; }
  .tb-blip.d { animation-delay: 1.1s; }
  .tb-blip.e { animation-delay: 2.2s; }
}
@keyframes tb-drift1 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(6vmax,4vmax) scale(1.12); } }
@keyframes tb-drift2 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(-5vmax,5vmax) scale(1.1); } }
@keyframes tb-drift3 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(4vmax,-5vmax) scale(1.08); } }
@keyframes tb-flow { to { stroke-dashoffset: -180; } }
@keyframes tb-pulse { 0%,100% { transform: scale(.6); opacity: .25; } 50% { transform: scale(1.5); opacity: .7; } }

/* contained + soft variant — for embedding ambient inside a panel (e.g. empty state) */
.travel-bg.contained { position: absolute; border-radius: inherit; }
.travel-bg.soft .tb-blob { filter: blur(46px); }
.travel-bg.soft .tb-blob.b1 { opacity: .16; }
.travel-bg.soft .tb-blob.b2 { opacity: .12; }
.travel-bg.soft .tb-blob.b3 { opacity: .10; }
.travel-bg.soft .tb-arc { opacity: .18; }
.travel-bg.soft .tb-blip { opacity: .35; }
:root[data-theme="dark"] .travel-bg.soft .tb-blob.b1 { opacity: .26; }
:root[data-theme="dark"] .travel-bg.soft .tb-arc { opacity: .24; }
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] .travel-bg.soft .tb-blob.b1 { opacity: .26; }
  :root[data-theme="system"] .travel-bg.soft .tb-arc { opacity: .24; }
}

/* ── 24. Settings tabs + usage rings (adapted from resend.com Usage) ───────── */
.tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 28px; }
.tab {
  padding: 8px 15px; border-radius: var(--r-md); font-size: 14px; font-weight: 500;
  color: var(--text-2); transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.tab:hover { background: var(--surface); color: var(--text); opacity: 1; }
.tab.active { background: var(--surface-2); color: var(--text); font-weight: 600; }

.usage-section { display: grid; grid-template-columns: 280px minmax(0,1fr); gap: 48px; padding: 34px 0; }
.usage-section + .usage-section { border-top: 1px solid var(--hairline); }
.usage-section h2 { font-size: 21px; font-weight: 700; letter-spacing: -.4px; }
.usage-section .us-desc { font-size: 14px; color: var(--text-2); margin-top: 8px; line-height: 1.5; max-width: 32ch; }
.usage-section .us-cta { margin-top: 18px; display: flex; gap: 10px; align-items: center; }
.us-free { font-size: 15px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.usage-row { display: flex; align-items: center; gap: 14px; padding: 15px 0; border-bottom: 1px solid var(--hairline); }
.usage-row:last-child { border-bottom: 0; }
.usage-row .ur-label { font-size: 14px; color: var(--text); }
.usage-row .ur-val { margin-left: auto; font-size: 14px; color: var(--text-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.usage-row .ur-caret { color: var(--text-4); margin-left: 4px; }
.ring { width: 18px; height: 18px; flex: none; }
.ring circle { fill: none; stroke-width: 3; }
.ring .track { stroke: var(--surface-2); }
.ring .meter { stroke: var(--accent); stroke-linecap: round; transform: rotate(-90deg); transform-origin: 10px 10px; }
.ring.full .meter { stroke: var(--buy); }
.ring.warn .meter { stroke: var(--wait); }
@media (max-width: 760px) { .usage-section { grid-template-columns: 1fr; gap: 20px; } }

/* On-demand scan quota ring on the Letenky board: green <25% / yellow >=25% / red >=75% (used/limit).
   Scoped to .scan-quota so the settings/usage rings keep their own blue/yellow/green palette. */
.scan-quota { display: inline-flex; align-items: center; gap: 6px; }
.scan-quota .sq-label { font-size: 12px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.scan-quota .ring .meter { stroke: var(--buy); }
.scan-quota .ring.warn .meter { stroke: var(--wait); }
.scan-quota .ring.full .meter { stroke: var(--alert); }

/* DS-5 indeterminate "scan in progress" — fixed arc, whole ring spins (overrides the used/limit meter
   so an in-flight scan reads as motion, not a stuck gauge). Reduced-motion → gentle opacity pulse. */
.ring.scanning .track { stroke: var(--surface-2); }
.ring.scanning .meter { stroke: var(--accent); stroke-dasharray: 14 36.3 !important; }
@media (prefers-reduced-motion: no-preference) {
  .ring.scanning { animation: vs-ringspin .85s linear infinite; transform-origin: 50% 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .ring.scanning .meter { animation: vs-ringpulse 1.6s ease-in-out infinite; }
}
@keyframes vs-ringspin { to { transform: rotate(360deg); } }
@keyframes vs-ringpulse { 0%,100% { opacity: .35; } 50% { opacity: 1; } }

/* /account "Limity" overview — two big ring gauges (scans X/Y · profiles X/Y). Same track/meter palette
   as the small scan-quota ring (green <25% / yellow >=25% / red >=75%), scaled up with the value inside. */
.lim-grid { display: flex; gap: 28px; flex-wrap: wrap; }
.lim-gauge { display: flex; flex-direction: column; align-items: center; text-align: center; min-width: 110px; }
.ring.gauge { width: 88px; height: 88px; }
.ring.gauge circle { stroke-width: 6; }
/* the -90° meter rotate must pivot around THIS gauge's center (40,40), not the small ring's 10,10
   inherited from `.ring .meter` — otherwise the arc is displaced into a broken partial sliver. */
.ring.gauge .meter { stroke: var(--buy); transform-origin: 40px 40px; }
.ring.gauge.warn .meter { stroke: var(--wait); }
.ring.gauge.full .meter { stroke: var(--alert); }
.ring.gauge .gauge-val {
  fill: var(--text); font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums;
  transform: none; /* keep the label upright (the -90° rotate is meter-only via the circle rule above) */
}
.lim-label { margin-top: 10px; font-size: 14px; font-weight: 600; color: var(--text); }
.lim-sub { font-size: 11.5px; margin-top: 2px; }

/* ── 25. Logo lockup helper ───────────────────────────────────────────────── */
.wordmark { height: 26px; display: inline-block; vertical-align: middle; color: var(--text); }

/* ── 26. Motion: compass settle on load + nav-icon liveliness ──────────────── */
.brand .glyph svg { display: block; width: 100%; height: 100%; }
.brand .glyph .vs-needle { transform-box: view-box; transform-origin: 16px 16px; }

@media (prefers-reduced-motion: no-preference) {
  /* compass needle settles like a real compass when the page loads */
  .brand .glyph .vs-needle { animation: vs-compass 1.25s cubic-bezier(.34,1.4,.64,1) both; }
  /* replay on hover of the wordmark */
  .brand:hover .glyph .vs-needle { animation: vs-compass 1.1s cubic-bezier(.34,1.4,.64,1); }

  /* nav icons spring to life on hover */
  .ni-ico.i-compass { transform-origin: 50% 50%; }
  .ni-ico.i-plane { transform-origin: 50% 50%; }
  .ni-ico.i-bell  { transform-origin: 50% 12%; }
  .ni-ico.i-beach { transform-origin: 50% 88%; }
  .ni-ico.i-gear  { transform-origin: 50% 50%; }
  /* compass settles like a real compass when its page is active (load) + re-settles on hover —
     reuses the shared vs-compass keyframe (same motion as the brand-glyph needle) */
  .nav-item.active .i-compass { animation: vs-compass 1.1s cubic-bezier(.34,1.4,.64,1) both; }
  .nav-item:hover .i-compass { animation: vs-compass 1s cubic-bezier(.34,1.4,.64,1); }
  .nav-item:hover .i-plane { animation: vs-plane .6s var(--ease); }
  .nav-item:hover .i-bell  { animation: vs-bell .65s var(--ease); }
  .nav-item:hover .i-beach { animation: vs-beach .7s var(--ease); }
  .nav-item:hover .i-gear  { animation: vs-gear .6s var(--ease); }
  .nav-item:hover .i-help  { transform: translateX(3px); }
}

@keyframes vs-compass {
  0%   { transform: rotate(-17deg); }
  35%  { transform: rotate(11deg); }
  60%  { transform: rotate(-6deg); }
  80%  { transform: rotate(3deg); }
  100% { transform: rotate(0deg); }
}
@keyframes vs-plane {
  0%   { transform: translate(0,0) rotate(0); }
  45%  { transform: translate(3px,-3px) rotate(10deg); }
  100% { transform: translate(0,0) rotate(0); }
}
@keyframes vs-bell {
  0%,100% { transform: rotate(0); }
  20% { transform: rotate(-15deg); }
  40% { transform: rotate(12deg); }
  60% { transform: rotate(-7deg); }
  80% { transform: rotate(4deg); }
}
@keyframes vs-beach {
  0%,100% { transform: rotate(0); }
  30% { transform: rotate(-11deg); }
  65% { transform: rotate(9deg); }
}
@keyframes vs-gear {
  from { transform: rotate(0); }
  to   { transform: rotate(90deg); }
}
@media (max-width: 1100px) {
  .content-wrap { grid-template-columns: minmax(0,1fr); }
  .rail { position: static; flex-direction: row; flex-wrap: wrap; }
  .rail .explainer { flex: 1 1 280px; }
  /* user-sim MUST #1 (2026-07-15, Franta/mobil): on the profile FORM pages the "V dosahu z…" airport-reach
     preview lives in the rail, which stacks AFTER the form on a narrow viewport — so it landed BELOW the
     submit and an impatient user hit "Dokončit" before ever seeing the reach tuning. Hoist the reach rail
     ABOVE the form (order:-1) so it's visible before the submit. Scoped by :has(#reach-preview) so ONLY the
     account/onboard reach rail reorders — a plain rail (e.g. /alerts) is untouched. Desktop (>1100) keeps
     the sticky right rail. */
  .content-wrap:has(#reach-preview) .rail { order: -1; }
}
@media (max-width: 860px) {
  .app { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; z-index: 50; left: 0; top: 0; width: 280px;
    transform: translateX(-100%); transition: transform var(--dur) var(--ease);
    box-shadow: var(--shadow-pop);
  }
  body.nav-open .sidebar { transform: translateX(0); }
  body.nav-open::after { content: ""; position: fixed; inset: 0; z-index: 40; background: rgba(0,0,0,.4); }
  .hamburger { display: inline-flex; }
  /* keep the safe-area top inset (base .topbar) — only the horizontal padding tightens on phones;
     each side is max()'d with the landscape-notch inset so a rotated iPhone clears the cutout, and
     the installed PWA under the Dynamic Island keeps its top inset (portrait) here too */
  .topbar { padding: var(--sa-top) max(var(--s5), var(--sa-right)) 0 max(var(--s5), var(--sa-left)); }
  /* Option-B mobile declutter: the narrow bar keeps ONLY [☰ · crumb · compact profile pill].
     Relocate lang+theme into the drawer footer; drop the redundant Nápověda link (it's in the drawer
     nav) and the pill's "aktivní profil" sub-caption (redundant with the overview's active-profile
     banner). Cap the pill so a long profile name ellipsizes instead of pushing the row wide. */
  .topbar-toggles { display: none; }
  .topbar .helplink { display: none; }
  .sidebar-toggles { display: flex; align-items: center; gap: var(--s3); margin-top: 12px; flex-wrap: wrap; }
  .pp-trigger { max-width: 190px; }
  .pp-trigger .pp-cur small { display: none; }
  .content-wrap { padding: var(--s5); gap: var(--s5); }
  .search { display: none; }
  .deal { grid-template-columns: 30px minmax(0,1fr); }
  .deal-aside { grid-column: 1 / -1; text-align: left; align-items: flex-start; flex-direction: row; justify-content: space-between; width: 100%; flex-wrap: wrap; }
  .page-head h1 { font-size: 26px; }
}
/* ── cookie-consent bar (full-mode only; injected by the Worker) ────────────────────────────── */
.consent {
  position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 70;
  display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; justify-content: space-between;
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-pop); padding: 14px 18px; max-width: 880px; margin: 0 auto;
}
.consent-text { font-size: 13px; color: var(--text-2); line-height: 1.5; flex: 1 1 320px; }
.consent-actions { display: flex; gap: 10px; }

@media (max-width: 480px) {
  .rail .explainer { flex-basis: 100%; }
  .deal-table .hide-sm { display: none; }
  /* .topbar .helplink is already hidden at ≤860 (Option-B declutter, above) */
}

/* ── 27. Overview dashboard ───────────────────────────────────────────────────
   FIX: the active-profile badge used to float inline against the lede and
   collide with it. It's now its own full-width banner row below the intro. */
.ov-head { margin-bottom: 24px; }
.ov-head h1 { font-size: 30px; font-weight: 700; letter-spacing: -.8px; }
.ov-head .lede { font-size: 16px; color: var(--text-2); margin-top: 8px; max-width: 56ch; line-height: 1.5; }
.profile-banner {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 18px 0 30px;
  padding: 13px 16px; border-radius: var(--r-lg);
  background: var(--buy-fill); border: 1px solid color-mix(in srgb, var(--buy) 28%, transparent);
}
.profile-banner .pb-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--buy); flex: none; box-shadow: 0 0 0 4px color-mix(in srgb, var(--buy) 18%, transparent); }
.profile-banner .pb-text { font-size: 14px; font-weight: 600; color: var(--buy); }
.profile-banner .pb-text b { color: var(--text); }
.profile-banner .pb-action { margin-left: auto; font-size: 13px; font-weight: 500; color: var(--accent); }

.ov-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 20px; }
.ov-card {
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-xl); padding: 22px 24px; position: relative; overflow: hidden;
  display: flex; flex-direction: column; min-height: 220px;
}
.ov-card .ovc-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; position: relative; z-index: 1; }
.ov-card .ovc-eyebrow { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); font-weight: 600; }
.ov-card .ovc-link { margin-left: auto; font-size: 13px; font-weight: 500; color: var(--accent); }
.ov-card.full { grid-column: 1 / -1; min-height: 0; }
.ov-card ul { position: relative; z-index: 1; }
/* mini ambient "scanning" empty state inside a card — map motif + WHY text */
.ov-empty { position: relative; z-index: 1; flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 6px; padding: 18px 8px; }
.ov-empty h3 { font-size: 15px; font-weight: 600; color: var(--text); }
.ov-empty p { font-size: 13px; color: var(--text-2); line-height: 1.55; max-width: 34ch; }
@media (max-width: 760px) { .ov-grid { grid-template-columns: 1fr; } }

/* ── 28. Admin · Analytics ────────────────────────────────────────────────────
   FIX: "Prokliky podle dne" used to render as one solid blue block. It's now a
   real per-day bar chart (one rounded bar per day, gaps, baseline, peak accent). */
.metric-strip {
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-xl); overflow: hidden;
}
.metric { padding: 18px 22px; border-right: 1px solid var(--hairline); }
.metric:last-child { border-right: 0; }
.metric .m-label { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); font-weight: 600; line-height: 1.3; }
.metric .m-val { font-size: 30px; font-weight: 700; letter-spacing: -.5px; margin-top: 12px; font-variant-numeric: tabular-nums; color: var(--text); }
.metric .m-sub { font-size: 12px; color: var(--text-3); margin-top: 6px; line-height: 1.4; }
@media (max-width: 900px) { .metric-strip { grid-template-columns: repeat(2, 1fr); } .metric:nth-child(2n){border-right:0;} }

.panel-h { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); font-weight: 600; margin-bottom: 18px; }
.panel-sub { font-size: 12px; color: var(--text-4); font-weight: 500; }

.barchart { display: flex; align-items: flex-end; gap: 4px; height: 180px; padding-top: 8px; border-bottom: 1px solid var(--hairline); }
.barchart .bar {
  flex: 1; min-width: 0; background: var(--accent); border-radius: 3px 3px 0 0;
  min-height: 4px; opacity: .55; transition: opacity var(--dur-fast) var(--ease);
}
.barchart .bar:hover { opacity: 1; }
.barchart .bar.peak { opacity: 1; }
.barchart-axis { display: flex; justify-content: space-between; margin-top: 10px; font-size: 11px; color: var(--text-4); font-variant-numeric: tabular-nums; }
/* bar chart hover number (Apple-style "count · day" label above the bar) — ported from DS-6 analytics.html */
.barchart .bar { cursor: default; }
.bc-tip {
  position: absolute; pointer-events: none; z-index: 5; opacity: 0;
  transform: translate(-50%, -100%); transition: opacity var(--dur-fast) var(--ease);
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--shadow-raise); padding: 6px 10px; white-space: nowrap;
  font-size: 13px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums;
}
.bc-tip.show { opacity: 1; }
.bc-tip .bc-tip-sub { font-size: 11px; font-weight: 500; color: var(--text-3); margin-left: 6px; }

/* ── Line chart (up to 3 toggleable series) — ported from DS-6 analytics.html ─── */
.linechart-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); margin-bottom: 16px; flex-wrap: wrap; }
.linechart-legend { display: flex; flex-wrap: wrap; gap: var(--s2); }
.lc-toggle {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  font-size: 13px; font-weight: 500; color: var(--text-2);
  padding: 5px 11px; border-radius: var(--r-pill); background: var(--surface-2);
  border: 1px solid transparent; transition: color var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease);
  user-select: none;
}
.lc-toggle .lc-swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; background: var(--lc-color); }
.lc-toggle[aria-pressed="true"] { color: var(--text); }
.lc-toggle[aria-pressed="false"] { opacity: .45; }
.lc-toggle[aria-pressed="false"] .lc-swatch { background: var(--text-4); }
.linechart { display: block; width: 100%; height: 220px; overflow: visible; }
.linechart .lc-grid { stroke: var(--hairline); stroke-width: 1; vector-effect: non-scaling-stroke; }
.linechart .lc-area { opacity: .10; transition: opacity var(--dur) var(--ease); }
.linechart .lc-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; transition: opacity var(--dur) var(--ease); }
.linechart .lc-dot { transition: opacity var(--dur) var(--ease); }
.linechart .lc-series.off .lc-line,
.linechart .lc-series.off .lc-area,
.linechart .lc-series.off .lc-dot { opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  .linechart .lc-line { stroke-dasharray: var(--lc-len); stroke-dashoffset: var(--lc-len); animation: vs-draw 1.1s var(--ease) forwards; }
}
@keyframes vs-draw { to { stroke-dashoffset: 0; } }
.lc-wrap { position: relative; }
.lc-ticks { display: flex; justify-content: space-between; margin-top: 10px; font-size: 11px; color: var(--text-4); font-variant-numeric: tabular-nums; }
/* hover guide + focus dots + tooltip */
.linechart .lc-guide { stroke: var(--text-4); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0; vector-effect: non-scaling-stroke; }
.linechart .lc-focus { opacity: 0; }
.linechart .lc-focus circle { stroke: var(--bg-elevated); stroke-width: 2; }
.linechart.is-hover .lc-guide,
.linechart.is-hover .lc-focus { opacity: 1; }
.lc-tip {
  position: absolute; pointer-events: none; z-index: 5; opacity: 0;
  transform: translate(-50%, -100%); transition: opacity var(--dur-fast) var(--ease);
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--r-md);
  box-shadow: var(--shadow-raise); padding: 9px 12px; min-width: 124px;
}
.lc-tip.show { opacity: 1; }
.lc-tip .lc-tip-date { font-size: 11px; font-weight: 600; color: var(--text-3); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 7px; }
.lc-tip .lc-tip-row { display: flex; align-items: center; gap: 8px; font-size: 13px; line-height: 1.5; }
.lc-tip .lc-tip-row .lc-swatch { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.lc-tip .lc-tip-row .lc-tip-name { color: var(--text-2); }
.lc-tip .lc-tip-row .lc-tip-val { margin-left: auto; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.lc-tip .lc-tip-row.off { display: none; }

.dtable { width: 100%; border-collapse: collapse; }
.dtable th { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); text-align: left; font-weight: 600; padding-bottom: 6px; }
.dtable th.num, .dtable td.num { text-align: right; font-variant-numeric: tabular-nums; }
.dtable td { padding: 12px 0; border-top: 1px solid var(--hairline); font-size: 14px; color: var(--text); }
.dtable td.num { font-weight: 600; }
.dtable .mono { font-family: var(--font-mono); font-size: 13px; color: var(--text-2); }

/* admin "Zdraví systému" signal dots — green ok / amber warn (same --notice cue as the nav ni-dot) /
   grey n/a (subsystem never enabled, e.g. no invia_feed rows yet). */
.hs-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; vertical-align: middle; margin-right: 5px; background: var(--c-green); }
.hs-dot.warn { background: var(--notice); box-shadow: 0 0 0 3px var(--notice-fill); }
.hs-dot.na { background: var(--text-3); }
.hs-dot.bad { background: var(--c-red); box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-red) 22%, transparent); }

.kpi-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.kpi-pair .kp .kp-val { font-size: 28px; font-weight: 700; letter-spacing: -.5px; font-variant-numeric: tabular-nums; }
.kpi-pair .kp .kp-label { font-size: 12px; color: var(--text-3); margin-top: 4px; }
.analytics-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 20px; }
@media (max-width: 900px) { .analytics-grid { grid-template-columns: 1fr; } }

/* Live airport-reach preview (Account "Odkud létáš") — Resend-style: which airports a drive radius
   unlocks, lit up live. Tokens only; from Voyscout Design System (ui_kits/web/ucet.html). */
.live-preview { position: relative; }
.lp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.lp-head h3 { margin-bottom: 0; }
.lp-count { font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.lp-count b { color: var(--buy); font-weight: 700; }
.lp-sub { font-size: 12.5px; color: var(--text-2); line-height: 1.5; margin-bottom: 10px; }
.lp-sub b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
/* the exclude instruction sits AT the clickable list (not in the far-away form group) + doubles as the
   "these rows are interactive" cue — a quiet accent-soft chip, present on every breakpoint. */
.lp-hint { font-size: 11.5px; color: var(--text-3); line-height: 1.45; margin: 0 0 12px; padding: 7px 9px; background: var(--accent-soft); border-radius: var(--r-sm, 8px); }
.reach-list { display: flex; flex-direction: column; }
/* non-home rows are <button>s (a11y) → reset native chrome; grid keeps a trailing 16px slot for the ✕ affordance */
.reach-row { display: grid; grid-template-columns: 14px 26px 1fr auto 16px; align-items: center; gap: 11px; padding: 9px 2px; width: 100%; margin: 0; text-align: inherit; font: inherit; color: inherit; background: none; border: 0; appearance: none; -webkit-appearance: none; transition: opacity var(--dur, .22s) var(--ease); }
.reach-row + .reach-row { box-shadow: 0 -1px 0 var(--hairline); }
.reach-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-4); justify-self: center; transition: background var(--dur, .22s) var(--ease); }
.reach-flag { font-size: 16px; line-height: 1; }
.reach-name { font-size: 13.5px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: color var(--dur, .22s) var(--ease); }
.reach-name b { color: var(--text); font-weight: 600; }
.reach-km { font-size: 12.5px; color: var(--text-4); font-variant-numeric: tabular-nums; white-space: nowrap; }
.reach-x { justify-self: center; font-size: 10.5px; line-height: 1; color: var(--text-4); opacity: 0; transition: opacity var(--dur-fast) var(--ease); }
.reach-row.in .reach-dot { background: var(--accent); }
.reach-row.in .reach-name { color: var(--text); }
.reach-row.in .reach-km { color: var(--text-2); }
.reach-row.home .reach-dot { background: var(--buy); box-shadow: 0 0 0 3px var(--buy-fill); }
.reach-row.home .reach-name b { color: var(--text); }
.reach-row.home .reach-km { color: var(--buy); font-weight: 600; }
.reach-row.out { opacity: .4; }
.reach-row.out .reach-name { color: var(--text-3); }
.reach-row.collapsed { display: none; }
/* click-to-exclude: click a reachable airport to turn it off. A faint ✕ shows at rest (survives touch — no
   hover needed), brighter on hover/focus; excluded = grey dot + strikethrough + an explicit "Vypnuto/Off"
   chip so the state reads as intentional, never as an error. */
.reach-row.excludable { cursor: pointer; border-radius: 7px; }
.reach-row.excludable .reach-x { opacity: .3; }
.reach-row.excludable:hover, .reach-row.excludable:focus-visible { background: var(--accent-soft); }
.reach-row.excludable:hover .reach-x, .reach-row.excludable:focus-visible .reach-x { opacity: 1; }
.reach-row.excluded:hover, .reach-row.excluded:focus-visible { background: var(--hairline); }
.reach-row.excluded .reach-dot { background: var(--text-4); box-shadow: none; }
.reach-row.excluded .reach-name { text-decoration: line-through; color: var(--text-4); }
.reach-row.excluded .reach-name b { color: var(--text-4); }
.reach-row.excluded .reach-x { opacity: .85; color: var(--text-3); }
.reach-row.excluded .reach-km { color: var(--text-3); background: var(--accent-soft); padding: 1px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 600; letter-spacing: .02em; }
.reach-more { margin-top: 8px; padding: 7px 2px; background: none; border: 0; border-top: 1px solid var(--hairline); width: 100%; text-align: left; cursor: pointer; font: inherit; font-size: 12.5px; font-weight: 600; color: var(--accent); }
.reach-more:hover { color: var(--text); }
.reach-more[hidden] { display: none; }
@media (prefers-reduced-motion: no-preference) { .reach-row.flip .reach-dot { animation: vs-reach-pop .5s var(--ease); } }
@keyframes vs-reach-pop { 0% { transform: scale(.4); } 55% { transform: scale(1.5); } 100% { transform: scale(1); } }

/* ── "Kam to táhne": country multi-select + expandable airport sub-picker (Voyscout Design System-9) ── */
.country-grid {
  display: grid;
  /* auto-fill (NOT a fixed 3): the picker lives in cards of very different widths (account edit has
     a side panel, onboarding is full-width) while the old breakpoints watched the VIEWPORT - a wide
     window with a narrow card kept 3 rigid 1fr tracks whose min-content overflowed the card edge and
     clipped the 3rd column (owner report 2026-07-18). Columns now derive from the CONTAINER width;
     minmax(0,·) lets tracks shrink and c-name wraps instead of shooting past the frame. */
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 2px 20px;
}
.country-opt { min-width: 0; }
.country-opt .c-name { min-width: 0; overflow-wrap: anywhere; }
.country-opt { display: flex; align-items: center; gap: 11px; padding: 9px 2px; cursor: pointer; user-select: none; }
.country-opt input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.cbox {
  width: 20px; height: 20px; flex: none; border-radius: 6px;
  border: 1.5px solid var(--border); background: var(--bg-elevated);
  display: grid; place-items: center;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.cbox::after {
  content: ""; width: 9px; height: 5px; margin-top: -2px;
  border-left: 2px solid #fff; border-bottom: 2px solid #fff;
  transform: rotate(-45deg) scale(0); transform-origin: center;
  transition: transform var(--dur-fast) var(--ease);
}
.country-opt input:checked + .cbox { background: var(--accent); border-color: var(--accent); }
.country-opt input:checked + .cbox::after { transform: rotate(-45deg) scale(1); }
.country-opt input:focus-visible + .cbox { box-shadow: var(--focus); }
.country-opt:hover .cbox { border-color: var(--text-4); }
.country-opt .c-flag { font-size: 18px; line-height: 1; }
.country-opt .c-name { font-size: 14.5px; color: var(--text); }
.country-opt input:checked ~ .c-name { font-weight: 600; }
.dest-panel { margin-top: 8px; display: flex; flex-direction: column; gap: 10px; }
.dest-empty { font-size: 13px; color: var(--text-3); padding: 14px 2px 2px; }
.dest-block { background: var(--surface-2); border-radius: var(--r-lg); padding: 13px 15px; }
@media (prefers-reduced-motion: no-preference) { .dest-block { animation: vs-dest-in .26s var(--ease) both; } }
@keyframes vs-dest-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.dest-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 11px; }
.dest-title { display: flex; align-items: center; gap: 9px; font-size: 14px; font-weight: 600; color: var(--text); }
.dest-title .dt-flag { font-size: 17px; }
.dest-title .dt-count { font-size: 12px; font-weight: 500; color: var(--text-3); }
.dest-all { font: inherit; font-size: 12.5px; font-weight: 500; color: var(--accent); background: none; border: 0; cursor: pointer; padding: 2px 4px; border-radius: var(--r-sm); }
.dest-all:hover { text-decoration: underline; }
.apt-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.apt-chip {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: 13px; font-weight: 500; color: var(--text-2);
  background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: var(--r-pill); padding: 6px 13px; cursor: pointer;
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.apt-chip .apt-code { font-weight: 700; letter-spacing: .2px; }
.apt-chip .apt-tick { width: 14px; text-align: center; color: var(--text-4); transition: color var(--dur-fast) var(--ease); }
.apt-chip:hover { border-color: var(--text-4); }
.apt-chip[aria-pressed="true"] { background: var(--accent-soft); border-color: transparent; color: var(--accent); }
.apt-chip[aria-pressed="true"] .apt-tick { color: var(--accent); }
.apt-chip[aria-pressed="true"] .apt-code { color: var(--accent); }

/* ── DS-14 mode-aware destination picker ──────────────────────────────────────
   The mode (Zájezd / Letenky / Obojí) drives a live banner + which dest groups are
   active + the badge each group carries, so the user always sees what is actually
   watched. The hidden <select name=rails> stays in the form (no-JS submit). */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* live mode banner — calm accent strip that changes with the mode */
.mode-banner {
  display: flex; align-items: flex-start; gap: 12px;
  background: var(--accent-soft); border-radius: var(--r-md);
  padding: 12px 15px; margin: 16px 0 18px;
}
.mode-banner .mb-ico {
  flex: none; width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center;
  background: var(--bg-elevated); font-size: 15px; box-shadow: 0 1px 2px rgba(0,0,0,.08);
}
.mode-banner .mb-txt { font-size: 13.5px; color: var(--text-2); line-height: 1.5; }
.mode-banner .mb-txt b { color: var(--text); font-weight: 600; }
/* badge that states what each group/destination watches */
.wbadge {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 11px; font-weight: 600; white-space: nowrap;
  border-radius: var(--r-pill); padding: 2px 8px; letter-spacing: .2px;
}
.wbadge.pkg { color: var(--buy); background: var(--buy-fill); }       /* 🏖 + ✈ package */
.wbadge.fly { color: var(--accent); background: var(--accent-soft); }  /* ✈ flight only */
/* destination group (one per box) with header + on/off state */
.dest-group { margin-top: 6px; }
.dest-group + .dest-group { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--hairline); }
.dest-group-head { margin-bottom: 4px; }
.dest-group-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 14px; font-weight: 650; color: var(--text); }
.dest-group-title .dgt-badge { margin-left: 2px; }
.dest-group-sub { font-size: 13px; color: var(--text-3); margin: 4px 0 14px; line-height: 1.5; max-width: 62ch; }
/* country/city row — checked multi-airport rows show a compact "selected/total ✈" hint */
.country-opt .c-aptcount {
  margin-left: auto; font-size: 11px; font-weight: 600; color: var(--accent);
  background: var(--accent-soft); border-radius: var(--r-pill); padding: 1px 7px;
  font-variant-numeric: tabular-nums; white-space: nowrap; flex: none;
}
.country-opt .c-aptcount:empty { display: none; }
/* OFF group: not available in this mode — hide the picks, show a switch nudge */
.dest-group.is-off .country-grid,
.dest-group.is-off .dest-panel,
.dest-group.is-off .dest-empty { display: none; }
.dg-off-note {
  display: none; align-items: flex-start; gap: 11px;
  background: var(--surface-2); border-radius: var(--r-md); padding: 13px 15px;
  font-size: 13px; color: var(--text-2); line-height: 1.5;
}
.dest-group.is-off .dg-off-note { display: flex; }
.dg-off-note .dgn-ico { flex: none; color: var(--text-4); }
.dg-off-note b { color: var(--text); font-weight: 600; }
.dg-off-note .dgn-link { color: var(--accent); font-weight: 600; cursor: pointer; background: none; border: 0; font: inherit; padding: 0; }
.dg-off-note .dgn-link:hover { text-decoration: underline; }
/* inline nudge: beach country selected while in flight-only mode */
.dest-nudge {
  display: none; align-items: center; gap: 9px; margin-top: 12px;
  font-size: 12.5px; color: var(--notice-text);
  background: var(--notice-fill); border: 1px solid var(--notice-border); border-left: 3px solid var(--notice);
  border-radius: var(--r-md); padding: 9px 13px; line-height: 1.45;
}
.dest-nudge.show { display: flex; }
.dest-nudge .dn-ico { color: var(--notice); flex: none; }
.dest-nudge .dn-link { color: var(--notice); font-weight: 700; cursor: pointer; background: none; border: 0; font: inherit; padding: 0; }
.dest-nudge .dn-link:hover { text-decoration: underline; }
/* live "Co hlídáme" summary (inline below the picker) */
.watch-sum .ws-row {
  display: grid; grid-template-columns: 22px 1fr auto; align-items: center; gap: 10px;
  padding: 9px 2px;
}
.watch-sum .ws-row + .ws-row { box-shadow: 0 -1px 0 var(--hairline); }
.watch-sum .ws-flag { font-size: 16px; line-height: 1; }
.watch-sum .ws-name { font-size: 13.5px; color: var(--text); }
.watch-sum .ws-name small { color: var(--text-3); font-size: 12px; }
.watch-sum .ws-empty { font-size: 13px; color: var(--text-3); padding: 8px 2px; line-height: 1.5; }
.watch-sum .ws-foot { font-size: 12px; color: var(--text-4); margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--hairline); line-height: 1.5; }
.watch-sum .ws-foot:empty { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .watch-sum .ws-row { animation: vs-dest-in .24s var(--ease) both; }
}

/* "Ostatní letiště" — per-country resort comparison on a flight detail (multi-resort countries) */
.resort-list { display: flex; flex-direction: column; }
.resort-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 11px 2px; font-size: 14px; }
.resort-row + .resort-row { box-shadow: 0 -1px 0 var(--hairline); }
.resort-name { color: var(--text-2); }
.resort-row.win .resort-name { color: var(--text); font-weight: 600; }
.resort-price { font-variant-numeric: tabular-nums; color: var(--text-2); white-space: nowrap; }
.resort-row.win .resort-price { color: var(--buy); font-weight: 700; }
.resort-tag { font-size: 11px; color: var(--buy); font-weight: 600; margin-left: 4px; }
/* sibling-resort cross-links (Egypt → Hurghada/Marsa Alam): each row is a tappable link to that resort's detail */
.resort-row.sibling { text-decoration: none; color: inherit; cursor: pointer; border-radius: 8px; padding: 11px 8px; transition: background 0.12s; }
.resort-row.sibling:hover { background: var(--surface-2, rgba(127, 127, 127, 0.08)); }
.resort-row.sibling .resort-name { color: var(--text); }

/* ── 33. DS-11 scanning marks (radar/vista) + scan-strip + out-of-window + off-state ────────────────
   Shared empty/scanning vocabulary: radar = Letenky (sken jízdného), vista = Zájezdy (dovolená). The
   sweep carries a 5-segment comet tail (no bare arm → no wagon-wheel reverse illusion); blips stagger via
   three DELAY-FREE keyframes (an animation-delay stutters under the hover playbackRate scale — DS-11 v4).
   Hover is driven by app.js (radar pause()/play(); vista playbackRate 1.55) — NEVER :hover{animation-duration}.
   currentColor for the faint bowl/booties; var(--accent) for the live sweep/sun; reduced-motion = static. */
.radar, .vista { display: block; width: 92px; height: 92px; margin: 0 auto 16px; color: var(--text-3); }
.radar.sm, .vista.sm { width: 60px; height: 60px; margin: 0 auto 8px; }
/* radar */
.radar .rad-bowl { stroke-width: 1.4; opacity: .45; }
.radar .rad-bowl line { opacity: .55; }
.radar .rad-arm { stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round; }
.radar .rad-trail { stroke: var(--accent); stroke-width: 2.4; stroke-linecap: round; transform-origin: 60px 60px; }
.radar .rad-trail.t2 { opacity: .55; transform: rotate(-8deg); }
.radar .rad-trail.t3 { opacity: .38; transform: rotate(-16deg); }
.radar .rad-trail.t4 { opacity: .24; transform: rotate(-24deg); }
.radar .rad-trail.t5 { opacity: .12; transform: rotate(-32deg); }
.radar .rad-sweep { transform-origin: 60px 60px; }
.radar .rad-blip { fill: var(--accent); opacity: 0; transform-origin: center; transform-box: fill-box; }
/* vista */
.vista .vista-pan { transform-origin: 60px 84px; opacity: .72; }
.vista .vista-rays { transform-origin: 86px 31px; opacity: .85; }
.vista .vista-core { transform-origin: center; transform-box: fill-box; }

@media (prefers-reduced-motion: no-preference) {
  .radar .rad-sweep { animation: rad-spin 3.6s linear infinite; }
  .radar .rad-blip.b1 { animation: rad-blip-1 3.6s ease-out infinite; }
  .radar .rad-blip.b2 { animation: rad-blip-2 3.6s ease-out infinite; }
  .radar .rad-blip.b3 { animation: rad-blip-3 3.6s ease-out infinite; }
  .vista .vista-pan { animation: vista-pan 5.2s ease-in-out infinite; }
  .vista .vista-rays { animation: rad-spin 14s linear infinite; }
  .vista .vista-core { animation: vista-pulse 3s ease-in-out infinite; }
}
@keyframes rad-spin { to { transform: rotate(360deg); } }
@keyframes rad-blip-1 { 0%,8% { opacity: 0; transform: scale(.4); } 14% { opacity: 1; transform: scale(1); } 30%,100% { opacity: 0; transform: scale(.4); } }
@keyframes rad-blip-2 { 0%,42% { opacity: 0; transform: scale(.4); } 50% { opacity: 1; transform: scale(1); } 66%,100% { opacity: 0; transform: scale(.4); } }
@keyframes rad-blip-3 { 0%,72% { opacity: 0; transform: scale(.4); } 80% { opacity: 1; transform: scale(1); } 96%,100% { opacity: 0; transform: scale(.4); } }
@keyframes vista-pan { 0%,100% { transform: rotate(-7deg); } 50% { transform: rotate(7deg); } }
@keyframes vista-pulse { 0%,100% { transform: scale(.86); opacity: .8; } 50% { transform: scale(1.12); opacity: 1; } }

/* scan-strip — the ONE home for "Skenovat teď" + quota ring + meta, in the header on every state. */
.scan-strip { margin-top: 14px; }
.scan-strip .ss-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.scan-strip .scan-quota-line { margin-top: 8px; }

/* out-of-window (.outwin) — "nic v tvém termínu": left-aligned header (small calendar, NOT a big one) +
   nearest offers just past the edge, each with a context sub-label + an amber "+N" offset chip (--notice). */
.outwin { padding: 22px 24px; }
.outwin .ow-head { display: flex; align-items: flex-start; gap: 14px; }
.outwin .ow-ico { flex: none; width: 40px; height: 40px; border-radius: var(--r-md); display: grid; place-items: center; font-size: 19px; background: var(--surface); border: 1px solid var(--hairline); }
.outwin .ow-headtext h2 { font-size: 18px; font-weight: 600; margin: 2px 0 6px; }
.outwin .ow-headtext p { font-size: 13.5px; color: var(--text-2); line-height: 1.55; }
.outwin .ow-eyebrow { margin: 18px 0 2px; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); font-weight: 600; }
.outwin .offwin-list li { display: flex; align-items: center; gap: 12px; padding: 11px 0; border-bottom: none; font-size: 14px; }
.outwin .ow-main { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.outwin .ow-sub { font-size: 12px; color: var(--text-3); }
.outwin .ow-when { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; white-space: nowrap; }
.outwin .ow-date { color: var(--text-2); font-size: 12.5px; }
.outwin .ow-offset { font-size: 11.5px; font-weight: 600; color: var(--notice-text); background: var(--notice-fill); border: 1px solid var(--notice-border); border-radius: var(--r-pill); padding: 1px 8px; }
.outwin .ow-price { margin-left: 0; white-space: nowrap; font-weight: 700; color: var(--text); }
.outwin .ow-cta { margin-top: 16px; }

/* off-state (.ov-card.is-off + .ov-off) — a section the active profile doesn't scan: dimmed, NO travel-bg,
   NO animation; power glyph + "Vypnuto" tag + "Zapnout hledání" CTA (CHANGELOG v2 §32: off = no movement). */
.ov-card.is-off { background: var(--surface); border-style: dashed; }
.ov-card.is-off .ovc-eyebrow { color: var(--text-4); }
.ov-card .ov-off-tag { margin-left: auto; font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-3); background: var(--surface-2, rgba(127,127,127,.1)); border: 1px solid var(--hairline); border-radius: var(--r-pill); padding: 2px 9px; }
.ov-off { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 8px; padding: 18px 8px; opacity: .85; }
.ov-off .ov-off-glyph { font-size: 30px; color: var(--text-3); line-height: 1; }
.ov-off h3 { font-size: 15px; font-weight: 600; color: var(--text-2); }
.ov-off p { font-size: 13px; color: var(--text-3); line-height: 1.55; max-width: 34ch; }
.ov-off .btn { margin-top: 6px; }

/* ── 30. Public DEMO tour (/demo) ─────────────────────────────────────────────
   The public interactive product tour: brand + live-demo pill, headline, a browser-chrome FRAME
   wrapping an <iframe> of bundled static screens, tabs that swap the screen + theme mirrored into the
   frame, a trust row and a closing access-request CTA. DS-13: NO card shadows (the frame is a genuinely
   floating browser window → --shadow-pop is the allowed floating exception), single --accent, system
   font (inherited). Lifted from the DS-13 kit demo.html inline <style>. */
.demo-wrap { max-width: 1240px; margin: 0 auto; padding: 22px 24px 60px; position: relative; z-index: 1; }

/* top bar: brand + demo pill + toggles */
.demo-top { display: flex; align-items: center; gap: 16px; margin-bottom: 22px; flex-wrap: wrap; }
.demo-top .brand { padding-left: 0; font-size: 22px; }
.demo-pill {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 600; color: var(--accent);
  background: var(--accent-soft); border-radius: var(--r-pill); padding: 5px 12px;
}
.demo-pill .live { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); position: relative; }
.demo-pill .live::after { content:""; position:absolute; inset:-4px; border-radius:50%; border:1.5px solid var(--accent); opacity:.5; animation: live-ring 2s ease-out infinite; }
@keyframes live-ring { 0%{transform:scale(.6);opacity:.6} 100%{transform:scale(1.7);opacity:0} }
.demo-top .spacer { flex: 1; }

.demo-headline { margin-bottom: 18px; max-width: 720px; }
.demo-headline h1 { font-size: 34px; font-weight: 700; letter-spacing: -1px; }
.demo-headline p { font-size: 16px; color: var(--text-2); margin-top: 8px; line-height: 1.55; }
.demo-headline b { color: var(--text); font-weight: 600; }

/* the framed live app — the ONE allowed shadow (a floating browser window) */
.demo-frame {
  border-radius: 16px; overflow: hidden; background: var(--surface);
  border: 1px solid var(--hairline); box-shadow: var(--shadow-pop);
}
/* browser chrome */
.df-chrome {
  display: flex; align-items: center; gap: 12px; padding: 11px 14px;
  background: var(--bg-elevated); border-bottom: 1px solid var(--hairline);
}
.df-lights { display: flex; gap: 7px; }
.df-lights i { width: 11px; height: 11px; border-radius: 50%; display: block; }
.df-url {
  flex: 1; display: flex; align-items: center; gap: 8px; justify-content: center;
  font-size: 12.5px; color: var(--text-3); background: var(--surface);
  border-radius: var(--r-pill); padding: 5px 14px; max-width: 360px; margin: 0 auto;
}
.df-url .lock { color: var(--text-4); font-size: 11px; }

/* demo tab bar */
.df-tabs { display: flex; align-items: center; gap: 4px; padding: 8px 12px; background: var(--bg-elevated); border-bottom: 1px solid var(--hairline); flex-wrap: wrap; }
.df-tab {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: 13px; font-weight: 500; color: var(--text-2);
  background: none; border: 0; border-radius: var(--r-md); padding: 7px 13px; cursor: pointer;
}
.df-tab:hover { background: var(--surface); color: var(--text); }
.df-tab.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.df-tabs .spacer { flex: 1; }
.df-hint { font-size: 12px; color: var(--text-4); padding-right: 6px; display: flex; align-items: center; gap: 6px; }

.df-stage { position: relative; background: var(--bg); }
.df-stage iframe { width: 100%; height: 660px; border: 0; display: block; }
/* gentle fade between screens */
.df-stage.is-loading iframe { opacity: .35; transition: opacity .2s ease; }

/* trust row */
.demo-trust { display: flex; gap: 22px; flex-wrap: wrap; margin-top: 18px; padding-left: 4px; }
.demo-trust span { font-size: 12.5px; color: var(--text-4); display: inline-flex; align-items: center; gap: 7px; }
.demo-trust b { color: var(--text-3); font-weight: 600; }

/* closing CTA band — invite pill + access-request form (same as the apex waitlist) */
.demo-cta {
  margin-top: 22px; display: flex; align-items: flex-start; gap: 28px; flex-wrap: wrap;
  background: var(--surface); border-radius: var(--r-xl); padding: 24px 26px;
}
.demo-cta .cta-txt { flex: 1; min-width: 240px; }
.demo-cta h3 { font-size: 18px; font-weight: 650; }
.demo-cta p { font-size: 14px; color: var(--text-2); margin-top: 6px; line-height: 1.5; }
.demo-cta .cta-form { flex: 1; min-width: 260px; }

@media (max-width: 600px) { .df-stage iframe { height: 560px; } .demo-headline h1 { font-size: 26px; } }

/* ── Mobile bottom tab bar (PWA nav — DS17 §30) ───────────────────────────────
   A home-screen PWA hides the top-left hamburger, so on phones we surface the
   primary destinations as a fixed, safe-area-aware bottom tab bar (mirrors the
   Asistent app). Desktop keeps the sidebar; the bar stays hidden there. */
.tabbar { display: none; }
@media (max-width: 860px) {
  .tabbar {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
    padding: 8px 4px calc(8px + var(--sa-bottom));
    background: color-mix(in srgb, var(--bg) 88%, transparent);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    border-top: 1px solid var(--hairline);
  }
  .tabbar-item {
    flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 3px;
    text-decoration: none; color: var(--text-3); padding: 3px 0 2px; position: relative;
    -webkit-tap-highlight-color: transparent;
    transition: color var(--dur-fast) var(--ease);
  }
  .tabbar-item .tb-ico {
    font-size: 20px; line-height: 1; filter: grayscale(1); opacity: .55;
    transition: filter var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  }
  .tabbar-item .tb-lbl { font-size: 10.5px; font-weight: 500; letter-spacing: .05px; line-height: 1; }
  .tabbar-item:active .tb-ico { transform: scale(.9); }
  .tabbar-item.active { color: var(--accent); }
  .tabbar-item.active .tb-ico { filter: none; opacity: 1; }
  .tabbar-item.active .tb-lbl { font-weight: 600; }
  .tabbar-item .tb-badge {
    position: absolute; top: -3px; left: 50%; transform: translateX(4px);
    min-width: 16px; height: 16px; box-sizing: border-box; padding: 0 4px;
    border-radius: 999px; background: var(--accent); color: #fff;
    font-size: 10px; font-weight: 600; line-height: 16px; text-align: center;
    border: 1.5px solid var(--bg);
  }
  /* keep scrolling content clear of the fixed bar */
  .content-wrap { padding-bottom: calc(66px + var(--sa-bottom)); }
}

/* ============================================================================
   DS-18 guided tour + /help page styles (ported from kit ui_kits/web/tour.css).
   Themed via the existing custom properties above - no new tokens, no web fonts.
   ============================================================================ */
/* ============================================================================
   Voyscout — tour.css
   In-app guided tour: dimmed backdrop + rounded spotlight cut-out + tooltip
   bubble (desktop) / bottom-sheet (mobile). Themed entirely via the existing
   app.css custom properties — no new colors, no web fonts. Inline-able under a
   strict CSP. Younger sibling of the right-rail .explainer: same tokens, same
   quiet tone.
   ============================================================================ */

/* Root layer — holds everything, above topbar (z 20) and profile menu (z 60) */
.vtour {
  position: fixed; inset: 0; z-index: 900;
  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.vtour[hidden] { display: none; }

/* Click-catcher: blocks interaction with the page beneath while the tour runs.
   Sits UNDER the spotlight + bubble so those still receive events. */
.vtour-catcher {
  position: absolute; inset: 0; z-index: 1;
  background: transparent; cursor: default;
}

/* The spotlight: a box matched to the target rect. The oversized box-shadow
   dims the whole viewport EXCEPT this hole; a thin accent ring draws the eye.
   pointer-events:none so the darkened area doesn't swallow the target visually. */
.vtour-spot {
  position: absolute; z-index: 2; pointer-events: none;
  border-radius: 12px;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, .58), 0 0 0 2px var(--accent);
  transition: left .32s var(--ease, cubic-bezier(.4,0,.2,1)),
              top .32s var(--ease, cubic-bezier(.4,0,.2,1)),
              width .32s var(--ease, cubic-bezier(.4,0,.2,1)),
              height .32s var(--ease, cubic-bezier(.4,0,.2,1)),
              border-radius .32s var(--ease, cubic-bezier(.4,0,.2,1));
}
:root[data-theme="dark"] .vtour-spot { box-shadow: 0 0 0 9999px rgba(0, 0, 0, .70), 0 0 0 2px var(--accent); }
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] .vtour-spot { box-shadow: 0 0 0 9999px rgba(0, 0, 0, .70), 0 0 0 2px var(--accent); }
}

/* soft pulse ring — the "come look here" cue */
.vtour-spot::after {
  content: ""; position: absolute; inset: -2px; border-radius: inherit;
  box-shadow: 0 0 0 2px var(--accent);
  animation: vtour-pulse 2s var(--ease, cubic-bezier(.4,0,.2,1)) infinite;
}
@keyframes vtour-pulse {
  0%   { opacity: .9; transform: scale(1); }
  70%  { opacity: 0;  transform: scale(1.06); }
  100% { opacity: 0;  transform: scale(1.06); }
}

/* Centered / no-target step: full dim, no hole */
.vtour.is-centered .vtour-spot { display: none; }
.vtour.is-centered .vtour-catcher { background: rgba(0, 0, 0, .58); }
:root[data-theme="dark"] .vtour.is-centered .vtour-catcher { background: rgba(0, 0, 0, .72); }
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] .vtour.is-centered .vtour-catcher { background: rgba(0, 0, 0, .72); }
}

/* ── Tooltip bubble ──────────────────────────────────────────────────────── */
.vtour-bubble {
  position: absolute; z-index: 4; box-sizing: border-box;
  width: 320px; max-width: calc(100vw - 32px);
  background: var(--bg-elevated); color: var(--text);
  border: 1px solid var(--hairline); border-radius: var(--r-xl, 18px);
  box-shadow: var(--shadow-pop, 0 4px 24px rgba(0,0,0,.10), 0 1px 3px rgba(0,0,0,.06));
  padding: 18px 18px 14px;
  opacity: 0; transform: translateY(4px) scale(.99);
  transition: opacity .18s var(--ease, cubic-bezier(.4,0,.2,1)),
              transform .18s var(--ease, cubic-bezier(.4,0,.2,1)),
              left .28s var(--ease, cubic-bezier(.4,0,.2,1)),
              top .28s var(--ease, cubic-bezier(.4,0,.2,1));
}
.vtour.is-ready .vtour-bubble { opacity: 1; transform: none; }
.vtour.is-centered .vtour-bubble { width: 380px; }

/* arrow */
.vtour-arrow {
  position: absolute; width: 12px; height: 12px;
  background: var(--bg-elevated);
  border: 1px solid var(--hairline); border-right: 0; border-bottom: 0;
  transform: rotate(45deg);
}
.vtour.is-centered .vtour-arrow { display: none; }

/* header row: step meta + close */
.vtour-top { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.vtour-kicker {
  font-size: 11px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase;
  color: var(--text-3);
}
.vtour-x {
  margin-left: auto; flex: none; width: 28px; height: 28px; border-radius: var(--r-sm, 8px);
  border: 0; background: transparent; color: var(--text-3); cursor: pointer;
  font-size: 16px; line-height: 1; display: flex; align-items: center; justify-content: center;
  transition: background var(--dur-fast, 120ms) var(--ease, cubic-bezier(.4,0,.2,1)), color var(--dur-fast, 120ms) var(--ease, cubic-bezier(.4,0,.2,1));
}
.vtour-x:hover { background: var(--surface); color: var(--text); }

.vtour-title { font-size: 17px; font-weight: 600; letter-spacing: -.3px; line-height: 1.3; }
.vtour-body { font-size: 14px; line-height: 1.55; color: var(--text-2); margin-top: 6px; }
.vtour-body b { color: var(--text); font-weight: 600; }

/* verdict swatches used inline in the trust step */
.vtour-body .vtour-verdicts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.vtour-tag {
  font-size: 11px; font-weight: 700; letter-spacing: .3px;
  padding: 3px 9px; border-radius: var(--r-pill, 980px);
  display: inline-flex; align-items: center; gap: 5px;
}
.vtour-tag .d { width: 7px; height: 7px; border-radius: 50%; }
.vtour-tag.buy   { color: var(--buy);   background: var(--buy-fill); }
.vtour-tag.buy .d   { background: var(--buy); }
.vtour-tag.wait  { color: var(--wait);  background: var(--wait-fill); }
.vtour-tag.wait .d  { background: var(--wait); }
.vtour-tag.watch { color: var(--watch); background: var(--watch-fill); }
.vtour-tag.watch .d { background: var(--watch); }

/* footer: progress + nav */
.vtour-foot { display: flex; align-items: center; gap: 12px; margin-top: 16px; }
.vtour-dots { display: flex; gap: 5px; align-items: center; }
.vtour-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--border); transition: background var(--dur-fast, 120ms) var(--ease, cubic-bezier(.4,0,.2,1)), transform var(--dur-fast, 120ms) var(--ease, cubic-bezier(.4,0,.2,1)); }
.vtour-dot.on { background: var(--accent); transform: scale(1.3); }
.vtour-count { font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }

.vtour-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.vtour-btn {
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  border-radius: var(--r-md, 10px); padding: 9px 15px; border: 1px solid transparent;
  min-height: 40px; white-space: nowrap;
  transition: filter var(--dur-fast, 120ms) var(--ease, cubic-bezier(.4,0,.2,1)),
              background var(--dur-fast, 120ms) var(--ease, cubic-bezier(.4,0,.2,1)),
              transform var(--dur-fast, 120ms) var(--ease, cubic-bezier(.4,0,.2,1));
}
.vtour-btn:active { transform: scale(.98); }
.vtour-btn.primary { background: var(--accent); color: var(--on-accent, #fff); }
.vtour-btn.primary:hover { filter: brightness(.95); }
.vtour-btn.ghost { background: transparent; color: var(--text-2); padding: 9px 10px; }
.vtour-btn.ghost:hover { background: var(--surface); color: var(--text); }

/* the "skip" link — quiet, on its own */
.vtour-skip {
  display: block; width: 100%; text-align: center; margin-top: 10px;
  font: inherit; font-size: 12.5px; color: var(--text-3); background: none; border: 0;
  cursor: pointer; padding: 6px; border-radius: var(--r-sm, 8px);
}
.vtour-skip:hover { color: var(--text-2); text-decoration: underline; }

/* ── Mobile / PWA: bubble becomes a safe-area-aware bottom sheet ──────────── */
@media (max-width: 640px) {
  .vtour-bubble,
  .vtour.is-centered .vtour-bubble {
    left: 0 !important; right: 0; top: auto !important; bottom: 0;
    width: 100%; max-width: 100%;
    border-radius: 20px 20px 0 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    padding: 16px 18px calc(14px + var(--sa-bottom));
    transform: translateY(6px);
  }
  .vtour.is-ready .vtour-bubble { transform: none; }
  .vtour-arrow { display: none !important; }
  .vtour-bubble::before {
    content: ""; display: block; width: 38px; height: 5px; border-radius: 100px;
    background: var(--border); margin: -4px auto 12px;
  }
  .vtour-btn { min-height: 44px; padding: 11px 16px; }   /* ≥44px tap targets */
  .vtour-actions { flex: 1; }
  .vtour-btn.primary { flex: 1; justify-content: center; text-align: center; }
}

/* ── Reduced motion: instant everything ──────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .vtour-spot, .vtour-bubble { transition: none !important; }
  .vtour-spot::after { animation: none; opacity: 0; }
}

/* ── Help-page bits (live in app.css world, scoped here to keep the addition
      self-contained) ─────────────────────────────────────────────────────── */
.help-hero {
  background: var(--surface); border-radius: var(--r-xl, 18px);
  padding: var(--s7, 32px); display: flex; gap: var(--s7, 32px);
  align-items: center; flex-wrap: wrap;
}
.help-hero .hh-body { flex: 1; min-width: 240px; }
.help-hero h1 { font-size: 30px; font-weight: 700; letter-spacing: -.8px; line-height: 1.1; }
.help-hero p { font-size: 16px; line-height: 1.55; color: var(--text-2); margin-top: 10px; max-width: 52ch; }
.help-hero .hh-mark {
  width: 76px; height: 76px; border-radius: 20px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent-soft);
}
.help-hero .hh-cta { margin-top: 20px; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.help-hero .hh-note { font-size: 12.5px; color: var(--text-3); }

.help-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s5, 20px); margin-top: var(--s6, 24px); }
.help-sec {
  background: var(--bg-elevated); border: 1px solid var(--hairline);
  border-radius: var(--r-xl, 18px); padding: var(--s6, 24px);
}
.help-sec .hs-ico { font-size: 22px; line-height: 1; }
.help-sec h2 { font-size: 16px; font-weight: 600; letter-spacing: -.2px; margin-top: 12px; }
.help-sec p { font-size: 14px; line-height: 1.6; color: var(--text-2); margin-top: 7px; }
.help-sec p b { color: var(--text); font-weight: 600; }
.help-sec .hs-verdicts { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.help-sec .hs-vrow { display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; line-height: 1.5; color: var(--text-2); }
.help-sec .hs-vrow .verdict { flex: none; }
@media (max-width: 720px) { .help-grid { grid-template-columns: 1fr; } .help-hero h1 { font-size: 25px; } }

/* ============================================================================
   DS-19 (ported from kit): stale "needs a scan" badge (žlutá kulička) on the
   sidebar + the PWA tabbar, and pull-to-refresh (mobile/PWA). Themed via existing
   tokens; env(safe-area-inset-*) routed through the shimmable --sa-* vars (the
   app's safe-area contract). Selectors are specific → apply only where used.
   ============================================================================ */
/* stale / needs-scan: the profile was edited so this group's data is no longer fresh →
   the count pill collapses to an amber dot. Semantics = --notice (attention), NOT
   --wait/POČKAT (that's a price verdict). Toggled in the render on flights/packages mismatch. */
.nav-item .ni-badge.is-stale {
  min-width: 0; width: 9px; height: 9px; padding: 0; align-self: center;
  background: var(--notice); color: transparent; font-size: 0;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--notice) 15%, transparent);
}
.tabbar-item .tb-badge.is-stale {
  min-width: 0; width: 10px; height: 10px; padding: 0;
  left: calc(50% + 7px); transform: none;
  background: var(--notice); color: transparent; font-size: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .ni-badge.is-stale, .tb-badge.is-stale { animation: vs-stale-pop .32s var(--ease); }
}
@keyframes vs-stale-pop { 0% { transform: scale(.2); } 60% { transform: scale(1.35); } 100% { transform: scale(1); } }

/* pull-to-refresh (mobile/PWA) — indicator injected + driven by pull-refresh.js (in app.js).
   The compass mark (our logo) drops into the gap under the topbar; past the threshold it locks
   to accent, then spins like the logo while the page reloads. Invisible until JS activates it. */
.ptr-ind {
  position: fixed; left: 50%; z-index: 15;
  top: calc(var(--sa-top) + 66px);
  width: 40px; height: 40px; margin-left: -20px;
  display: grid; place-items: center; border-radius: 50%;
  background: var(--bg); border: 1px solid var(--hairline);
  box-shadow: var(--shadow-pop); color: var(--text-3);
  opacity: 0; pointer-events: none;
  transform: translateY(-24px) scale(.7);
  will-change: transform, opacity;
}
.ptr-ind.ptr-anim { transition: transform .34s var(--ease), opacity .22s var(--ease); }
.ptr-mark { width: 22px; height: 22px; display: block; transform-origin: 50% 50%; }
.ptr-mark .ptr-ring { stroke: currentColor; opacity: .55; }
.ptr-mark .ptr-n { fill: var(--accent); }
.ptr-mark .ptr-s { fill: currentColor; opacity: .5; }
.ptr-mark .ptr-core { fill: currentColor; }
.ptr-ind.is-ready { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--hairline)); }
.ptr-ind.is-busy  { color: var(--accent); }
.ptr-ind.is-busy .ptr-mark { transform: none !important; }
@media (prefers-reduced-motion: no-preference) {
  .ptr-ind.is-busy .ptr-mark { animation: ptr-spin .9s cubic-bezier(.5,0,.5,1) infinite; }
}
@keyframes ptr-spin { to { transform: rotate(360deg); } }
.ptr-shift { will-change: transform; }
.ptr-shift.ptr-anim { transition: transform .34s var(--ease); }

/* ==== Public blog + site chrome — ported from Voyscout Design System v21 (ui_kits/web/app.css §34-35). Uses existing tokens; 0 selector dupes verified. ==== */
/* ── 34. Blog ─────────────────────────────────────────────────────────────────
   Content surface — post list + single article. On brand: NO stock photography
   (Voyscout is data, not photos). Thumbnails are ambient generative panels built
   from the same arc/blip vocabulary as the dashboard travel-bg, tinted per
   category via a `--cat` custom property set inline on each card. */
.blog-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 22px; margin-top: var(--s6); }
@media (max-width: 1100px) { .blog-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 680px)  { .blog-grid { grid-template-columns: 1fr; } }

/* post card — a whole clickable tile */
.post-card {
  --cat: var(--accent);
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--hairline);
  border-radius: var(--r-xl); overflow: hidden;
  text-decoration: none; color: inherit;
  transition: background var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.post-card:hover { background: var(--surface-2); opacity: 1; }
.post-card:active { transform: scale(.995); }

/* generative thumbnail */
.blog-thumb {
  position: relative; aspect-ratio: 16 / 10; overflow: hidden;
  border-bottom: 1px solid var(--hairline);
  background:
    radial-gradient(130% 120% at 12% 0%, color-mix(in srgb, var(--cat) 22%, var(--surface)) 0%, var(--surface) 68%);
}
.bt-arcs { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.bt-arcs .a {
  fill: none; stroke: var(--cat); stroke-width: 1.4; stroke-linecap: round;
  stroke-dasharray: 2 15; opacity: .55; vector-effect: non-scaling-stroke;
}
.bt-arcs .a.solid { stroke-dasharray: none; opacity: .38; }
.bt-arcs .blip { fill: var(--cat); }
.bt-arcs .blip.o { fill: none; stroke: var(--cat); stroke-width: 2; }
.post-card:hover .bt-arcs { opacity: .85; }
.bt-cat {
  position: absolute; top: 12px; left: 12px; z-index: 2;
  font-size: 11px; font-weight: 600; letter-spacing: .5px; text-transform: uppercase;
  color: var(--cat);
  background: color-mix(in srgb, var(--cat) 15%, var(--bg));
  padding: 5px 10px; border-radius: var(--r-pill);
}
.bt-glyph { position: absolute; right: 16px; bottom: 14px; width: 54px; height: 54px; color: var(--cat); opacity: .9; }

.post-body { display: flex; flex-direction: column; gap: 8px; flex: 1; padding: 18px 20px 20px; }
.post-title { font-size: 18px; font-weight: 600; letter-spacing: -.3px; line-height: 1.3; color: var(--text); }
.post-excerpt { font-size: 14px; color: var(--text-2); line-height: 1.55; }
.post-meta { margin-top: auto; padding-top: 8px; display: flex; align-items: center; gap: 9px; font-size: 12.5px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.post-meta .mdot { width: 3px; height: 3px; border-radius: 50%; background: var(--text-4); }

/* featured (first post on the list) — wide horizontal tile */
.post-card.feat { grid-column: 1 / -1; flex-direction: row; }
.post-card.feat .blog-thumb { aspect-ratio: auto; width: 46%; min-height: 280px; border-bottom: none; border-right: 1px solid var(--hairline); }
.post-card.feat .bt-glyph { width: 72px; height: 72px; }
.post-card.feat .post-body { justify-content: center; gap: 12px; padding: 34px 38px; }
.post-card.feat .bt-cat-inline { align-self: flex-start; }
.post-card.feat .post-title { font-size: 27px; letter-spacing: -.7px; line-height: 1.15; }
.post-card.feat .post-excerpt { font-size: 15.5px; line-height: 1.6; max-width: 54ch; }
@media (max-width: 820px) {
  .post-card.feat { flex-direction: column; }
  .post-card.feat .blog-thumb { width: 100%; aspect-ratio: 16 / 9; min-height: 0; border-right: none; border-bottom: 1px solid var(--hairline); }
  .post-card.feat .post-body { padding: 22px 22px 24px; }
  .post-card.feat .post-title { font-size: 22px; }
}

/* inline category label (used in featured body + article head) */
.cat-label {
  --cat: var(--accent);
  display: inline-flex; align-items: center;
  font-size: 11px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase;
  color: var(--cat);
  background: color-mix(in srgb, var(--cat) 15%, var(--bg));
  padding: 5px 11px; border-radius: var(--r-pill);
}

/* blog filter row */
.blog-cats { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; margin: var(--s6) 0 0; }
.blog-cats .bc {
  font-size: 13px; font-weight: 500; color: var(--text-2);
  background: var(--surface); border: 1px solid var(--hairline);
  padding: 7px 14px; border-radius: var(--r-pill); cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.blog-cats .bc:hover { background: var(--surface-2); opacity: 1; }
.blog-cats .bc.active { background: var(--accent); color: var(--on-accent); border-color: transparent; }

/* section header (blog preview on the dashboard) */
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin: var(--s8) 0 2px; }
.section-head h2 { font-size: 20px; font-weight: 650; letter-spacing: -.4px; }
.section-head .sh-link { font-size: 13px; font-weight: 500; color: var(--accent); white-space: nowrap; }

/* ── single article ───────────────────────────────────────────────────────── */
.article { max-width: 720px; margin: 0 auto; }
.article-head { margin-bottom: 8px; }
.article-head h1 { font-size: 36px; font-weight: 700; letter-spacing: -1px; line-height: 1.12; margin-top: 14px; }
.article-lede { font-size: 19px; color: var(--text-2); line-height: 1.5; margin-top: 16px; max-width: 60ch; }
.article-byline { display: flex; align-items: center; gap: 11px; margin-top: 20px; font-size: 13.5px; color: var(--text-3); }
.article-byline .avatar { width: 34px; height: 34px; font-size: 14px; flex: none; }
.article-byline b { color: var(--text-2); font-weight: 600; }
.article-byline .bdot { width: 3px; height: 3px; border-radius: 50%; background: var(--text-4); }
.article-banner {
  position: relative; aspect-ratio: 16 / 7; overflow: hidden;
  border: 1px solid var(--hairline); border-radius: var(--r-xl);
  margin: 26px 0 32px;
}
.article-banner .bt-glyph { width: 96px; height: 96px; right: 28px; bottom: 22px; }

.prose { font-size: 16.5px; line-height: 1.72; color: var(--text); }
.prose > * + * { margin-top: 18px; }
.prose p { color: var(--text-2); }
.prose h2 { font-size: 22px; font-weight: 650; letter-spacing: -.4px; color: var(--text); margin-top: 36px; }
.prose h3 { font-size: 17px; font-weight: 600; color: var(--text); margin-top: 28px; }
.prose ul, .prose ol { padding-left: 22px; }
.prose li { color: var(--text-2); margin-top: 8px; }
.prose li::marker { color: var(--text-4); }
.prose strong { color: var(--text); font-weight: 600; }
.prose a { color: var(--accent); }
.prose code { font-family: var(--mono, ui-monospace, monospace); font-size: 14px; background: var(--surface); padding: 2px 6px; border-radius: var(--r-sm); color: var(--text); }
.prose blockquote {
  border-left: 3px solid var(--accent); padding: 2px 0 2px 20px; margin-left: 0;
  font-size: 18px; line-height: 1.55; color: var(--text-2);
}
.prose figure { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--r-lg); padding: 18px 20px; }
.prose figure .fig-cap { font-size: 12.5px; color: var(--text-3); margin-top: 12px; }
.prose hr { border: 0; height: 1px; background: var(--hairline); margin: 32px 0; }

/* tags + newer/older nav */
.article-tags { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 34px; }
.post-nav {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
  margin-top: 30px; padding-top: 28px; border-top: 1px solid var(--hairline);
}
.post-nav a {
  display: flex; flex-direction: column; gap: 5px;
  padding: 16px 18px; border: 1px solid var(--hairline); border-radius: var(--r-lg);
  text-decoration: none; transition: background var(--dur-fast) var(--ease);
}
.post-nav a:hover { background: var(--surface); opacity: 1; }
.post-nav .pn-dir { font-size: 12px; font-weight: 600; letter-spacing: .5px; text-transform: uppercase; color: var(--text-3); display: flex; align-items: center; gap: 6px; }
.post-nav .pn-title { font-size: 15px; font-weight: 600; color: var(--text); line-height: 1.35; }
.post-nav .older { text-align: right; }
.post-nav .older .pn-dir { justify-content: flex-end; }
.post-nav .is-disabled { opacity: .4; pointer-events: none; }
@media (max-width: 560px) {
  .post-nav { grid-template-columns: 1fr; }
  .post-nav .older { text-align: left; }
  .post-nav .older .pn-dir { justify-content: flex-start; }
}

/* blog preview strip on the splash / invite page — sits below the centered
   auth card, above the fixed ambient bg. Reuses .section-head + .blog-grid. */
.splash-blog { position: relative; z-index: 1; max-width: 1080px; margin: 0 auto; padding: 4px 24px 72px; }
.splash-blog .section-head { margin-top: 0; border-top: 1px solid var(--hairline); padding-top: 30px; }
.splash-blog .section-head h2 { font-size: 18px; }

/* glyph gallery — reference grid of reusable article-thumbnail icons */
.glyph-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 16px; margin-top: var(--s5); }
.glyph-tile { display: flex; flex-direction: column; gap: 9px; }
.glyph-tile .blog-thumb { aspect-ratio: 16 / 11; border-radius: var(--r-lg); }
.glyph-tile .bt-glyph { width: 46px; height: 46px; }
.glyph-tile .gt-name { display: flex; align-items: center; justify-content: center; gap: 7px; font-size: 12.5px; color: var(--text-2); text-align: center; }
.glyph-tile .gt-name code { font-family: var(--mono, ui-monospace, monospace); font-size: 12px; color: var(--text); background: var(--surface); padding: 2px 7px; border-radius: var(--r-sm); }


/* ── 35. Public site chrome (apex / logged-out — no app sidebar) ──────────────
   The marketing surface at voyscout.com: sticky translucent header with the
   wordmark + a few links + login CTA, a centered hero over the ambient
   travel-bg, and a footer. Used by landing + the public blog (readable without
   an account). Same tokens/theme as the app. */
.site { min-height: 100vh; display: flex; flex-direction: column; background: var(--bg); }
.site-header {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 16px;
  padding: 13px 28px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--hairline);
}
.site-header .brand { padding: 0; font-size: 18px; }
.site-nav { display: flex; align-items: center; gap: 2px; margin-left: 10px; }
.site-nav a { font-size: 14px; font-weight: 500; color: var(--text-2); padding: 8px 12px; border-radius: var(--r-md); }
.site-nav a:hover { color: var(--text); background: var(--surface); opacity: 1; }
.site-nav a.active { color: var(--text); }
.site-actions { margin-left: auto; display: flex; align-items: center; gap: 12px; }
@media (max-width: 760px) { .site-nav { display: none; } .site-header { padding: 11px 18px; gap: 10px; } }
/* phones: brand + lang seg + theme seg + sign-in overflowed 390px (clipped "Přihlásit se", persona 2026-07-12).
   Drop the theme toggle on narrow screens — theme follows the OS (prefers-color-scheme); the in-app board keeps its own. */
@media (max-width: 480px) { .site-header .seg[aria-label="Theme"] { display: none; } .site-actions { gap: 8px; } }

.site-main { flex: 1; width: 100%; }
.site-section { max-width: 1080px; margin: 0 auto; padding: 0 28px; width: 100%; }
.site-section.narrow { max-width: 820px; }

/* hero */
.hero { position: relative; overflow: hidden; }
.hero-inner { position: relative; z-index: 1; max-width: 940px; margin: 0 auto; padding: 96px 28px 84px; text-align: center; }
.hero .eyebrow { justify-content: center; margin-bottom: 20px; }
.hero h1 { font-size: 58px; font-weight: 700; letter-spacing: -1.8px; line-height: 1.04; max-width: 15ch; margin: 0 auto; text-wrap: balance; }
.hero-lede { font-size: 20px; color: var(--text-2); line-height: 1.5; max-width: 54ch; margin: 22px auto 0; text-wrap: pretty; }
.hero-cta { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 34px; }
.hero-note { font-size: 13px; color: var(--text-3); margin-top: 18px; }
@media (max-width: 620px) { .hero h1 { font-size: 38px; letter-spacing: -1px; } .hero-lede { font-size: 17px; } .hero-inner { padding: 60px 20px 58px; } }

/* value strip — reuses the verdict vocabulary */
.value-strip { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.value-card { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--r-xl); padding: 24px 24px 26px; }
.value-card .vc-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.value-card h3 { font-size: 16px; font-weight: 600; letter-spacing: -.2px; }
.value-card p { font-size: 14px; color: var(--text-2); line-height: 1.6; }
@media (max-width: 760px) { .value-strip { grid-template-columns: 1fr; } }

/* public section header */
.site-sec-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-bottom: 6px; flex-wrap: wrap; }
.site-sec-head h2 { font-size: 30px; font-weight: 700; letter-spacing: -.8px; }
.site-sec-head p { font-size: 15px; color: var(--text-2); margin-top: 6px; }
.site-sec-head .sh-link { font-size: 14px; font-weight: 500; color: var(--accent); white-space: nowrap; }
.site-block { margin-top: 84px; }
.site-block:first-child { margin-top: 56px; }
@media (max-width: 620px) { .site-block { margin-top: 60px; } .site-sec-head h2 { font-size: 24px; } }

/* footer */
.site-foot { border-top: 1px solid var(--hairline); margin-top: 96px; }
.sf-inner { max-width: 1080px; margin: 0 auto; padding: 44px 28px 40px; display: flex; flex-wrap: wrap; gap: 40px; align-items: flex-start; justify-content: space-between; }
.sf-brand { max-width: 300px; }
.sf-brand .brand { padding: 0 0 12px; font-size: 18px; }
.sf-legal { font-size: 12.5px; color: var(--text-3); line-height: 1.6; }
.sf-cols { display: flex; gap: 56px; flex-wrap: wrap; }
.sf-col h4 { font-size: 12px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; color: var(--text-3); margin-bottom: 12px; }
.sf-col a { display: block; font-size: 14px; color: var(--text-2); padding: 5px 0; }
.sf-col a:hover { color: var(--text); opacity: 1; }
@media (max-width: 620px) { .sf-cols { gap: 36px; } }


/* ── 36. Feedback widget ─────────────────────────────────────────────────────
   In-app zpětná vazba (DS feedback mockup). Tři stavy: trigger (menu přihlášené
   aplikace, volitelný žlutý badge když aktivně sbíráme), panel (popover na
   desktopu / bottom-sheet na mobilu), auto-nudge (stejný panel, jen se ukáže
   sám — nikdy přes obsah, ✕ vždy vidět). Žádné hvězdičky, žádné NPS — tři
   smajlíky, max 3 tapy do odeslání. */

/* trigger — v produktu sedí v sidebar navigaci jako <button class="nav-item fb-trigger">.
   DS motion (feedback-trigger.html): na hover se řádek podloží tichou pill (.nav-item:hover
   background už dělá) a bublina ikony JEDNOU zamává (transform-origin u špičky); během sběru
   badge halo pomalu DÝCHÁ (3s rytmus, jen box-shadow, tečka samotná se nehýbe). Vše výhradně
   pod prefers-reduced-motion: no-preference — dýchání není blikání, nic nepřekrývá obsah. */
.fb-trigger {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 500; color: var(--text-3);
  background: none; border: none; padding: 6px 2px; cursor: pointer;
  border-radius: var(--r-md);
  transition: color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.fb-trigger:hover { color: var(--text); background: var(--surface); opacity: 1; }
.fb-trigger:active { background: var(--surface-2); }
.fb-trigger .fb-ico { width: 15px; height: 15px; flex: none; transform-origin: 50% 100%; }
/* the nav-item variant inherits the sidebar row look; reset the button chrome + full row width */
button.nav-item.fb-trigger { width: 100%; font: inherit; text-align: left; }
/* standalone placement (between the primary destinations and the Settings group): a quiet standing
   channel, so give it a hairline separator above + a touch more presence than the muted in-settings
   look. The divider is a ::before in the row gap, so the hover pill (button background) never covers it. */
.fb-trigger.fb-standalone { color: var(--text-2); margin-top: 8px; position: relative; }
.fb-trigger.fb-standalone::before {
  content: ""; position: absolute; left: 10px; right: 10px; top: -5px; height: 1px;
  background: var(--hairline); pointer-events: none;
}
.nav-item .fb-dot { margin-left: auto; }
.fb-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--wait, #c77a00);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--wait, #c77a00) 22%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
  .fb-trigger:hover .fb-ico { animation: fb-wave .55s var(--ease); }
  @keyframes fb-wave {
    30% { transform: rotate(-10deg); }
    65% { transform: rotate(7deg); }
  }
  .fb-dot { animation: fb-breathe 3s ease-in-out infinite; }
  @keyframes fb-breathe {
    0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--wait, #c77a00) 22%, transparent); }
    50%      { box-shadow: 0 0 0 5px color-mix(in srgb, var(--wait, #c77a00) 10%, transparent); }
  }
}

/* panel — desktop popover */
.fb-panel {
  position: fixed; right: 22px; bottom: 22px; z-index: 60;
  width: 344px; max-width: calc(100vw - 44px);
  background: var(--bg-elevated); border: 1px solid var(--hairline);
  border-radius: var(--r-xl); padding: 20px;
  box-shadow: 0 16px 44px rgba(0,0,0,.16), 0 2px 8px rgba(0,0,0,.06);
}
@media (prefers-reduced-motion: no-preference) {
  .fb-panel { animation: fb-in .32s var(--ease) both; }
  @keyframes fb-in { from { opacity: 0; transform: translateY(10px); } }
  .fb-panel.closing { transition: opacity .2s var(--ease), transform .2s var(--ease); opacity: 0; transform: translateY(8px); }
}
.fb-panel h3 { font-size: 16px; font-weight: 650; letter-spacing: -.2px; padding-right: 30px; }
.fb-close {
  position: absolute; top: 10px; right: 10px;
  width: 34px; height: 34px; display: grid; place-items: center;
  font-size: 14px; color: var(--text-3);
  background: none; border: none; border-radius: 50%; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.fb-close:hover { background: var(--surface); color: var(--text); opacity: 1; }

/* smajlíky */
.fb-faces { display: flex; gap: 10px; margin-top: 14px; }
.fb-face {
  flex: 1; min-height: 76px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  background: var(--surface); border: 1.5px solid var(--hairline); border-radius: var(--r-lg);
  padding: 10px 6px; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.fb-face:hover { background: var(--surface-2); opacity: 1; }
.fb-face:active { transform: scale(.96); }
.fb-face .em { font-size: 28px; line-height: 1; }
.fb-face small { font-size: 11.5px; font-weight: 500; color: var(--text-2); }
.fb-face.selected {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 9%, var(--bg-elevated));
}
.fb-face.selected small { color: var(--accent); font-weight: 600; }

/* volitelný dovětek */
.fb-more { display: none; flex-direction: column; gap: 10px; margin-top: 14px; }
.fb-more.open { display: flex; }
.fb-more label { font-size: 12.5px; font-weight: 500; color: var(--text-2); }
.fb-text {
  width: 100%; min-height: 72px; resize: vertical;
  font: inherit; font-size: 14px; line-height: 1.5; color: var(--text);
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--r-md);
  padding: 10px 12px; outline: none;
  transition: border-color var(--dur-fast) var(--ease);
}
.fb-text:focus { border-color: var(--accent); }

/* thanks */
.fb-thanks { text-align: center; padding: 18px 6px 8px; }
.fb-thanks .fb-check {
  width: 44px; height: 44px; margin: 0 auto 12px; display: grid; place-items: center;
  border-radius: 50%; font-size: 20px;
  color: var(--buy, #1f8a5b);
  background: color-mix(in srgb, var(--buy, #1f8a5b) 12%, var(--bg-elevated));
}
.fb-thanks p { font-size: 14.5px; font-weight: 500; color: var(--text); }

/* mobil — bottom-sheet */
@media (max-width: 680px) {
  .fb-panel {
    left: 0; right: 0; bottom: 0; width: auto; max-width: none;
    border-radius: var(--r-xl) var(--r-xl) 0 0; border-bottom: none;
    padding: 18px 20px calc(20px + var(--sa-bottom)); /* safe-area via the :root shim, never raw env() */
  }
  .fb-panel::before {
    content: ""; display: block; width: 36px; height: 4px; margin: 0 auto 14px;
    border-radius: 2px; background: var(--hairline);
  }
  @media (prefers-reduced-motion: no-preference) {
    .fb-panel { animation: fb-sheet-in .36s var(--ease) both; }
    @keyframes fb-sheet-in { from { transform: translateY(100%); } }
    .fb-panel.closing { transform: translateY(100%); opacity: 1; }
  }
}

/* per-page limit state uvnitř panelu (1 feedback / 24 h / stránka) — poctivá hláška místo formuláře */
.fb-limited { padding: 12px 4px 4px; }
.fb-limited p { font-size: 14px; line-height: 1.5; color: var(--text-2); }

/* ── PWA install tip card (#874) — inline dismissible TIP, NOT a notice-slot banner ── */
.pwa-card {
  position: relative; margin-top: 18px; padding: 18px 46px 18px 20px;
  background: var(--bg-elevated); border: 1px solid var(--hairline); border-radius: var(--r-xl);
}
.pwa-head { display: flex; align-items: center; gap: 10px; }
.pwa-head h3 { font-size: 16px; font-weight: 650; letter-spacing: -.2px; }
.pwa-ico { font-size: 20px; line-height: 1; }
.pwa-card .pwa-body { margin-top: 6px; font-size: 14px; line-height: 1.5; color: var(--text-2); }
.pwa-cta { margin-top: 12px; }
.pwa-how { margin-top: 10px; font-size: 13.5px; line-height: 1.55; color: var(--text-2); }
.pwa-close {
  position: absolute; top: 10px; right: 10px;
  width: 34px; height: 34px; display: grid; place-items: center;
  font-size: 14px; color: var(--text-3);
  background: none; border: none; border-radius: 50%; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.pwa-close:hover { background: var(--surface); color: var(--text); opacity: 1; }

/* admin „Zpětná vazba" panel (§37 z DS feedback-admin.html) — KPI řada s konverzí, mood split bary,
   mini trend + dashed řídký stav (trend od 7 dní dat), kampaňová sekce */
.fb-stats { display: flex; flex-direction: column; gap: 10px; }
.fb-stat-row { display: flex; align-items: center; gap: 10px; }
.fb-stat-emoji { font-size: 18px; flex: none; width: 24px; text-align: center; }
.fb-stat-bar { flex: 1; height: 10px; border-radius: 5px; background: var(--surface); overflow: hidden; }
.fb-stat-fill { display: block; height: 100%; border-radius: 5px; }
.fb-stat-num { flex: none; min-width: 74px; text-align: right; font-size: 13px; color: var(--text-2); }
.fb-trend { height: 72px; }
.fba-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 14px; margin-top: 16px; }
.fba-kpi { background: var(--surface); border-radius: var(--r-lg); padding: 13px 16px; }
.fba-kpi .k { font-size: 11.5px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase; color: var(--text-3); }
.fba-kpi .v { font-size: 22px; font-weight: 700; letter-spacing: -.5px; margin-top: 3px; }
.fba-kpi .v small { font-size: 13px; font-weight: 500; color: var(--text-3); letter-spacing: 0; }
.fba-empty {
  height: 72px; display: grid; place-items: center;
  border: 1.5px dashed var(--hairline); border-radius: var(--r-lg);
  font-size: 13px; color: var(--text-3); text-align: center; padding: 0 18px;
}
.fba-sec { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--hairline); }

/* ── +/- stepper (progressive enhancement of party number inputs) ─────────────────────────────────────
   app.client.txt wraps the native <input type=number data-stepper> in .stepper, shows the value in a
   .val span and hides the native control (kept for the submitted value + SR). NO-JS → plain input. */
.stepper { display: inline-flex; align-items: center; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg-elevated); overflow: hidden; max-width: 100%; cursor: default; }
.stepper:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } /* the wrapper is the spinbutton */
.stepper button { border: 0; background: transparent; color: var(--accent); font-size: 19px; font-weight: 600; width: 44px; height: 44px; cursor: pointer; line-height: 1; display: flex; align-items: center; justify-content: center; transition: background var(--dur-fast) var(--ease); } /* 44px = touch target */
.stepper button:hover:not(:disabled) { background: var(--accent-soft); }
.stepper button:disabled { color: var(--text-4); opacity: .4; cursor: not-allowed; }
.stepper .val { min-width: 40px; text-align: center; font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; padding: 0 6px; color: var(--text); }
.stepper.wide .val { min-width: 120px; }
/* native input kept for POST + no-JS fallback, visually removed once enhanced (sr-only) */
.input.stepper-native { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
/* the "add a second profile" cap note reveals only when the party hits the ceiling */
.stepper-capmsg[hidden] { display: none; }

/* ── collapsible destination catalog (edit folds it behind a chip preview; onboard stays open) ────── */
details.dest-collapse { border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; background: var(--bg-elevated); margin-top: 12px; }
details.dest-collapse > summary { list-style: none; cursor: pointer; padding: 13px 15px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
details.dest-collapse > summary::-webkit-details-marker { display: none; }
details.dest-collapse > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.dc-sum .dc-title { font-size: 14px; font-weight: 600; color: var(--text); }
.dc-sum .dc-chips { display: inline-flex; gap: 6px; flex-wrap: wrap; flex: 1; min-width: 0; }
.dc-chip { font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 999px; background: var(--accent-soft); color: var(--accent); white-space: nowrap; }
.dc-chip.dc-more { background: transparent; border: 1px solid var(--border); color: var(--text-2); }
.dc-empty { font-size: 12.5px; color: var(--text-3); font-style: italic; }
/* "Upravit ›" affordance — signals the folded catalog is clickable (persona Franta: chips alone read as
   read-only badges). Pushed right; carries the chevron. */
.dc-edit { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; color: var(--accent); font-weight: 600; font-size: 12.5px; white-space: nowrap; }
.dc-chev { color: var(--accent); transition: transform var(--dur-fast) var(--ease); font-size: 18px; line-height: 1; }
details.dest-collapse[open] > summary .dc-chev { transform: rotate(90deg); }
/* when expanded the real checkboxes + the live "Co hlídáme" summary are visible, so the STATIC chip
   preview (server-rendered from the saved state) would only contradict them — hide it (personas Franta +
   Klára: stale chips vs the live list). */
details.dest-collapse[open] > summary .dc-chips { display: none; }
.dc-body { padding: 2px 15px 15px; }

/* ── rail-hiding (v2): "Co hledáš" hides genuinely-irrelevant other-rail fields (server sets the initial
   state, app.client.txt setMode toggles live). */
.rail-off { display: none !important; }

/* ── v2 profile-form visual polish: numbered framed groups (compact, colorful, minimal) ───────────── */
.pf-grp { border: 1px solid var(--border); border-radius: 14px; padding: 15px 16px; margin-bottom: 12px; background: var(--bg-elevated); }
.pf-grp.pf-prio { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); background: color-mix(in srgb, var(--accent) 5%, var(--bg-elevated)); }
.pf-grp-h { display: flex; align-items: center; gap: 9px; font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; font-weight: 700; color: var(--text-2); margin-bottom: 13px; }
.pf-grp-h .pf-num { display: inline-flex; align-items: center; justify-content: center; width: 19px; height: 19px; border-radius: 50%; background: var(--accent-soft); color: var(--accent); font-size: 11px; font-weight: 700; flex: none; }
.pf-grp-h .pf-ico { font-size: 13px; line-height: 1; }
.pf-grp-h .pf-why { margin-left: auto; font-size: 11px; font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--text-3); text-align: right; max-width: 52%; }
@media (max-width: 480px) { .pf-grp-h .pf-why { display: none; } } /* Franta/Klára: on narrow screens the why fights the title for one row — drop it */
/* tighter fields inside a group (v2 compactness) */
.pf-grp .field { margin-bottom: 13px; }
.pf-grp .field:last-child { margin-bottom: 0; }
