/* =============================================================================
   assets/style.css — Antarctic Air

   Structure:
     PART A — Design tokens (added U1)
     PART B — Base typography & surfaces (added U1)
     PART C — Loader keyframes (added U1, wired in U7)
     PART D — Legacy classes (from before refresh; U2+ will progressively replace)
     PART E — Responsive shell: topbar + mobile bottom-nav (added U2);
              About + intro modals redesign (added U3);
              tab-level layouts: Time Series (U4), Air Temp (U5);
              Get Data tab layout (added U6);
              Brewing coffee-cup loader (added U7 — wires PART C keyframes
              onto the SVG mounted by components/brewing_loader.py)
   ============================================================================= */


/* ============================================================
   PART A — Design tokens (added U1)
   ============================================================ */
:root {
  /* Surfaces — neutral blacks (no blue tint; picked so the neon accents
     and basemap blues can breathe without competing against a blue chrome). */
  --bg-primary: #0a0a0a;
  --bg-surface: #141414;
  --bg-elevated: #1c1c1c;
  --bg-panel: #171717;

  /* Neon accents (used sparingly — never on body text) */
  --neon-cyan: #08f7fe;
  --neon-pink: #fe53bb;
  --neon-purple: #a855f7;
  --neon-green: #09fbd3;
  --neon-amber: #ffe74c;
  --neon-orange: #ff6b35;

  /* Text */
  --text-primary: #e0e0ff;
  --text-muted: #8888aa;
  --text-bright: #ffffff;

  /* Borders + gridlines — neutral to match the surfaces */
  --border-soft: #2e2e2e;
  --grid-line: #232323;

  /* Semantic chart series */
  --chart-series-1: var(--neon-cyan);
  --chart-series-2: var(--neon-green);
  --chart-series-3: var(--neon-pink);
  --chart-series-4: var(--neon-amber);
  --chart-series-5: var(--neon-orange);
  --chart-marker-halo: rgba(8, 247, 254, 0.25);

  /* Glow shadows (two-layer blur) */
  --glow-cyan: 0 0 8px #08f7fe, 0 0 20px rgba(8, 247, 254, 0.4);
  --glow-green: 0 0 8px #09fbd3, 0 0 20px rgba(9, 251, 211, 0.4);
  --glow-pink:  0 0 8px #fe53bb, 0 0 20px rgba(254, 83, 187, 0.4);
  --glow-amber: 0 0 8px #ffe74c, 0 0 20px rgba(255, 231, 76, 0.4);

  /* Typography */
  --font-ui:    'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:  'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;

  /* Layout tokens */
  --topbar-height: 88px;
  --bottomnav-height: 56px;
  --sheet-peek: 96px;
  --sidebar-width: 440px;
  --border-radius: 6px;
  --transition: 0.18s ease;
  --touch-target: 44px;

  /* Safe-area (notched phones) */
  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left:   env(safe-area-inset-left, 0px);
  --safe-right:  env(safe-area-inset-right, 0px);
}

/* Reduced-motion opt-out — kills all non-essential motion.
   Loader keyframes in PART C respect this via their own rule too. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}


/* ============================================================
   PART B — Base typography & surfaces (added U1)
   ============================================================ */

/* Base document typography.
   NB: the legacy html/body/#root rule in PART D still sets padding/height/
   overflow to preserve current layout behaviour. This rule sets colour,
   font and background using the new tokens. Font-family + background win
   because they come later in the cascade for those specific properties. */
body {
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

html {
  background: var(--bg-primary);
}

/* Headings — use UI font at weight 600. Deliberately NOT overriding
   Bootstrap-DARKLY's .h1/.h2/etc. utility classes, which some layouts
   rely on for sizing. This only touches native heading elements. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-ui);
  font-weight: 600;
  color: var(--text-bright);
  line-height: 1.25;
  margin-top: 0;
}

/* Mono utility — for values, readouts, code and labels. */
.mono {
  font-family: var(--font-mono);
  font-feature-settings: 'zero' 1, 'ss01' 1;
}

/* Reusable surface family — cards, panels, sheets.
   Consumers add .surface for the default panel, or a modifier for a
   different tint. All variants share a 1px border-soft and radius. */
.surface,
.surface--panel,
.surface--elevated {
  background: var(--bg-panel);
  border: 1px solid var(--border-soft);
  border-radius: var(--border-radius);
  color: var(--text-primary);
}

.surface--panel {
  background: var(--bg-panel);
}

.surface--elevated {
  background: var(--bg-elevated);
}

/* Pill / chip — for filter chips, tags, mode toggles. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.25em 0.75em;
  min-height: calc(var(--touch-target) - 16px);
  background: var(--bg-elevated);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1;
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition), color var(--transition);
  user-select: none;
}

.chip:hover {
  background: var(--bg-surface);
  border-color: var(--text-muted);
  color: var(--text-bright);
}

.chip[aria-pressed="true"],
.chip.is-active {
  background: rgba(8, 247, 254, 0.08);
  border-color: var(--neon-cyan);
  color: var(--neon-cyan);
}


/* ============================================================
   PART C — Loader keyframes (added U1, wired in U7)
   ============================================================ */

/* Ported verbatim from D2 §3 (frontend/src/components/BrewingLoader.module.css:89-151).
   U7 supplies the SVG markup and mounts it via dcc.Loading(custom_spinner=...). */

@keyframes brew-fill {
  0% { transform: translateY(46px); }
  70%, 88% { transform: translateY(0); }
  100% { transform: translateY(46px); }
}

@keyframes brew-steam {
  0%, 40% { opacity: 0; translate: 0 4px; }
  60% { opacity: 0.6; }
  100% { opacity: 0; translate: 0 -6px; }
}

@keyframes brew-dots {
  0% { content: ''; }
  25% { content: '.'; }
  50% { content: '..'; }
  75% { content: '...'; }
}

/* Base cup stub — U7 will layer the SVG + caption on top.
   Positions the loader as a centred overlay over its dcc.Loading target,
   using a soft blur-scrim consistent with the D2 loader spec. */
.brew-cup {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 120px;
  padding: 24px;
  background: rgba(10, 10, 15, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  border-radius: var(--border-radius);
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  z-index: 5;
  pointer-events: none;
}

.brew-cup svg {
  width: 64px;
  height: 64px;
  filter: drop-shadow(0 0 8px rgba(8, 247, 254, 0.4));
}

/* Animated dots after the caption text — U7 renders
   <span class="brew-cup__caption">brewing data<span class="brew-cup__dots"></span></span> */
.brew-cup__dots::after {
  content: '';
  display: inline-block;
  min-width: 1.2em;
  text-align: left;
  animation: brew-dots 1.2s steps(4, end) infinite;
}

/* Reduced-motion: freeze the fill mid-cup, slow the dots. Matches D2 spec. */
@media (prefers-reduced-motion: reduce) {
  .brew-cup__fill {
    animation: none !important;
    transform: translateY(12px) !important;
  }
  .brew-cup__steam {
    animation: none !important;
    opacity: 0 !important;
  }
  .brew-cup__dots::after {
    animation-duration: 3s !important;
  }
}


/* ============================================================
   PART D — Legacy classes (from before refresh; U2+ will replace)
   ============================================================ */

/* Legacy classes preserved for U2+ progressive replacement. */

/* =============================================================================
   Global styles, tab & logo container, tab styling, card hover effects,
   title section, and overview-specific styles for Ross Sea Dashboard
   ============================================================================= */

/* ──────────────────────────────────────────────────────────────────────────────
   1. Import Fonts & Reset
   ────────────────────────────────────────────────────────────────────────────── */
@import url('https://fonts.googleapis.com/css2?family=Anton&display=swap');

html,
body,
#root {
  margin: 0;
  padding: 0 12px;
  height: 100vh;
  width: 100%;
  overflow: auto;
  background-color: #000000; /* Dark background for contrast */
}

/* ──────────────────────────────────────────────────────────────────────────────
   2. Tab + Logo Container
   ────────────────────────────────────────────────────────────────────────────── */
.tabs-container {
  position: relative;
  margin-bottom: 1rem;  /* Spacing below the tab bar */
}

.tabContainer {
  position: relative;
  margin-bottom: 1rem;
  font-size: 16px;
  padding-top: 26px;
}

.tabContainer .logo {
  position: absolute;
  top: 0;
  right: 0;
  height: 60px;
  margin: 0.25rem;
}

.logo-in-tabs {
  position: absolute;
  top: 0;
  right: 0;
  height: 60px;
  margin: 0.25rem;
}

/* ──────────────────────────────────────────────────────────────────────────────
   3. Tab Styling
   ────────────────────────────────────────────────────────────────────────────── */
.tab {
  font-size: 16px;
  padding-top: 24px;
}

.tab-content,
.tabContent {
  padding-top: 12px;
}

.nav-tabs {
  border-bottom: 1px solid rgb(90, 90, 90) !important;
  width: 100%;
}

.nav-tabs .nav-item {
  margin-right: 0.8rem;
}

.nav-tabs .nav-link {
  padding: 10px 36px;
  padding-bottom: 10px;
  font-weight: 500;
  font-size: 16px;
  border: 1px solid transparent;
  border-top-left-radius: 0.375rem;
  border-top-right-radius: 0.375rem;
  margin: 0 0.8rem 0 0;
}

.nav-tabs .nav-link.active {
  background-color: #282829;
  color: white;
  border: 1px solid rgb(90, 90, 90);
  border-bottom-color: rgb(35, 35, 36);
  margin: 0 0.8rem 0 0;
}

/* Base style for all nav links (non-tab specific) */
.tab-link {
  color: white !important;
  font-weight: 500;
  padding: 12px 510px 13px 510px;
  border-bottom: 3px solid transparent;
  transition: all 0.3s ease-in-out;
  border-radius: 5px;
}

.tab-link:hover {
  color: white !important;
  background-color: rgba(255, 255, 255, 0.05);
  text-decoration: none;
  border-color: white 1px;
}

.tab-link.active {
  background-color: rgb(40, 40, 41);
  color: white !important;
  font-weight: bold;
  border-top: 1px solid rgb(90, 90, 90);
  border-left: 1px solid rgb(90, 90, 90);
  border-right: 1px solid rgb(90, 90, 90);
  border-bottom: none;
}

/* ──────────────────────────────────────────────────────────────────────────────
   4. Card Hover Effects & Base Layout
   ────────────────────────────────────────────────────────────────────────────── */
.card-container-title {
  display: inline-block;
  position: relative;
  width: 100%;
  padding: 3px 0 18px 0;
  transform-origin: center center;
  font-family: 'Anton', sans-serif;
  font-size: clamp(2.6rem, 2.3vw, 5rem);
  font-weight: 200;
  color: rgb(244, 244, 246);
  text-shadow: 0 0 2px rgba(102, 217, 255, 0.4);
  text-align: center;
}

.card {
  background-color: rgb(40, 40, 41) !important;
  transition: transform 0.2s ease-in-out;
  font-size: 21px;
}

.card:hover {
  transform: translateY(-3px);
}

.card-header {
  font-size: 18px;
  background-color: rgb(40, 40, 41) !important;
  color: lightgray;
  margin: 0.2rem;
  text-align: center;
}

.card-body {
  font-size: 16px;
  text-align: center;
}

/* Container variations */
.card-container {
  display: grid;
  grid-template-columns: repeat(3, 360px);
  justify-content: center;
  gap: 24px;
  max-width: 100%;
  margin: 0.8rem auto;
}

@media (max-width: 1200px) {
  .card-container {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 600px) {
  .card-container {
    grid-template-columns: 1fr;
  }
}

/* Sub-card */
.sub-card-container {
  display: grid;
  justify-content: center;
  grid-template-columns: repeat(3, 230px);
  max-width: 100%;
  gap: 12px;
  margin: 0.8rem;
}
.sub-card-container .card {
  background-color: rgb(50, 50, 51) !important;
}
.sub-card-container .card:hover {
  transform: translateY(2px);
}
.sub-card-container .card-header {
  font-size: 18px;
  background-color: rgb(50, 50, 51) !important;
  margin: 0;
}
@media (max-width: 300px) {
  .sub-card-container {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 200px) {
  .sub-card-container {
    grid-template-columns: 1fr;
  }
}

/* ──────────────────────────────────────────────────────────────────────────────
   5. Title (Bottom) Section
   ────────────────────────────────────────────────────────────────────────────── */
.title {
  display: flex;
  align-items: center;
  width: 100%;
  color: lightgray;
  font-size: 20px;
  font-weight: bold;
  position: relative;
  height: auto;
}
.title-text {
  flex: 6;
  cursor: default;
  transition: transform 0.12s ease;
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
}
.title-text:hover {
  color: #fff;
}
.title-time {
  flex: 2;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  white-space: nowrap;
}
@media (max-width: 500px) {
  .title-time {
    justify-content: center;
    text-align: center;
    margin-top: 10px;
    flex: 100%;
  }
}
.title-time:hover {
  color: #fff;
}

/* Bottom title alternative */
.bottomTitle {
  display: flex;
  align-items: center;
  width: 100%;
  color: rgb(221, 226, 225);
  font-size: 1.3rem;
  font-weight: bold;
}
.bottomTitle .title {
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
}
.bottomTitle .infoArea {
  margin-left: auto;
  cursor: pointer;
  transition: transform 0.12s ease;
}
.bottomTitle .infoArea:hover { color: #fff; }
.bottomTitle .infoArea .info {
  position: relative;
  display: inline-block;
  padding-right: 1.8em;
  font-size: 1.3rem;
}
.bottomTitle .infoArea .info .infoIcon {
  position: absolute;
  top: 0.1rem;
  right: 1.2rem;
  font-size: 0.85rem;
}

/* ──────────────────────────────────────────────────────────────────────────────
   6. Overview Tab Specific Styles
   ────────────────────────────────────────────────────────────────────────────── */
.overview_title {
  display: inline-block;
  position: relative;
  width: 100%;
  padding: 3px 0 12px 0;
  font-family: 'Anton', sans-serif;
  font-size: clamp(3rem, 3vw, 4rem);
  font-weight: 200;
  color: #7FDBFF;
  text-shadow: 0 0 2px rgba(102, 217, 255, 0.4);
  text-align: center;
}

.overview-conclusion {
  display: grid;
  align-items: center;
  width: 100%;
  margin: 0.3rem auto;
  gap: 0.5rem;
  padding: 0.5rem;
  background: rgba(255, 255, 255, 0.03);
  border-left: 6px solid #FFD662;
  font-family: 'Anton', sans-serif;
  font-size: clamp(1.8rem, 2.3vw, 1.6rem);
  font-weight: 200;
  color: #FFD662;
  text-shadow: 0 0 2px rgba(102, 217, 255, 0.4);
}

.chart-body {
  margin: 12px;
  background-color: rgb(40, 40, 41) !important;
  height: auto;
}

.dropdown-area {
  display: grid;
  grid-template-columns: 1fr;
  row-gap: 1rem;
  padding: 0.5rem 1rem;
}

.dropdown-item {
  display: grid;
  grid-template-columns: 4fr 8fr;
  align-items: center;
  gap: 0.75rem;
}

.dropdown-label {
  font-size: 1rem;
  font-weight: 600;
  color: #f8f9fa;
  white-space: nowrap;
}

.dropdown-select {
  width: 100%;
  border-radius: 10px;
  color: rgb(40, 40, 41) !important;
  padding: 0.5rem 0.5rem !important;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.dropdown-select:hover {
  background-color: rgb(77, 77, 77);
}
.dropdown-select:focus-within {
  background-color: rgb(87, 87, 87);
}

/* Slider mark text */
.rc-slider-mark-text {
  font-size: 16px;
  white-space: nowrap;
  max-width: 60px;
  color: white !important;
}
@media (max-width: 900px) {
  .rc-slider-mark-text {
    font-size: 8px;
  }
}
@media (max-width: 480px) {
  .rc-slider-mark-text {
    font-size: 6px;
  }
}

/* Adjusting Map */
#map {
  width: 100%;
  height: 100vh;
  position: relative;
  cursor: pointer;
}

/* Adjusting Time Series Plot*/
.user-select-none.svg-container {
  width: 100% !important;
  height: 50%; /* or keep fixed height like 85vh if needed */
}

/* Sea Ice Tracker Graph Selectors*/
.selector-text {
  fill: black !important;
}

/* Dropdown / Select theming */
.Select-control {
  background-color: rgb(40, 40, 41) !important;
  color: white !important;
  border-color: #555 !important;
}
.Select-value-label {
  color: white !important;
  text-align: center !important;
  width: 100%;
  display: block !important;
}
.Select--single > .Select-control .Select-placeholder {
  color: #ccc !important;
  text-align: center !important;
  display: block !important;
  justify-content: center !important;
}
.Select-input {
  display: flex !important;
  justify-content: center !important;
  text-align: center !important;
}
.Select-input input {
  text-align: center !important;
  color: white !important;
}
.VirtualizedSelectOption {
  background-color: rgb(40, 40, 41) !important;
  color: white !important;
}
.VirtualizedSelectOption:hover {
  background-color: #333 !important;
}

/* ── Get Data Panel / Sidebar Navigation ── */
.get-data-sidebar-nav .nav-link {
  border-radius: 4px;
  transition: background-color .15s ease, transform .1s ease;
  color: #ccc;
}
.get-data-sidebar-nav .nav-link:hover {
  background-color: rgba(255, 255, 255, 0.08);
  transform: translateX(2px);
  color: #fff;
}
.get-data-sidebar-nav .nav-link.active {
  background-color: rgba(255, 255, 255, 0.1);
  color: #fff;
  font-weight: 600;
}

/* dividing line / frame */
.get-data-inner-frame {
  border: 2px solid rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  overflow: hidden;
}

.get-data-scroll {
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
  max-height: calc(100vh - 180px);
  padding-right: 8px;
  box-sizing: border-box;
  scroll-behavior: smooth;
}

/* ── Misc / Legacy Cleanup targets ── */
.conclusionArea {
  max-width: 96%;
  margin: 0 auto;
  display: flex;
  justify-content: center;
  padding: 0.6rem 1.8rem;
  border-left: 6px solid #FFD662;
  font-family: 'Anton', sans-serif;
  font-size: 2rem;
  font-weight: 200;
  color: #FFD662;
}

.filterInfo:hover {
  color: #fff;
}


/* ============================================================
   PART E — Responsive shell (added U2)
   ------------------------------------------------------------
   Topbar (48 px, all viewports), content region, and mobile
   bottom-nav (<640 px). Progressively supersedes the legacy
   .nav-tabs / .tab-link / .logo-in-tabs rules in PART D.
   Uses only tokens from PART A — no new tokens introduced.
   ============================================================ */

/* ---------- Topbar ---------- */
.aa-topbar {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: calc(var(--topbar-height) + var(--safe-top));
  padding: var(--safe-top) 20px 0 20px;
  padding-left: calc(20px + var(--safe-left));
  padding-right: calc(20px + var(--safe-right));
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-soft);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

/* Centre nav (topbar) — desktop + tablet */
.aa-topbar__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
  flex: 1 1 auto;
  min-width: 0;
}

.aa-topbar__nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--touch-target);
  padding: 12px 14px;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 16px;
  color: var(--text-primary);
  text-decoration: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  transition:
    color var(--transition),
    text-shadow var(--transition);
}

.aa-topbar__nav-link:hover {
  color: var(--text-bright);
  text-shadow: 0 0 8px rgba(8, 247, 254, 0.45);
}

.aa-topbar__nav-link:focus-visible {
  outline: 2px solid var(--neon-cyan);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Active state — set by Dash NavLink (`active="exact"` -> .active) */
.aa-topbar__nav-link.active {
  color: var(--neon-cyan);
}

.aa-topbar__nav-link.active::after {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 6px;
  height: 2px;
  background: var(--neon-cyan);
  box-shadow: 0 0 6px var(--neon-cyan);
  border-radius: 2px;
}

/* Brand cluster (left): ASP logo + dashboard title. */
.aa-topbar__brand {
  display: flex;
  align-items: center;
  gap: 22px;
  min-width: 0;
  flex: 0 0 auto;
}

.aa-topbar__brand-text {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.02em;
  color: var(--text-bright);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ASP logo — now the top-left brand element (was top-right). */
.aa-topbar__logo {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  opacity: 0.8;
  transition: opacity var(--transition);
}

.aa-topbar__logo:hover {
  opacity: 1;
}

.aa-topbar__logo img {
  height: 56px;
  width: auto;
  display: block;
}

/* Top-right cluster: "How to use this tab" + "About" chips.
   Both use the shared `.chip filterInfo` pill styling from Part B — the
   NZAEA reference for these top-right action pills. `.aa-topbar__help-chip`
   just marks the tutorial chip so the topbar layout can gap them apart. */
.aa-topbar__chips {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

.aa-topbar__help-chip {
  cursor: pointer;
}

.aa-topbar__help-chip-label {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--text-muted);
}

.aa-topbar__help-chip-glyph {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--neon-cyan);
  line-height: 1;
}

.aa-topbar__help-chip:hover .aa-topbar__help-chip-label {
  color: var(--text-bright);
}

/* Tablet — tighter nav spacing */
@media (max-width: 1023px) {
  .aa-topbar__nav {
    gap: 16px;
  }
}


/* ---------- Content region ---------- */
.aa-content {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: calc(100vh - var(--topbar-height));
  min-width: 0;
}


/* ---------- Bottom nav (mobile only) ---------- */
.aa-bottomnav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
  display: none;                     /* revealed <640 px */
  align-items: stretch;
  justify-content: space-around;
  height: calc(var(--bottomnav-height) + var(--safe-bottom));
  padding-bottom: var(--safe-bottom);
  padding-left: var(--safe-left);
  padding-right: var(--safe-right);
  background: var(--bg-surface);
  border-top: 1px solid var(--border-soft);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.aa-bottomnav__item {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: var(--touch-target);
  padding: 6px 4px;
  font-family: var(--font-ui);
  font-weight: 500;
  font-size: 11px;
  color: var(--text-muted);
  text-decoration: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: color var(--transition);
}

.aa-bottomnav__item:hover {
  color: var(--text-primary);
}

.aa-bottomnav__item:focus-visible {
  outline: 2px solid var(--neon-cyan);
  outline-offset: -2px;
  border-radius: 4px;
}

.aa-bottomnav__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
}

.aa-bottomnav__icon svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.aa-bottomnav__item.active {
  color: var(--neon-cyan);
}

.aa-bottomnav__item.active .aa-bottomnav__icon {
  filter: drop-shadow(0 0 6px rgba(8, 247, 254, 0.65));
}


/* ---------- Mobile break (<640 px) ---------- */
@media (max-width: 639px) {
  /* Mobile shows only the brand-glyph in the topbar — no need for the
     tall desktop bar. Shrink the token so all downstream calc()s follow. */
  :root {
    --topbar-height: 56px;
  }
  .aa-topbar {
    padding-left: calc(16px + var(--safe-left));
    padding-right: calc(16px + var(--safe-right));
  }
  .aa-topbar__brand-text,
  .aa-topbar__nav,
  .aa-topbar__logo {
    display: none;
  }
  .aa-bottomnav {
    display: flex;
  }
  .aa-content {
    padding-bottom: calc(var(--bottomnav-height) + var(--safe-bottom) + 16px);
  }
}

@media (min-width: 640px) {
  .aa-bottomnav {
    display: none;
  }
}


/* ============================================================
   PART E · U4 — Time Series tab layout
   ------------------------------------------------------------
   Retains the basemap iframe verbatim (assets/antarctica_gibs.html)
   and wraps it in a hero card. On desktop the basemap and the
   banner + graphs stack side-by-side (60 / 40). On tablet and
   mobile the basemap goes full-width up top and the graphs stack
   below.

   Preserved IDs consumed by CSS (styled by class, not id):
     #antarctica-iframe, #time-series, #granular-time-series,
     #output, #ts-brew-caption (U7 populates).
   ============================================================ */

.aa-ts {
  display: block;
  padding: 16px;
  color: var(--text-primary);
}

/* Grid container.
   Mobile (default): single column, hero on top.
   Tablet + desktop: see media queries below. */
.aa-ts__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  align-items: stretch;
  min-height: 0;
}

/* ---- Basemap card ---- */
/* No header above the iframe — the map fills the card top-to-almost-bottom
   with a slim status strip beneath. The top padding here MUST match
   `.aa-ts__controls-panel` so the map iframe's top edge aligns with the
   controls-panel inner row across the grid row. */
.aa-ts__basemap-hero {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 16px 14px 16px;
  min-width: 0;
}

/* Status strip beneath the iframe. Written to by the time_series callback:
   "No location selected…" / "Current location …". Slim, quiet, but with
   the neon cyan accent bar so users can find it. */
.aa-ts__basemap-status {
  display: flex;
  align-items: center;
  min-height: 20px;
}

.aa-ts__basemap-status-text {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-primary);
  letter-spacing: 0.02em;
  border-left: 2px solid var(--neon-cyan);
  padding-left: 10px;
  min-height: 1em;
  width: 100%;
}
.aa-ts__basemap-status-text:empty {
  border-left-color: transparent;
}

/* Tutorial chip: inherits .chip from Part B; add positioning + spacing. */
.aa-ts__hero-tutorial {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  cursor: pointer;
}

.aa-ts__hero-tutorial-label {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--text-muted);
}

.aa-ts__hero-tutorial-glyph {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--neon-cyan);
  line-height: 1;
}

.aa-ts__hero-tutorial-label {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--text-muted);
}

.aa-ts__hero-tutorial-glyph {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--neon-cyan);
  line-height: 1;
}

/* Iframe mount + iframe itself.
   The iframe body (assets/antarctica_gibs.html) is unchanged. */
.aa-ts__basemap-mount {
  position: relative;
  width: 100%;
  border-radius: var(--border-radius);
  overflow: hidden;
  background: var(--bg-elevated);
  border: 1px solid var(--border-soft);
  min-height: 40vh;
}

.aa-ts__basemap-iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 40vh;
  border: 0;
}

/* ---- Right column: single tabbed graph card ---- */
.aa-ts__data-column {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

/* Graph card holds the tab switcher + a stack of panes (only one visible). */
.aa-ts__graph-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 14px 14px 14px;
  min-width: 0;
}

/* Proportional graph sizing.
   16:9 keeps the daily plot readable on tablet/desktop; min-height guards
   short/narrow viewports; max-height prevents the plot from dominating
   the fold on ultra-wide screens. */
.aa-ts__graph {
  width: 100%;
  aspect-ratio: 16 / 9;
  min-height: 260px;
  max-height: 480px;
}

/* ---- Daily date-range picker (dcc.DatePickerRange / react-dates) ----
   The stock component is a light-theme island in the middle of the dark
   neon canvas. These overrides re-skin the visible surfaces: the input
   row, its focus state, and the calendar overlay. Kept scoped to
   `.aa-ts__daterange` where possible so the airtemp / get-data tabs
   aren't affected if they ever mount their own picker. */
/* Controls panel — top of the right column. Single horizontal row.
   Padding matches `.aa-ts__basemap-hero` so the inner row's top edge
   lines up with the map iframe's top edge across the grid row. */
.aa-ts__controls-panel {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px 14px 16px;
  min-width: 0;
  flex-wrap: wrap;
}

/* Date-range block: label to the LEFT of the picker (inline row form). */
.aa-ts__daterange-row {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.aa-ts__daterange-label {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
  white-space: nowrap;
}

/* Input row — replace the white bordered pill with a neon-tinted chip. */
.aa-ts__daterange .DateRangePickerInput,
.aa-ts__daterange .DateRangePickerInput__withBorder {
  background: rgba(224, 224, 255, 0.04);
  border: 1px solid var(--border-soft);
  border-radius: calc(var(--border-radius) - 4px);
  overflow: hidden;
}

.aa-ts__daterange .DateInput {
  background: transparent;
  width: 108px;
}

.aa-ts__daterange .DateInput_input {
  background: transparent;
  color: var(--text-bright);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 6px 10px;
  border: 0;
  border-bottom: 2px solid transparent;
  text-align: center;
}

.aa-ts__daterange .DateInput_input::placeholder {
  color: var(--text-muted);
}

.aa-ts__daterange .DateInput_input__focused {
  border-bottom-color: var(--neon-cyan);
  background: rgba(8, 247, 254, 0.06);
}

.aa-ts__daterange .DateRangePickerInput_arrow_svg {
  fill: var(--text-muted);
  height: 14px;
  width: 14px;
}

.aa-ts__daterange .DateInput_fang {
  display: none;
}

/* Calendar overlay — rendered in a portal, so scope by inner classes
   (react-dates emits these globally). The overlay isn't a descendant of
   `.aa-ts__daterange` in the DOM, so we style the DayPicker classes
   directly. If another picker mounts elsewhere it will inherit the neon
   skin — acceptable given the dark theme is app-wide. */
.DayPicker,
.DayPicker__horizontal,
.DateRangePicker_picker,
.SingleDatePicker_picker {
  background: var(--bg-elevated) !important;
  color: var(--text-primary) !important;
  border: 1px solid var(--border-soft);
  border-radius: var(--border-radius);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
}

.DayPicker_transitionContainer,
.CalendarMonthGrid,
.CalendarMonth {
  background: transparent !important;
}

.CalendarMonth_caption {
  color: var(--text-bright);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding-top: 18px;
  padding-bottom: 42px;
}

.DayPicker_weekHeader {
  color: var(--text-muted);
}

.DayPicker_weekHeader_li small {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}

.CalendarDay__default {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-primary);
  font-family: var(--font-mono);
  font-size: 12px;
  vertical-align: middle;
}

.CalendarDay__default:hover {
  background: rgba(8, 247, 254, 0.10);
  border-color: rgba(8, 247, 254, 0.35);
  color: var(--text-bright);
}

.CalendarDay__blocked_out_of_range,
.CalendarDay__blocked_out_of_range:hover,
.CalendarDay__blocked_out_of_range:active {
  background: transparent;
  color: rgba(224, 224, 255, 0.20);
  border-color: transparent;
  cursor: not-allowed;
}

.CalendarDay__selected_span {
  background: rgba(8, 247, 254, 0.16);
  border: 1px solid rgba(8, 247, 254, 0.25);
  color: var(--text-bright);
}
.CalendarDay__selected_span:hover {
  background: rgba(8, 247, 254, 0.24);
  border-color: rgba(8, 247, 254, 0.45);
}

.CalendarDay__hovered_span,
.CalendarDay__hovered_span:hover {
  background: rgba(8, 247, 254, 0.08);
  border: 1px solid rgba(8, 247, 254, 0.20);
  color: var(--text-primary);
}

.CalendarDay__selected,
.CalendarDay__selected:active,
.CalendarDay__selected:hover {
  background: var(--neon-cyan);
  border-color: var(--neon-cyan);
  color: #0a0a0f;
  font-weight: 600;
}

.CalendarDay__today {
  box-shadow: inset 0 -2px 0 var(--neon-cyan);
}

/* Month-nav arrows — the SVG chevrons. */
.DayPickerNavigation_button__default {
  background: rgba(224, 224, 255, 0.05);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
}
.DayPickerNavigation_button__default:hover {
  background: rgba(8, 247, 254, 0.10);
  border-color: rgba(8, 247, 254, 0.35);
}
.DayPickerNavigation_svg__horizontal {
  fill: var(--text-primary);
}

/* Keyboard-shortcut helper in the corner of the calendar — hide it,
   it clashes with the compact neon layout. */
.DayPickerKeyboardShortcuts_show {
  display: none !important;
}

/* U7 target: escalating caption during a fetch. Empty by default.
   Reserves visual space so the layout doesn't jump when text appears. */
.aa-ts__brew-caption {
  min-height: 16px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-align: center;
}
.aa-ts__brew-caption:empty {
  min-height: 0;
}

/* Legacy loading-message placeholder — hidden but mounted. */
.aa-ts__loading-message {
  display: none;
}

/* ---- Tablet: 640 – 1023 px ---- */
@media (min-width: 640px) {
  .aa-ts {
    padding: 20px;
  }
  .aa-ts__grid {
    gap: 20px;
  }
  .aa-ts__basemap-mount,
  .aa-ts__basemap-iframe {
    min-height: 55vh;
  }
  .aa-ts__graph {
    min-height: 300px;
    max-height: 520px;
  }
}

/* ---- Desktop: >= 1024 px — 60 / 40 split ---- */
@media (min-width: 1024px) {
  .aa-ts__grid {
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 24px;
    align-items: stretch;
  }
  /* Basemap fills the vertical space between the top of the grid and the
     bottom of the viewport. Reserves ~160 px for topbar + p-4 + aa-ts
     padding + hero header + card padding + bottom breathing room. */
  .aa-ts__basemap-mount,
  .aa-ts__basemap-iframe {
    min-height: calc(100vh - var(--topbar-height) - 160px);
  }
  /* Single visible graph → let it size proportionally to the card width
     via aspect-ratio, but cap the height so it never exceeds the visible
     band next to the basemap. */
  .aa-ts__graph {
    min-height: 300px;
    max-height: calc(100vh - var(--topbar-height) - 240px);
  }
}

/* Extremely short viewports (<= 560 px tall): shrink the iframe cap
   so the banner and at least one graph remain visible without
   forcing the user to scroll through the map. */
@media (max-height: 560px) {
  .aa-ts__basemap-mount,
  .aa-ts__basemap-iframe {
    min-height: 45vh;
  }
}


/* ============================================================
   PART E · U5 — Air Temp tab layout
   ------------------------------------------------------------
   Retains the VAPOR iframe verbatim (assets/index_antair.html).
   Hero card with the iframe on top, supporting description
   panel below. Tutorial trigger is a chip in the top-right
   of the hero header.

   Preserved IDs consumed by CSS (styled by class, not id):
     #all-tracker-iframe.
   ============================================================ */

.aa-airtemp {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  color: var(--text-primary);
}

/* ---- Hero card ---- */
.aa-airtemp__hero {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px 14px 14px 14px;
  min-width: 0;
}

.aa-airtemp__hero-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
}

.aa-airtemp__hero-title-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.aa-airtemp__hero-title {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 14px;
  color: var(--text-bright);
  letter-spacing: 0.01em;
}

.aa-airtemp__hero-hint {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 11px;
  color: var(--text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.aa-airtemp__hero-tutorial {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  cursor: pointer;
}

.aa-airtemp__hero-tutorial-label {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--text-muted);
}

.aa-airtemp__hero-tutorial-glyph {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--neon-cyan);
  line-height: 1;
}

/* Iframe mount + iframe. VAPOR is heavy — loading="lazy" applied
   on the tag in air_temp_tab.py. Mobile uses aspect-ratio for a
   consistent shape on small screens; desktop uses min-height. */
.aa-airtemp__iframe-mount {
  position: relative;
  width: 100%;
  border-radius: var(--border-radius);
  overflow: hidden;
  background: #000;
  border: 1px solid var(--border-soft);
  aspect-ratio: 16 / 9;
  min-height: 40vh;
}

.aa-airtemp__iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 40vh;
  border: 0;
}

/* ---- Description panel ---- */
.aa-airtemp__description {
  padding: 12px 14px;
}

.aa-airtemp__description-text {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-primary);
}

/* ---- Gallery scaffold (currently unused — reserved for future
   teaser images / mp4 posters if U6/owner decides to surface them
   here rather than in Get Data). Kept as an empty stub so
   supporting content can be added without a fresh CSS pass. ---- */
.aa-airtemp__gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

/* ---- Tablet: 640 – 1023 px ---- */
@media (min-width: 640px) {
  .aa-airtemp {
    padding: 20px;
    gap: 20px;
  }
  .aa-airtemp__iframe-mount {
    aspect-ratio: auto;
    min-height: 55vh;
  }
  .aa-airtemp__iframe {
    min-height: 55vh;
  }
  .aa-airtemp__gallery {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---- Desktop: >= 1024 px ---- */
@media (min-width: 1024px) {
  .aa-airtemp__iframe-mount {
    aspect-ratio: auto;
    min-height: 65vh;
  }
  .aa-airtemp__iframe {
    min-height: 65vh;
  }
  .aa-airtemp__gallery {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Very short viewports: keep the iframe usable without forcing
   the description panel off-screen. */
@media (max-height: 560px) {
  .aa-airtemp__iframe-mount,
  .aa-airtemp__iframe {
    min-height: 45vh;
  }
}



/* ============================================================
   PART E · U3 — About modal & intro overlay
   ------------------------------------------------------------
   Two dbc.Modal instances redesigned to the token system:
     * `#about-modal`      ("How to use this dashboard" — pop_up)
     * `#aboutintro-modal` (AntAir dataset intro — about_intro_modal)

   Copy inside both modals is preserved verbatim in common_layout.py.
   All rules here paint chrome, not content.

   Desktop / tablet: centred elevated card, 1 px --border-soft,
     6 px --border-radius, cyan focus ring on interactive elements.
   Mobile (<640 px): dbc.Modal(fullscreen="sm-down") already turns the
     dialog into a full-height sheet — we add the bottom-sheet feel
     (rounded top corners, subtle slide-up entrance, drag handle) via
     the `.aa-modal.modal-fullscreen-sm-down` selector Bootstrap sets.

   Also styles the discreet `.aa-help-chip` that replaces the old
   "Antarctic Air Dashboard" title strip (agent-F flagged the
   redundancy under the new topbar).
   ============================================================ */

/* ---------- Hero-actions cluster + contextual About chip ---------- */
/* Every tab's hero header has a right-aligned actions group (tutorial
   trigger + About chip). The About chip is generated by
   common_layout.about_chip(loc) with a pattern-matching ID so a single
   `pop_up` callback handles every instance. */
.aa-hero-actions {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  flex: 0 0 auto;
}

.aa-hero-about {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  cursor: pointer;
}
.aa-hero-about-label {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--text-muted);
}
.aa-hero-about-glyph {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--neon-cyan);
  line-height: 1;
}

@media (max-width: 639px) {
  /* Mobile: keep the icon, drop the label — actions row stays compact. */
  .aa-hero-about-label {
    display: none;
  }
}

/* ---------- Modal (all sizes) ---------- */
.aa-modal .modal-content,
.aa-modal__content {
  background: var(--bg-elevated);
  color: var(--text-primary);
  border: 1px solid var(--border-soft);
  border-radius: var(--border-radius);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55);
  font-family: var(--font-ui);
}

.aa-modal__header {
  background: transparent;
  border-bottom: 1px solid var(--border-soft);
  padding: 16px 20px;
  gap: 12px;
  align-items: center;
}

.aa-modal__title {
  font-family: var(--font-ui);
  font-weight: 600;
  color: var(--text-bright);
  font-size: 18px;
  letter-spacing: 0.01em;
  margin: 0;
}

.aa-modal__header .btn-close {
  width: var(--touch-target);
  height: var(--touch-target);
  min-width: var(--touch-target);
  min-height: var(--touch-target);
  margin: 0 0 0 auto;
  padding: 12px;
  background-color: transparent;
  border-radius: var(--border-radius);
  opacity: 0.7;
  transition: opacity var(--transition), background-color var(--transition),
              box-shadow var(--transition);
}

.aa-modal__header .btn-close:hover {
  opacity: 1;
  background-color: rgba(8, 247, 254, 0.08);
}

.aa-modal__header .btn-close:focus-visible {
  outline: 2px solid var(--neon-cyan);
  outline-offset: 2px;
  opacity: 1;
  box-shadow: none;
}

.aa-modal__body {
  padding: 20px;
  color: var(--text-primary);
  font-size: 14px;
  line-height: 1.6;
}

.aa-modal__body p,
.aa-modal__body li {
  color: var(--text-primary);
}

.aa-modal__body h5 {
  font-family: var(--font-ui);
  font-weight: 600;
  color: var(--text-bright);
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-top: 20px;
  margin-bottom: 8px;
}

.aa-modal__body hr {
  border: 0;
  border-top: 1px solid var(--border-soft);
  margin: 16px 0;
  opacity: 1;
}

.aa-modal__body ul {
  padding-left: 18px;
  margin-bottom: 8px;
}

.aa-modal__link {
  color: var(--neon-cyan);
  text-decoration: underline;
  text-decoration-color: rgba(8, 247, 254, 0.4);
  text-underline-offset: 2px;
  transition: color var(--transition),
              text-decoration-color var(--transition);
}

.aa-modal__link:hover,
.aa-modal__link:focus-visible {
  color: var(--neon-cyan);
  text-decoration-color: var(--neon-cyan);
}

.aa-modal__link:focus-visible {
  outline: 2px solid var(--neon-cyan);
  outline-offset: 2px;
  border-radius: 2px;
}

.aa-modal__footnote {
  color: var(--text-muted);
  font-style: italic;
  font-size: 12px;
  margin-top: 20px;
  margin-bottom: 0;
}

.aa-modal__footer {
  background: transparent;
  border-top: 1px solid var(--border-soft);
  padding: 12px 20px;
  padding-bottom: calc(12px + var(--safe-bottom));
}

.aa-modal__cta {
  min-height: var(--touch-target);
  padding: 8px 18px;
  border-radius: var(--border-radius);
  border: 1px solid var(--border-soft);
  background: var(--bg-surface);
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-weight: 500;
  transition: color var(--transition), border-color var(--transition),
              background-color var(--transition), box-shadow var(--transition);
}

.aa-modal__cta:hover {
  color: var(--text-bright);
  border-color: var(--neon-cyan);
  background: var(--bg-elevated);
  box-shadow: 0 0 12px rgba(8, 247, 254, 0.25);
}

.aa-modal__cta:focus-visible {
  outline: 2px solid var(--neon-cyan);
  outline-offset: 2px;
}

.modal-backdrop.show {
  opacity: 0.65;
}

/* ---------- Mobile bottom-sheet (<640 px) ---------- */
@media (max-width: 639px) {
  .aa-modal .modal-fullscreen-sm-down {
    padding-top: max(56px, var(--sheet-peek, 96px));
  }

  .aa-modal .modal-fullscreen-sm-down .modal-content,
  .aa-modal .modal-fullscreen-sm-down .aa-modal__content {
    border-radius: 14px 14px 0 0;
    border-top: 1px solid var(--border-soft);
    border-left: none;
    border-right: none;
    border-bottom: none;
    animation: aa-sheet-in 0.24s cubic-bezier(0.22, 1, 0.36, 1);
    padding-bottom: var(--safe-bottom);
  }

  .aa-modal .modal-fullscreen-sm-down .aa-modal__header {
    position: relative;
    padding-top: 22px;
  }
  .aa-modal .modal-fullscreen-sm-down .aa-modal__header::before {
    content: "";
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background: var(--border-soft);
  }

  .aa-modal__title {
    font-size: 16px;
  }

  .aa-modal__body {
    padding: 16px;
    font-size: 14px;
  }
}

@keyframes aa-sheet-in {
  from { transform: translateY(24px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}


/* ============================================================
   PART E · U6 — Get Data tab layout
   ------------------------------------------------------------
   Chip strip + content grid.

   Desktop  (>=1024 px): sidebar 240 px fixed left,
                         content flex-1 right, both scroll independently.
   Tablet   (640-1023 px): sidebar collapses to a horizontal chip strip
                           on top; content spans full width below.
   Mobile   (<640 px):    chip strip stays; overflow-x scrolls when
                          there are more chips than viewport width.

   Preserved IDs consumed by CSS (styled by class, not id):
     - `#get-data-current-topic` (dcc.Store — invisible)
     - `#get-data-content`       — scroll container in the content col
     - `#get-data-output`        — dcc.Graph inside the "plot" section
     - `#topic-{key}-link`       — chip buttons

   Legacy classes `.get-data-scroll` and `.get-data-sidebar-nav` are
   also present on the same DOM nodes so `assets/get_data_nav.js`
   (scroll-follow + active-state) continues to work without change.
   ============================================================ */

.aa-getdata__wrap {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  padding-left: calc(16px + var(--safe-left));
  padding-right: calc(16px + var(--safe-right));
  height: 100%;
  min-height: 0;
  box-sizing: border-box;
  overflow: hidden;
}

/* ---------- Hero ---------- */
.aa-getdata__hero {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 4px 8px 4px;
}

.aa-getdata__hero-text {
  min-width: 0;
  flex: 1 1 auto;
}

.aa-getdata__hero-title {
  font-family: var(--font-ui);
  font-weight: 600;
  color: var(--text-bright);
  font-size: 20px;
  letter-spacing: 0.01em;
  margin: 0 0 4px 0;
}

.aa-getdata__hero-lede {
  font-family: var(--font-ui);
  color: var(--text-muted);
  font-size: 13px;
  margin: 0;
}

/* ---------- Grid ---------- */
.aa-getdata {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 16px;
  flex: 1;
  min-height: 0;
  align-items: stretch;
}

/* ---------- Sidebar (desktop) ---------- */
.aa-getdata__sidebar {
  min-width: 0;
}

.aa-getdata__sidebar-inner {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  height: 100%;
  box-sizing: border-box;
  overflow: hidden;
}

.aa-getdata__sidebar-title {
  font-family: var(--font-ui);
  font-weight: 600;
  color: var(--text-muted);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 4px 6px;
}

.aa-getdata__chips {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ---------- Chip (sidebar item / mobile chip) ---------- */
.aa-getdata__chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--touch-target);
  padding: 8px 12px;
  background: transparent;
  color: var(--text-primary);
  border: 1px solid var(--border-soft);
  border-radius: var(--border-radius);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
  text-align: left;
  white-space: nowrap;
  text-decoration: none;
  transition: color var(--transition), border-color var(--transition),
              background-color var(--transition), box-shadow var(--transition);
}

.aa-getdata__chip:hover {
  color: var(--text-bright);
  border-color: var(--neon-cyan);
  background: var(--bg-elevated);
}

.aa-getdata__chip:focus-visible {
  outline: 2px solid var(--neon-cyan);
  outline-offset: 2px;
  color: var(--text-bright);
}

/* Active state — driven by assets/get_data_nav.js which toggles the
   `.active` class as the reader scrolls between sections. */
.aa-getdata__chip.active {
  color: var(--neon-cyan);
  border-color: var(--neon-cyan);
  background: rgba(8, 247, 254, 0.06);
  box-shadow: 0 0 12px rgba(8, 247, 254, 0.18);
}

/* ---------- Content column ---------- */
.aa-getdata__content {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  padding: 0;
}

.aa-getdata__content-inner {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 20px 24px;
  scroll-behavior: smooth;
}

.aa-getdata__section {
  padding-top: 8px;
  padding-bottom: 40px;
  border-bottom: 1px solid var(--border-soft);
}

.aa-getdata__section:last-child {
  border-bottom: none;
  padding-bottom: 24px;
}

.aa-getdata__section-title {
  font-family: var(--font-ui);
  font-weight: 600;
  color: var(--text-bright);
  font-size: 18px;
  letter-spacing: 0.01em;
  margin: 0 0 12px 0;
}

.aa-getdata__p {
  color: var(--text-primary);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.6;
  text-align: left;
  margin: 16px 0 12px 0;
}

/* ---------- Code blocks ---------- */
.aa-getdata__codewrap {
  position: relative;
  margin-top: 8px;
}

.aa-getdata__codeblock {
  margin: 0;
  padding: 14px 16px;
  padding-right: 44px;
  background: var(--bg-surface);
  color: var(--text-primary);
  border: 1px solid var(--border-soft);
  border-radius: var(--border-radius);
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.55;
  white-space: pre;
  overflow-x: auto;
  text-align: left;
}

.aa-getdata__codeblock::selection {
  background: rgba(8, 247, 254, 0.22);
  color: var(--text-bright);
}

.aa-getdata__copy {
  position: absolute;
  top: 8px;
  right: 8px;
  color: var(--text-muted);
  padding: 6px;
  border-radius: 4px;
  cursor: pointer;
  transition: color var(--transition), background-color var(--transition);
}

.aa-getdata__copy:hover {
  color: var(--neon-cyan);
  background: rgba(8, 247, 254, 0.08);
}

.aa-getdata__output {
  margin: 8px 0 12px 0;
  padding: 10px 12px;
  background: var(--bg-primary);
  color: var(--text-muted);
  border: 1px solid var(--border-soft);
  border-radius: var(--border-radius);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.45;
  white-space: pre;
  overflow-x: auto;
  text-align: left;
}

.aa-getdata__img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 12px 0;
  border: 1px solid var(--border-soft);
  border-radius: var(--border-radius);
  background: var(--bg-surface);
}

.aa-getdata__graph {
  margin: 12px 0;
  min-height: 260px;
}

/* ---------- Tablet: sidebar → horizontal chip strip ---------- */
@media (max-width: 1023px) {
  .aa-getdata {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }
  .aa-getdata__sidebar {
    height: auto;
  }
  .aa-getdata__sidebar-inner {
    flex-direction: column;
    padding: 10px 12px;
    gap: 6px;
    height: auto;
  }
  .aa-getdata__chips {
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 8px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--border-soft) transparent;
    padding-bottom: 2px;
  }
  .aa-getdata__chips::-webkit-scrollbar {
    height: 6px;
  }
  .aa-getdata__chips::-webkit-scrollbar-thumb {
    background: var(--border-soft);
    border-radius: 3px;
  }
  .aa-getdata__chip {
    flex: 0 0 auto;
    padding: 6px 12px;
    min-height: calc(var(--touch-target) - 6px);
  }
}

/* ---------- Mobile: tighten paddings ---------- */
@media (max-width: 639px) {
  .aa-getdata__wrap {
    padding: 12px;
    padding-left: calc(12px + var(--safe-left));
    padding-right: calc(12px + var(--safe-right));
    gap: 10px;
  }
  .aa-getdata__content-inner {
    padding: 16px 14px;
  }
  .aa-getdata__hero-title {
    font-size: 18px;
  }
  .aa-getdata__section-title {
    font-size: 16px;
  }
  .aa-getdata__codeblock {
    font-size: 12px;
    padding: 12px 14px;
    padding-right: 40px;
  }
  .aa-getdata__output {
    font-size: 11px;
  }
}


/* ============================================================
   PART E · U7 — Brewing coffee-cup loader (added U7)
   ============================================================
   Wires the PART C keyframes (brew-fill, brew-steam, brew-dots) to the
   inline SVG mounted by `components/brewing_loader.py` and hosted by the
   two `dcc.Loading(custom_spinner=…)` wrappers on the Time Series tab.

   Structure of the loader DOM (as returned by brewing_cup()):

     .brew-scrim                          full-cover overlay + backdrop blur
       .brew-cup-wrap                     flex column, cup + caption
         .brew-cup                        96 x 96 SVG wrapper (Part C stub
                                          re-declared here to override the
                                          Part C absolute-positioning that
                                          was written before dcc.Loading's
                                          custom_spinner render tree was
                                          known)
           <svg>                          coffee cup
             rect.brew-cup__liquid       .brew-fill 3s ease-in-out infinite
             path.brew-cup__steam--1     .brew-steam 2.4s ease-out infinite
             path.brew-cup__steam--2     .brew-steam 2.4s + 0.4s delay
             path.brew-cup__steam--3     .brew-steam 2.4s + 0.8s delay
         .brew-caption                    static text + ::after animated dots
   */

/* Full-cover scrim — dcc.Loading positions its spinner in an absolutely-
   positioned box over the wrapped graph. We paint a semi-transparent dark
   fill + 2 px backdrop blur so the demo/stale figure fades behind the
   brewing cup while the fetch is in flight. `pointer-events: none` so the
   Plotly modebar underneath doesn't get blocked while the cup shows (it
   already can't be clicked because dcc.Loading masks input, but belt-
   and-braces). */
.brew-scrim {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 10, 15, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  border-radius: var(--border-radius);
  z-index: 5;
  pointer-events: none;
}

.brew-cup-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 16px 20px;
}

/* Override PART C's absolute-positioning `.brew-cup` stub — inside the
   custom_spinner render tree we want the SVG wrapper to size to its
   contents, not fill the parent. The scrim above already covers the
   graph area. */
.brew-cup {
  position: static;
  display: block;
  width: 96px;
  height: 96px;
  padding: 0;
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  min-height: 0;
  filter: drop-shadow(0 0 12px rgba(8, 247, 254, 0.35));
}

.brew-cup svg {
  width: 96px;
  height: 96px;
  overflow: visible;  /* let steam wisps rise slightly above the viewBox */
}

/* Liquid rectangle — rises from the bottom of the cup to just below the
   rim on each 3 s cycle. PART C `@keyframes brew-fill` translates Y from
   +46 (below cup) → 0 (rim) → +46. */
.brew-cup__liquid {
  animation: brew-fill 3s ease-in-out infinite;
  transform-origin: center;
}

/* Steam wisps — three paths, same keyframe, staggered delays so they
   feel organic. PART C `@keyframes brew-steam` fades opacity 0 → 0.6 → 0
   and translates upward. */
.brew-cup__steam {
  animation: brew-steam 2.4s ease-out infinite;
  transform-origin: center;
}
.brew-cup__steam--1 { animation-delay: 0s; }
.brew-cup__steam--2 { animation-delay: 0.4s; }
.brew-cup__steam--3 { animation-delay: 0.8s; }

/* Caption — mono readout below the cup with animated dots via ::after.
   PART C `@keyframes brew-dots` cycles content between '', '.', '..',
   '...'. */
.brew-caption {
  font-family: var(--font-mono);
  color: var(--text-primary);
  font-size: 13px;
  letter-spacing: 0.06em;
  text-align: center;
  min-width: 14em;         /* stop layout jump as caption text lengthens */
  min-height: 1.2em;
  text-shadow: 0 0 6px rgba(8, 247, 254, 0.35);
}

.brew-caption::after {
  content: '';
  display: inline-block;
  min-width: 1.2em;
  text-align: left;
  animation: brew-dots 1.6s steps(4, end) infinite;
}

/* Reduced-motion friendly. The Part C @media block handles the SVG
   pieces (.brew-cup__fill / .brew-cup__steam / .brew-cup__dots::after
   from the original spec); we add explicit rules for the new class
   names so nothing wiggles when the OS says "no motion please". */
@media (prefers-reduced-motion: reduce) {
  .brew-cup__liquid {
    animation: none !important;
    transform: translateY(12px);
  }
  .brew-cup__steam {
    animation: none !important;
    opacity: 0 !important;
  }
  .brew-caption::after {
    animation-duration: 3s !important;
  }
}

/* First-load splash variant — full viewport cover, sits above everything
   until the Dash app hydrates. Removed by the small script at the bottom
   of app.py's index_string once #page-content has children. Hides Dash's
   default `Loading...` div behind it. */
.brew-scrim--splash {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--bg-primary, #0a0a0f);
  border-radius: 0;
  pointer-events: auto;
  opacity: 1;
  transition: opacity 0.35s ease-out;
}
.brew-scrim--splash.is-hiding {
  opacity: 0;
}
.brew-caption--splash {
  font-size: 15px;
  min-width: 18em;
}
._dash-loading {
  display: none;
}


/* ============================================================
   PART J — Tutorial sidebar (right-slide pane)
   ------------------------------------------------------------
   Ported from the Antarctic Moss Dashboard's About sidebar.
   Toggled by adding the `aa-sidebar-open` class to `#app` (the
   root flex column); a clientside callback in app.py owns that
   flip. At >=900 px the app root gains `padding-right:
   --sidebar-width` so tab content shifts left rather than
   being obscured — the whole point of using a sidebar instead
   of a modal.
   ============================================================ */
.aa-sidebar {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(var(--sidebar-width), 100vw);
  background: var(--bg-surface);
  border-left: 1px solid var(--border-soft);
  box-shadow: -18px 0 40px rgba(0, 0, 0, 0.45);
  transform: translateX(100%);
  transition: transform 0.28s ease;
  z-index: 200;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#app.aa-sidebar-open .aa-sidebar--tutorial {
  transform: translateX(0);
}
@media (min-width: 900px) {
  #app.aa-sidebar-open {
    padding-right: var(--sidebar-width);
    transition: padding-right 0.28s ease;
  }
}

.aa-sidebar__header {
  padding: 20px 24px 16px 24px;
  background: linear-gradient(
    180deg,
    rgba(8, 247, 254, 0.06) 0%,
    rgba(20, 20, 20, 0) 100%);
  border-bottom: 1px solid var(--border-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 0 0 auto;
}
.aa-sidebar__title {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
}
.aa-sidebar__close {
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--border-soft);
  color: var(--text-primary);
  font-size: 16px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all var(--transition);
}
.aa-sidebar__close:hover {
  border-color: var(--neon-cyan);
  color: var(--neon-cyan);
  box-shadow: 0 0 10px rgba(8, 247, 254, 0.35);
}

.aa-sidebar__scroll {
  padding: 20px 24px 32px 24px;
  overflow-y: auto;
  flex: 1 1 auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border-soft) transparent;
}

.aa-sd-intro {
  font-size: 14px;
  color: var(--text-primary);
  margin: 0 0 20px 0;
  line-height: 1.6;
}
.aa-sd-intro strong { color: var(--text-bright); }

.aa-sd-card {
  position: relative;
  padding: 16px 18px 16px 22px;
  margin-bottom: 14px;
  background: linear-gradient(
    140deg,
    rgba(8, 247, 254, 0.04) 0%,
    rgba(20, 20, 20, 0) 60%),
    var(--bg-panel);
  border: 1px solid var(--border-soft);
  border-radius: var(--border-radius);
  transition: all var(--transition);
}
.aa-sd-card::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  border-radius: var(--border-radius) 0 0 var(--border-radius);
  background: linear-gradient(180deg, var(--neon-cyan), var(--neon-green));
  box-shadow: 0 0 12px rgba(8, 247, 254, 0.55);
}
.aa-sd-card:hover {
  transform: translateX(1px);
  border-color: rgba(8, 247, 254, 0.35);
  box-shadow: 0 0 18px rgba(8, 247, 254, 0.1);
}
.aa-sd-card__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: rgba(8, 247, 254, 0.1);
  border: 1px solid rgba(8, 247, 254, 0.55);
  color: var(--neon-cyan);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  box-shadow: 0 0 10px rgba(8, 247, 254, 0.4);
  margin-bottom: 8px;
}
.aa-sd-card__title {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 14px;
  color: var(--text-bright);
  margin: 0 0 6px 0;
}
.aa-sd-card__body {
  font-size: 13px;
  color: var(--text-primary);
  line-height: 1.55;
  margin: 0;
}
.aa-sd-card__body ul {
  margin: 8px 0 0 0;
  padding-left: 18px;
}
.aa-sd-card__body li {
  margin-bottom: 6px;
}
.aa-sd-card__body em {
  color: var(--text-muted);
  font-style: italic;
}
