:root {
  color-scheme: dark;
  interpolate-size: allow-keywords;
  /* Slate Dark Theme */
  --bg-core: #0a0b0d;
  --bg-surface: #12141c;
  --bg-surface-elevated: #1a1d29;
  --bg-surface-workbench: #0e1017;
  --border-workbench: #232736;

  --text-primary: #ffffff;
  --text-secondary: #acb9ca;
  --text-muted: #94a3b8;

  --accent-green: #00ff66;
  --accent-green-glow: rgba(0, 255, 102, 0.15);

  --accent-flight: #00e5ff;
  --accent-flight-glow: rgba(0, 229, 255, 0.1);

  --accent-transit: #00e5a3;
  --accent-transit-glow: rgba(0, 229, 163, 0.12);

  --accent-activity: #29b6f6;
  --accent-activity-glow: rgba(41, 182, 246, 0.12);

  /* Date / Time Picker Tokens */
  --dp-selected-bg: var(--accent-activity);
  --dp-selected-text: #0b0f19;
  --dp-in-range-bg: var(--accent-activity-glow);
  --dp-in-range-text: var(--text-primary);
  --dp-hover-bg: rgba(255, 255, 255, 0.1);
  --dp-hover-text: var(--text-primary);
  --dp-btn-hover-bg: rgba(255, 255, 255, 0.08);

  --accent-lodging: #FA60FF;
  --accent-lodging-glow: rgba(213, 0, 249, 0.1);

  --accent-car: #ffab00;
  --accent-car-glow: rgba(255, 171, 0, 0.1);

  --accent-dining: #FA7282;
  --accent-dining-glow: rgba(255, 61, 0, 0.1);

  --accent-sandbox: #00e676;

  --border-color: #3d4355;
  --border-focus: #3e4866;

  /* Layout Metrics */
  --hud-height: 85px;
  --mobile-hud-height: 125px;
  --sandbox-banner-height: 0px;
  --announcement-banner-height: 0px;
  --border-radius-lg: 16px;
  --border-radius-md: 10px;
  --border-radius-sm: 6px;

  /* Fonts */
  --font-sans: 'Space Grotesk', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  --font-mono: 'JetBrains Mono', 'Fira Code', monospace;

  --transition-smooth: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
  --shadow-premium: 0 12px 30px rgba(0, 0, 0, 0.4), 0 2px 8px rgba(0, 0, 0, 0.2);

  /* Card surfaces.
     Dark themes lift a card by making it lighter than its ground, so
     --bg-surface-elevated does the job directly. Every light theme defines
     --bg-surface-elevated *darker* than --bg-surface, which inverts the
     relationship and makes cards sink into the panel. These tokens name the
     roles instead, so a light theme can override them without touching the
     surface ramp the rest of the app depends on. */
  --card-ground: transparent;
  --card-bg: var(--bg-surface-elevated);
  --card-border: var(--border-color);
  --card-shadow: none;
  --card-inset: rgba(255, 255, 255, 0.06);
  --card-divider: var(--border-color);
  --drawer-header-bg: rgba(0, 0, 0, 0.2);
  --danger: #ff5252;
}

/* [hidden] must beat the display rules on component classes, otherwise a
   `display: flex` class silently re-shows a hidden element. */
[hidden] {
  display: none !important;
}

/* Base resets & styles */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  -webkit-font-smoothing: antialiased;
}

/* Fluid root framework by default to handle mobile document flow scales */
html,
body {
  width: 100%;
  height: 100%;
  max-width: 100%;
  overflow-x: hidden !important;
  background-color: var(--bg-core);
  color: var(--text-primary);
  font-family: var(--font-sans);
}

/* Ambient glow backdrops */
.ambient-glow {
  position: fixed;
  width: 400px;
  height: 400px;
  border-radius: 50%;
  filter: blur(150px);
  z-index: -1;
  pointer-events: none;
  opacity: 0.25;
}

.glow-1 {
  background: var(--accent-flight);
  top: -100px;
  left: 20%;
}

.glow-2 {
  background: var(--accent-lodging);
  bottom: -50px;
  right: 10%;
}

.glow-3 {
  background: var(--accent-green);
  top: 40%;
  left: 45%;
  width: 300px;
  height: 300px;
  opacity: 0.1;
}

.version-tag {
  font-family: var(--font-mono);
  font-size: 9px;
  background: rgba(255, 255, 255, 0.08);
  padding: 2px 6px;
  border-radius: 4px;
  color: var(--text-secondary);
  margin-left: 8px;
  vertical-align: middle;
}

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: var(--border-radius-sm);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: var(--transition-smooth);
  border: none;
}

/* Theme-agnostic disabled state — .btn-primary's actual color comes from
   each theme file (see css/themes/*.css), several of which don't define a
   disabled variant, so this dims uniformly regardless of theme. */
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  filter: grayscale(0.3);
}

.btn-secondary {
  background: var(--bg-surface-elevated);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
}

.btn-secondary:hover {
  background: var(--bg-surface-elevated);
  filter: brightness(1.12);
  border-color: var(--border-focus);
}

.btn-icon svg {
  stroke-width: 2.5;
}

/* Toast Notification */
/* Share Modal Window Layout */
.modal {
  display: flex;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(10, 11, 13, 0);
  -webkit-backdrop-filter: blur(0px);
  backdrop-filter: blur(0px);
  z-index: 2000;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.22s ease, background 0.22s ease, backdrop-filter 0.22s ease, visibility 0s linear 0.22s;
}

.modal.active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  background: rgba(10, 11, 13, 0.85);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition: opacity 0.22s ease, background 0.22s ease, backdrop-filter 0.22s ease, visibility 0s linear 0s;
}

.modal-content {
  background: var(--bg-surface);
  border: 1px stroke rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  padding: 24px;
  max-width: 480px;
  width: 90%;
  text-align: center;
  position: relative;
  transform: scale(0.94) translateY(8px);
  opacity: 0;
  transition: transform 0.24s cubic-bezier(0.2, 0.9, 0.3, 1.1), opacity 0.2s ease;
}

.modal.active .modal-content {
  transform: scale(1) translateY(0);
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {

  .modal,
  .modal-content {
    transition: none;
  }
}



.share-modal .help-content {
  text-align: left;
}

.share-options-grid {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 20px 0;
}

.share-opt-btn {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px;
  text-align: left;
  border-radius: 8px;
  cursor: pointer;
}

.share-opt-btn .icon {
  display: inline-flex;
  flex-shrink: 0;
}

.btn-lbl-stack {
  display: flex;
  flex-direction: column;
}

.share-options-grid button {
  background: var(--bg-surface-elevated);
}

.btn-lbl-stack strong {
  color: var(--text-primary);
  font-size: 14px;
}

.btn-lbl-stack span {
  color: var(--text-secondary);
  font-size: 11px;
  margin-top: 2px;
}

.close-modal-btn {
  margin-top: 8px;
  background: var(--text-muted);
  color: var(--text-primary);
}

/* Danger zone positioning inside the layout framework */
.modal-danger-zone {
  margin-top: 16px;
  border-top: 1px dashed rgba(255, 255, 255, 0.08);
  padding-top: 16px;
}

.btn-text-danger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: none;
  color: var(--text-secondary);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  padding: 6px 12px;
  border-radius: 6px;
  transition: background 0.2s, color 0.2s;
}

.btn-text-danger:hover {
  color: #ff4d4d;
  background: rgba(255, 77, 77, 0.1);
}

.btn-text-danger:disabled {
  color: #8a92a6;
  cursor: not-allowed;
  background: transparent;
}

/* Sync Button Spinning Animation */
@keyframes spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

.btn-sync-flight.spinning svg {
  animation: spin 1s linear infinite;
}

body:not([data-travel-mode="true"]) .btn-sync-flight {
  display: none !important;
}

/* Interactive Deck Map */
.deck-map {
  height: 35vh;
  min-height: 250px;
  width: 100%;
  border-bottom: 1px solid var(--border-color);
  background: var(--bg-surface-elevated);
  position: relative;
  flex-shrink: 0;
  transition: var(--transition-smooth);
}

/* Map Loading Skeleton */
.map-skeleton {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--bg-surface, rgba(15, 23, 42, 0.85));
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  z-index: 10;
  pointer-events: none;
  animation: skeleton-pulse 1.5s infinite ease-in-out;
}

.map-state-icon {
  width: 44px;
  height: 44px;
  color: var(--text-secondary, rgba(255, 255, 255, 0.35));
}

/* Last-resort manual reload, shown only after MAP_INIT_MAX_RETRIES silent
   auto-retries have all failed (see map.js) */
.map-error-state {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--bg-surface, rgba(15, 23, 42, 0.85));
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  z-index: 10;
  padding: 24px;
  text-align: center;
}

.map-error-message {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-secondary, #94a3b8);
}

.deck-map.hidden {
  display: none !important;
  height: 0 !important;
  min-height: 0 !important;
  border-bottom: none !important;
  overflow: hidden !important;
}

/* Theme picker dropdown styling */
.theme-picker-container {
  display: flex;
  align-items: center;
  margin-right: 8px;
}

.theme-select {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius-sm);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  padding: 6px 28px 6px 10px;
  cursor: pointer;
  outline: none;
  transition: var(--transition-smooth);
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}

.theme-journal .theme-select,
.theme-terminal .theme-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  color: var(--text-primary);
  border-color: var(--border-color);
  background-color: rgba(0, 0, 0, 0.05);
}

.theme-select:hover {
  background-color: rgba(255, 255, 255, 0.12);
  border-color: var(--border-focus);
}

.theme-journal .theme-select:hover,
.theme-terminal .theme-select:hover {
  background-color: rgba(0, 0, 0, 0.08);
}


/* ==========================================================================
   2. DESKTOP APPLICATION SHELL ENGINES (Min-Width 769px)
   ========================================================================== */
@media (min-width: 769px) {

  html,
  body {
    height: 100%;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
    position: relative;
    display: flex;
    flex-direction: column;
  }

  /* If the app is view-only, stretch the main itinerary deck to take up the full view */
  /* Stretch the app layout to full width in view-only desktop mode */
  body.view-only #app-layout {
    display: block;
    max-width: 100%;
    margin: 0;
    padding: 0;
    flex: 1 1 0%;
    min-height: 0;
    height: 100%;
  }

  /* Split the layout into map left and scrollable timeline right */
  body.view-only #panel-deck {
    display: grid !important;
    grid-template-columns: 1fr 1.25fr;
    height: 100%;
    width: 100%;
  }

  /* Break the original row metrics and force the map canvas to occupy full height */
  body.view-only #deck-map-desktop {
    height: 100% !important;
    min-height: 100% !important;
    flex-shrink: 0;
    border-bottom: none;
    border-right: 1px solid var(--border-color);
  }

  .app-layout {
    display: grid;
    grid-template-columns: 1fr 1.25fr;
    flex: 1 1 0%;
    min-height: 0;
    height: 100%;
    overflow: hidden;
    position: relative;
  }

  body:not(.view-only) #app-layout {
    display: grid !important;
    grid-template-columns: 1fr 1.25fr auto;
  }

  #editor-workspace-wrapper {
    display: flex;
    flex: 1;
    min-width: 300px;
    height: 100%;
    overflow: hidden;
  }

  .panel {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
    position: relative;
    min-height: 0;
    background: var(--bg-core);
  }

  .deck-scroll-wrapper {
    overflow-y: auto;
    height: 100%;
  }

  .deck-map-panel {
    display: none !important;
  }

  .panel-packing {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 25;
  }

  #mobile-itinerary-root {
    display: none;
  }

  body .mobile-nav,
  body.view-only .mobile-nav {
    display: none !important;
  }
}


/* ==========================================================================
   3. MOBILE-FIRST COMPONENT DRIVERS (Max-Width 768px)
   ========================================================================= */
@media (max-width: 768px) {

  html {
    height: auto;
    overflow-x: hidden !important;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Target both standard and animated state bodies to enforce the horizontal lock */
  body,
  body.no-entry-animations,
  body.view-only {
    height: auto !important;
    min-height: 100dvh !important;
    overflow-y: visible !important;
    overflow-x: hidden !important;
  }

  /* Clamp the layout wrappers horizontally to stop layout component drift */
  .panel-deck,
  .timeline-container,
  .deck-scroll-wrapper {
    width: 100% !important;
    max-width: 100vw !important;
    overflow-x: visible !important;
    box-sizing: border-box;
  }

  /* Force internal elements to never expand past layout bounds */
  .day-group,
  .day-timeline,
  .card-deck-item,
  .card {
    width: 100% !important;
    max-width: 100% !important;
    box-sizing: border-box;
  }

  .card .expanded {
    cursor: default !important;
  }

  /* Force the day headers to register sticky positioning against the html root */
  .day-header {
    position: -webkit-sticky !important;
    position: sticky !important;
    top: calc(var(--mobile-hud-height, 125px) + var(--sandbox-banner-height, 0px) + var(--announcement-banner-height, 0px) + 12px) !important;
    z-index: 1200 !important;
    background-color: var(--bg-core) !important;
    width: 100% !important;
    box-sizing: border-box;
    /* Adds a protective top buffer so text content never clips behind the notch/status bar */
    padding-top: 12px !important;
    padding-bottom: 8px !important;
    cursor: pointer !important;
    touch-action: manipulation !important;
    -webkit-tap-highlight-color: transparent !important;
    user-select: none !important;
    -webkit-user-select: none !important;
  }

  /* Compact mode: HUD collapses to a single-row strip, day-header adjusts */
  body.hud-scrolled .day-header {
    top: calc(var(--mobile-hud-compact, 48px) + var(--sandbox-banner-height, 0px) + var(--announcement-banner-height, 0px) + 8px) !important;
  }

  /* Unravel panels and grids into standard block-layout document streams */
  body #app-layout.app-layout,
  body.view-only #app-layout {
    display: block;
    height: auto;
    min-height: 0;
    max-height: none;
    margin-top: 0;
    width: 100% !important;
    max-width: 100vw !important;
    overflow-x: visible !important;
    box-sizing: border-box;
  }

  /* HUD frame clamping setup to block un-wrapped strings from expanding the viewport */
  body #hud.live-hud {
    position: fixed;
    /* Sits below the fixed sandbox banner when it's showing (see app.js
       syncSandboxBannerHeight, which measures it into this var) so the two
       never overlap. */
    top: var(--sandbox-banner-height, 0px);
    left: 0;
    width: 100vw !important;
    max-width: 100vw !important;
    height: var(--mobile-hud-height);
    padding-top: max(12px, env(safe-area-inset-top, 0px));
    padding-bottom: 12px;
    padding-left: 16px;
    padding-right: 16px;
    z-index: 1300;
    background-color: var(--bg-core);
    border-bottom: 1px solid var(--border-color);
    box-sizing: border-box;
    display: flex;
    align-items: center;
    overflow: hidden !important;
    transition: height 0.28s cubic-bezier(0.16, 1, 0.3, 1),
      padding 0.28s cubic-bezier(0.16, 1, 0.3, 1),
      top 0.2s ease;
  }

  /* Wrap text lines inside split-flap metrics if string scales long */
  #hud-countdown-text,
  #hud-countdown-timer,
  .hud-section.milestone {
    max-width: 100% !important;
    overflow-x: hidden !important;
    flex-wrap: wrap !important;
  }

  /* Compact scrolled: collapse HUD height (CSS transition handles the rest) */
  body.hud-scrolled #hud.live-hud {
    height: var(--mobile-hud-compact, 48px);
    padding-top: max(8px, env(safe-area-inset-top, 0px));
    padding-bottom: 8px;
  }

  body #hud.live-hud #hud-progress-container {
    display: none !important;
  }

  /* Offset the page content so it starts below the fixed HUD (and the
     fixed sandbox banner above it, when showing) */
  body #app-layout.app-layout {
    padding-top: calc(var(--mobile-hud-height) + var(--sandbox-banner-height, 0px) + var(--announcement-banner-height, 0px));
    transition: padding-top 0.28s cubic-bezier(0.16, 1, 0.3, 1);
  }

  /* Compact scrolled: shrink the reserved offset to match the collapsed
     HUD. Without this, panels that scroll with the window just scroll this
     reserve out of view (so the mismatch is invisible once scrolled down),
     but landing back at the top with the HUD already compact — e.g. after
     switching tabs while scrolled, which now preserves that state instead
     of always re-expanding — exposes it as a dead gray gap above the
     content. */
  body.hud-scrolled #app-layout.app-layout {
    padding-top: calc(var(--mobile-hud-compact, 48px) + var(--sandbox-banner-height, 0px) + var(--announcement-banner-height, 0px));
  }

  /* Display active panels blocks inline inside the global document flow */
  body .panel {
    display: none !important;
    width: 100% !important;
    max-width: 100% !important;
    position: relative;
    background-color: var(--bg-core);
    box-sizing: border-box;
  }

  body .panel.active {
    display: block !important;
  }

  body .panel-edit.active {
    display: flex !important;
    flex-direction: column !important;
    min-height: calc(100dvh - var(--mobile-hud-height, 125px) - var(--sandbox-banner-height, 0px) - var(--announcement-banner-height, 0px) - var(--mobile-nav-height, 60px) - env(safe-area-inset-bottom, 0px));
  }

  body.hud-scrolled .panel-edit.active {
    min-height: calc(100dvh - var(--mobile-hud-compact, 48px) - var(--sandbox-banner-height, 0px) - var(--announcement-banner-height, 0px) - var(--mobile-nav-height, 60px) - env(safe-area-inset-bottom, 0px));
  }

  /* Kill internal tracking container bounds to flatten layout columns */
  body #editor-workspace-wrapper,
  body .panel-deck,
  body .deck-scroll-wrapper {
    height: auto;
    max-height: none;
    overflow-y: visible;
    overflow-x: visible !important;
    -webkit-overflow-scrolling: auto;
  }

  /* Pad out the timeline bottom natively while matching the strict top padding reset */
  body .deck-scroll-wrapper {
    padding: 0px 12px calc(80px + env(safe-area-inset-bottom, 0px)) 12px !important;
    overflow: visible !important;
    box-sizing: border-box;
  }

  /* Fixed interactive bottom nav tab setup — always visible */
  body .mobile-nav

  /* body.view-only .mobile-nav  */
    {
    display: flex !important;
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100vw !important;
    max-width: 100vw !important;
    z-index: 1400;
    background-color: var(--bg-surface);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    height: calc(60px + env(safe-area-inset-bottom, 0px));
    box-sizing: border-box;
    overflow: hidden !important;
    transition: height 0.28s cubic-bezier(0.16, 1, 0.3, 1);
  }

  body .mobile-nav .nav-item {
    flex: 1;
    height: 60px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-family: var(--font-sans);
    font-size: 11px;
    font-weight: 500;
    gap: 4px;
    box-sizing: border-box;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: height 0.28s cubic-bezier(0.16, 1, 0.3, 1);
  }

  body .mobile-nav .nav-item.active {
    color: var(--accent-green);
  }

  body .mobile-nav .nav-item svg {
    stroke: var(--text-muted);
  }

  body .mobile-nav .nav-item.active svg {
    stroke: var(--accent-green);
  }

  body .mobile-nav .nav-item>span,
  body .mobile-nav .nav-item .alt-hint-badge {
    transition: opacity 0.18s ease, max-height 0.18s ease;
    max-height: 20px;
    opacity: 1;
    overflow: hidden;
  }

  /* Compact bottom nav: icons only, no labels, on scroll (mirrors body.hud-scrolled) */
  body.hud-scrolled .mobile-nav {
    height: calc(44px + env(safe-area-inset-bottom, 0px));
  }

  body.hud-scrolled .mobile-nav {
    padding-bottom: 45px !important;
  }

  body.hud-scrolled .mobile-nav .nav-item {
    height: 44px;
    gap: 0;
  }

  body.hud-scrolled .mobile-nav .nav-item>span,
  body.hud-scrolled .mobile-nav .nav-item .alt-hint-badge {
    max-height: 0;
    opacity: 0;
    pointer-events: none;
  }

  /* Fullscreen Map Panel mobile positioning bounds */
  body #panel-map {
    display: none;
    position: fixed;
    top: calc(var(--mobile-hud-compact, 48px) + var(--sandbox-banner-height, 0px));
    left: 0;
    width: 100%;
    height: calc(100dvh - var(--mobile-hud-compact, 48px) - var(--sandbox-banner-height, 0px) - var(--mobile-nav-height, 60px) - env(safe-area-inset-bottom, 0px));
    z-index: 900;
    overflow: hidden;
  }

  body #panel-map.active {
    display: block;
  }

  #deck-map-desktop,
  .desktop-only {
    display: none !important;
    height: 0 !important;
  }

  body #panel-map #deck-map {
    height: 100%;
    width: 100%;
  }

  /* Let metrics inside inline weather widgets scroll gracefully if wide */
  .weather-forecast-container,
  .forecast-row {
    max-width: 100%;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  /* Completely remove tracking footprints for glow graphics */
  .ambient-glow,
  .glow-1,
  .glow-2,
  .glow-3 {
    display: none !important;
    opacity: 0 !important;
    visibility: hidden !important;
    width: 0 !important;
    height: 0 !important;
    pointer-events: none !important;
  }
}

/* ==========================================================================
   4. PRODUCTION IOS HOME SCREEN STANDALONE APP SHEET REFINEMENTS
   ========================================================================== */
@media (max-width: 768px) and (display-mode: standalone) {
  :root {
    /* Seamless scaling: Base height calculations + active system metrics */
    --mobile-hud-height: calc(125px + env(safe-area-inset-top, 24px));
    --mobile-hud-compact: calc(48px + env(safe-area-inset-top, 24px));
  }

  /* When the sandbox banner is showing, it sits above the HUD and reserves
     the notch/Dynamic Island space itself (see .sandbox-banner in hud.css) —
     so the HUD is no longer the topmost element and shouldn't reserve that
     space a second time. Drop back to the un-padded base heights/paddings. */
  body.has-sandbox-banner {
    --mobile-hud-height: 125px;
    --mobile-hud-compact: 48px;
  }

  body #app-layout.app-layout {
    padding-top: calc(var(--mobile-hud-height) + var(--sandbox-banner-height, 0px) + var(--announcement-banner-height, 0px)) !important;
  }

  /* Full-Height State Initialization */
  body #hud.live-hud {
    padding-top: env(safe-area-inset-top, 24px) !important;
    height: var(--mobile-hud-height) !important;
    padding-bottom: 12px !important;
    /* Locks structural bottom padding safely */
  }

  body.has-sandbox-banner #hud.live-hud {
    padding-top: 12px !important;
  }

  .day-header {
    top: calc(var(--mobile-hud-height) + var(--sandbox-banner-height, 0px) + var(--announcement-banner-height, 0px)) !important;
  }

  /* 🛠️ Compact Scrolled State: Relieve inner padding to let text surface */
  body.hud-scrolled #hud.live-hud {
    height: var(--mobile-hud-compact) !important;
    min-height: 0 !important;
    padding-top: env(safe-area-inset-top, 24px) !important;
    padding-bottom: 0 !important;
    /* Reset vertical alignment and flex flow to allow inner content to center cleanly */
    align-items: stretch !important;
  }

  body.has-sandbox-banner.hud-scrolled #hud.live-hud {
    padding-top: 0 !important;
  }

  body.hud-scrolled .day-header {
    top: calc(var(--mobile-hud-compact) + var(--sandbox-banner-height, 0px) + var(--announcement-banner-height, 0px) + 8px) !important;
  }

  body.hud-scrolled #app-layout.app-layout {
    padding-top: calc(var(--mobile-hud-compact) + var(--sandbox-banner-height, 0px) + var(--announcement-banner-height, 0px)) !important;
  }

  /* 🛠️ Remove the layout blowup cushion breaking full-size heights */
  .hud-section.milestone {
    margin-bottom: 0 !important;
  }

  body .deck-scroll-wrapper {
    padding: 10px 12px calc(80px + env(safe-area-inset-bottom, 0px)) 12px !important;
  }
}

a.mapboxgl-ctrl-logo {
  margin: 0 0 -0.5rem 0.5rem !important;
  scale: 0.8;
}

.mapboxgl-ctrl-recenter,
.mapboxgl-ctrl-traffic {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: #333;
  transition: color 0.15s ease, background-color 0.15s ease;
}

.mapboxgl-ctrl-recenter:hover,
.mapboxgl-ctrl-traffic:hover {
  color: #000;
}

.mapboxgl-ctrl-traffic.active {
  color: var(--accent, #00f2fe) !important;
  background-color: rgba(0, 242, 254, 0.12) !important;
}

/* ── Custom iOS-Style Navigation Arrow for Mapbox Geolocate Control ── */
.mapboxgl-ctrl-geolocate .mapboxgl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23333333'%3E%3Cpath d='M3 11l19-9-9 19-2-8-8-2z'/%3E%3C/svg%3E") !important;
  background-size: 16px 16px !important;
}

.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-active .mapboxgl-ctrl-icon,
.mapboxgl-ctrl-geolocate.mapboxgl-ctrl-geolocate-background .mapboxgl-ctrl-icon {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23007AFF'%3E%3Cpath d='M3 11l19-9-9 19-2-8-8-2z'/%3E%3C/svg%3E") !important;
  background-size: 16px 16px !important;
}

/* ── Mapbox Custom Markers ───────────────────────────────────────────────── */
.custom-map-marker {
  --marker-size: 14px;
  --marker-size-hover: 19px;
  width: var(--marker-size);
  height: var(--marker-size);
  border-radius: 50%;
  background-color: var(--marker-color, #fff);
  border: 2.5px solid var(--bg-core, #0a0b0d);
  box-shadow: 0 0 8px var(--marker-color, #fff);
  cursor: pointer;
  /* Mapbox positions each marker with an inline transform and its own
     .mapboxgl-marker { position: absolute } rule. This file loads after
     mapbox-gl.css, so a `position: relative` here silently wins and drops
     markers back into normal flow — they then pan correctly but drift out
     of place as the map zooms. Keep it absolute. */
  position: absolute;
  /* Do NOT transition 'transform' globally, as it delays Mapbox translation math */
  transition: width 0.15s ease, height 0.15s ease, box-shadow 0.15s ease;
}

/* Expanded invisible touch hit area for mobile/touch usability (min 36x36px target) */
.custom-map-marker::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 36px;
  height: 36px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
}

.custom-map-marker:hover {
  /* Grow via width/height, not `transform: scale()`: the transform belongs to
     Mapbox, which writes it inline (and so wins over anything here). The
     inline value ends in translate(-50%, -50%), a percentage of the marker's
     own box, so it re-centers on its coordinate as the size changes. */
  --marker-size: var(--marker-size-hover);
  box-shadow: 0 0 14px var(--marker-color, #fff);
}

/* Search pin — temporary, visually distinct from itinerary markers */
.custom-map-marker.search-pin {
  --marker-size: 18px;
  --marker-size-hover: 24px;
  border-width: 3px;
  animation: pin-pulse 1.8s ease-in-out infinite;
}

@keyframes pin-pulse {

  0%,
  100% {
    box-shadow: 0 0 6px var(--marker-color, #fff);
  }

  50% {
    box-shadow: 0 0 20px var(--marker-color, #fff);
  }
}

/* ── Mapbox Popup Custom Styles ─────────────────────────────────────────── */
.mapboxgl-popup {
  z-index: 20;
}

.mapboxgl-popup-content {
  background: var(--bg-surface-elevated);
  border: 1px solid var(--border-color);
  border-radius: var(--border-radius-md);
  box-shadow: var(--shadow-premium);
  padding: 0;
}

.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip {
  border-top-color: var(--bg-surface-elevated);
}

.mapboxgl-popup-anchor-top .mapboxgl-popup-tip {
  border-bottom-color: var(--bg-surface-elevated);
}

.mapboxgl-popup-anchor-left .mapboxgl-popup-tip {
  border-right-color: var(--bg-surface-elevated);
}

.mapboxgl-popup-anchor-right .mapboxgl-popup-tip {
  border-left-color: var(--bg-surface-elevated);
}

/* Enlarged to a real 44x44 touch target — the native Mapbox close button is
   too small to reliably tap on mobile. */
.mapboxgl-popup-close-button {
  width: 44px;
  height: 44px;
  font-size: 20px;
  line-height: 44px;
  top: 0;
  right: 0;
  color: var(--text-secondary);
  border-radius: 0 var(--border-radius-md) 0 var(--border-radius-md);
  transition: background 0.15s ease, color 0.15s ease;
}

.mapboxgl-popup-close-button:hover,
.mapboxgl-popup-close-button:focus {
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-primary);
}

.map-popup-card {
  color: var(--text-primary);
  font-family: var(--font-sans);
  padding: 14px 44px 14px 14px;
  min-width: 160px;
}

.map-popup-title {
  font-size: 15px;
  font-weight: 700;
  line-height: 1.35;
  display: flex;
  align-items: center;
  gap: 8px;
}

.map-popup-emoji {
  font-size: 17px;
  line-height: 1;
}

/* Reuses .btn-dashboard-new (dashboard.css) for its themed bg/text colors —
   same button style as "+ New Trip" — and only overrides layout here. */
.map-popup-directions-btn.btn-dashboard-new {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: 10px;
  min-height: 40px;
  text-decoration: none;
  outline: none !important;
  box-shadow: none !important;
  -webkit-tap-highlight-color: transparent;
}

.map-popup-directions-btn.btn-dashboard-new:focus,
.map-popup-directions-btn.btn-dashboard-new:focus-visible {
  outline: none !important;
  box-shadow: none !important;
}

body.view-only .hide-view-only,
body.view-only .btn-day-empty-add,
body.view-only .btn-empty-cta,
body.view-only .add-event-btn,
body.view-only .btn-outline-add-event,
body.view-only .btn-outline-add-day,
body.view-only .btn-add-gap-days,
body.view-only .btn-quick-add-day,
body.view-only .btn-outline-action.edit,
body.view-only .btn-outline-action.delete,
body.view-only .outline-item-handle,
body.view-only #btn-shift-trip-dates,
body.view-only #btn-packing-toggle-all,
body.view-only #btn-packing-clear-completed,
body.view-only #btn-suggest-packing,
body.view-only #btn-show-add-packing,
body.view-only .btn-delete-packing,
body.view-only .btn-sync-flight,
body.view-only .btn-add-itinerary {
  display: none !important;
}

body.view-only .packing-checkbox,
body.view-only .packing-item {
  pointer-events: none;
}

/* Packing and Budget are excluded from view-only shares entirely (the
   markdown itself is stripped before encryption — see stripIdeaItems and
   stripPrivateFields) — also force their panels closed so a viewer can't
   land on an empty panel via a stale open state. */
body.view-only #panel-packing,
body.view-only #panel-budget {
  display: none !important;
}

/* 🛠️ Recovery Warning Banner on Dashboard */
.recovery-warning-banner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  background-color: var(--bg-secondary, rgba(255, 255, 255, 0.03));
  border: 1px dashed var(--border-color, rgba(255, 255, 255, 0.15));
  border-radius: var(--border-radius-md, 10px);
  padding: 12px 18px;
  margin-bottom: 20px;
  box-sizing: border-box;
}

.recovery-warning-banner.hidden {
  display: none !important;
}

.recovery-warning-banner-content {
  display: flex;
  align-items: center;
  gap: 10px;
}

.recovery-warning-banner-content .warning-icon {
  font-size: 16px;
  flex-shrink: 0;
  opacity: 0.8;
}

.recovery-warning-banner-content .banner-text {
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.4;
}

.btn-banner-generate-key {
  background: transparent;
  color: var(--text-primary);
  border: 1px solid var(--border-color, rgba(255, 255, 255, 0.2));
  border-radius: var(--border-radius-sm, 6px);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  padding: 8px 14px;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.btn-banner-generate-key:hover {
  background-color: rgba(255, 255, 255, 0.08);
  border-color: var(--text-secondary);
  transform: translateY(-1px);
}

.drawer-recovery-warning {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background-color: var(--bg-secondary, rgba(255, 255, 255, 0.02));
  border: 1px solid var(--border-color, rgba(255, 255, 255, 0.1));
  border-radius: var(--border-radius-sm, 6px);
  padding: 10px 12px;
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.4;
  margin-top: 4px;
  margin-bottom: 4px;
  box-sizing: border-box;
}

.drawer-recovery-warning.hidden {
  display: none !important;
}

.drawer-recovery-warning-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.drawer-recovery-warning .warning-icon {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--text-muted);
}

.drawer-recovery-warning .warning-icon svg {
  flex: none;
  width: 15px;
  height: 15px;
}

.drawer-recovery-warning .btn-banner-generate-key {
  width: 100%;
}

@media (max-width: 768px) {
  .recovery-warning-banner {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .btn-banner-generate-key {
    width: 100%;
    text-align: center;
  }

  /* Redundant with the bottom-nav Packing tab, and toggles a `.collapsed`
     state the mobile packing panel CSS doesn't read — hide rather than
     leave a dead control in the editor toolbar. */
  #btn-toggle-packing {
    display: none;
  }

  /* ── Mobile Bottom-Nav Tab Slide Animations ─────────────────────────────── */
  @keyframes slide-in-from-right {
    from {
      transform: translateX(20px);
      opacity: 0.1;
    }

    to {
      transform: translateX(0);
      opacity: 1;
    }
  }

  @keyframes slide-in-from-left {
    from {
      transform: translateX(-20px);
      opacity: 0.1;
    }

    to {
      transform: translateX(0);
      opacity: 1;
    }
  }

  @keyframes tab-fade-in {
    from {
      opacity: 0.1;
    }

    to {
      opacity: 1;
    }
  }

  body .panel.tab-enter-right {
    animation: slide-in-from-right 200ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  body .panel.tab-enter-left {
    animation: slide-in-from-left 200ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  /* Animate timeline deck contents on enter so cards and groups visibly transition */
  body #panel-deck.tab-enter-right .deck-scroll-wrapper {
    animation: slide-in-from-right 200ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  body #panel-deck.tab-enter-left .deck-scroll-wrapper {
    animation: slide-in-from-left 200ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }

  /* Packing panel contains fixed-position modal drawers (#suggestion-drawer,
     #load-list-drawer). A transform on an ancestor creates a new containing
     block that disrupts fixed positioning for those children. Use an opacity
     crossfade instead of transform-driven slide to keep drawers stable. */
  body #panel-packing.tab-enter-right,
  body #panel-packing.tab-enter-left {
    animation: tab-fade-in 200ms ease both;
  }
}

/* ==========================================================================
   PREFERS-REDUCED-MOTION — Global pass
   Covers existing animated components that previously lacked carve-outs,
   plus all new transitions added in this change.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {

  /* Kill new panel/tab transitions */
  body .panel.tab-enter-right,
  body .panel.tab-enter-left {
    animation: none !important;
  }

  /* Existing gaps: HUD height collapse, card entrance stagger, day collapse */
  #hud.live-hud {
    transition: none !important;
  }

  .day-content {
    transition: none !important;
  }

  /* Visual builder tab crossfade + outline collapse (added in this change) */
  .tab-pane,
  .tab-pane.active,
  .outline-day-items {
    transition: none !important;
    animation: none !important;
  }

  /* Card entrance stagger animations */
  .card {
    animation: none !important;
  }
}

/* iOS Safari auto-zooms into any focused text field under 16px. Force 16px
   on mobile so typing never triggers a viewport zoom, regardless of what
   per-component styles set elsewhere. */
@media (max-width: 768px) {

  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  textarea,
  select,
  [contenteditable="true"] {
    font-size: 16px !important;
  }
}

/* ==========================================================================
   Keyboard Shortcut Keycap Badges (revealed on pressing Alt/Option)
   ========================================================================== */
.alt-hint-badge {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  box-sizing: border-box;
  font-family: var(--font-mono, 'JetBrains Mono', 'Fira Code', monospace) !important;
  font-size: 10px !important;
  font-weight: 800 !important;
  line-height: 1 !important;
  text-transform: uppercase !important;
  color: #ffffff !important;
  background: #1e293b !important;
  border: 1px solid rgba(255, 255, 255, 0.4) !important;
  border-bottom: 2px solid rgba(255, 255, 255, 0.6) !important;
  border-radius: 4px !important;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5) !important;
  pointer-events: none;
  user-select: none;
  flex-shrink: 0;
  z-index: 100;
  position: absolute;
  animation: altBadgePop 0.12s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes altBadgePop {
  0% {
    opacity: 0;
    transform: translateY(-1px) scale(0.85);
  }

  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

body.show-alt-hints .alt-hint-badge,
html.show-alt-hints .alt-hint-badge {
  display: inline-flex !important;
}

/* Position anchors for keycap badge overlays */
.command-pill {
  position: relative;
}

.command-pill .alt-hint-badge {
  top: -5px;
  right: -5px;
}

.tab-btn {
  position: relative;
}

.tab-btn .alt-hint-badge {
  top: -5px;
  right: -5px;
}

.btn-icon {
  position: relative;
}

.btn-icon .alt-hint-badge {
  top: -5px;
  right: -5px;
}

.filter-icon-btn {
  position: relative;
}

.filter-icon-btn>.alt-hint-badge {
  bottom: -5px;
  right: -5px;
}

.deck-map {
  position: relative;
}

.deck-map>.map-hint-badge {
  top: 10px;
  right: 44px;
  z-index: 100;
}

.nav-item {
  position: relative;
}

.nav-item .alt-hint-badge {
  top: 4px;
  right: 12px;
  z-index: 100;
}

.drawer-nav-card {
  position: relative;
}

.drawer-nav-card .alt-hint-badge {
  top: 50%;
  right: 12px;
  transform: translateY(-50%);
}

/* Rotate-device overlay. iOS Safari has no orientation-lock API (and ignores
   the manifest's "orientation" hint even when installed as a PWA), so phones
   are blocked here in CSS instead of actually being locked to portrait.
   Scoped to short landscape heights so it never catches tablets; pointer:coarse
   is deliberately not part of the query since Safari's Responsive Design Mode
   (unlike Chrome's device emulation) doesn't fake it, which would make this
   untestable outside a real device. */
#rotate-device-overlay {
  display: none;
}

@media (orientation: landscape) and (max-height: 500px) {
  #rotate-device-overlay {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: var(--bg-core);
    padding: 24px;
    text-align: center;
  }

  /* Not display:none — collapsing the Mapbox canvas to 0x0 makes Safari
     drop its WebGL context, and nothing here ever calls map.resize() to
     recover it, so the map comes back dead after rotating back to portrait.
     The overlay is opaque and full-screen, so pointer-events is enough to
     block interaction without touching anything's layout box. */
  #rotate-device-overlay~* {
    pointer-events: none !important;
  }

  body {
    overflow: hidden;
  }

  .rotate-device-message {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    max-width: 320px;
  }

  .rotate-device-wordmark {
    font-size: 22px;
    font-weight: 900;
    color: var(--text-primary);
    margin: 0;
    letter-spacing: -0.5px;
    font-family: var(--font-sans);
  }

  .rotate-device-wordmark span {
    color: var(--accent-flight);
  }

  .rotate-device-icon {
    font-size: 40px;
    color: var(--text-primary);
    animation: rotate-device-spin 1.6s ease-in-out infinite;
  }

  .rotate-device-message p {
    color: var(--text-secondary);
    font-family: var(--font-sans);
    font-size: 15px;
    line-height: 1.5;
    margin: 0;
  }
}

@keyframes rotate-device-spin {

  0%,
  100% {
    transform: rotate(0deg);
  }

  50% {
    transform: rotate(-90deg);
  }
}