/* ============================================================================
   RatePilot redesign — shared shell (sidebar + topbar) and design tokens.
   Loaded sitewide from base.html, after every page-specific stylesheet, so
   its rules win on any incidental selector collision. Every new class is
   "rp-" prefixed to guarantee no collision with existing page CSS (verified
   against static/css/*.css before adding this file — .kpi-card and .nav-item
   were already taken by mystyle.css / pricing_dashboard.css).

   The .widget-gated* / .gated-* block near the bottom is the one deliberate
   exception: those are EXISTING selectors (templates/include/widget_overlay.html)
   reskinned in place so every already-gated widget sitewide picks up the new
   look without touching each widget's markup.
   ========================================================================= */

:root {
  color-scheme: light;
  --paper:        #F3F4F1;
  --surface:      #FFFFFF;
  --surface-2:    #EAEBE6;
  --ink:          #14181D;
  --ink-secondary:#4B5158;
  --muted:        #868C8F;
  --border:       rgba(20,24,29,0.10);
  --border-strong:rgba(20,24,29,0.16);
  --accent:       #1E6E71;
  --accent-ink:   #FFFFFF;
  --accent-soft:  #DEEBEA;
  --accent-soft-ink: #12504F;
  --good:         #0ca30c;
  --good-text:    #006300;
  --warning:      #fab219;
  --serious:      #ec835a;
  --critical:     #d03b3b;
  --series-1:     #2a78d6;
  --series-2:     #eb6834;
  --shadow-1:     0 1px 2px rgba(20,24,29,0.05);
  --radius-sm:    6px;
  --radius:       10px;
  --scrim:        rgba(243,244,241,0.72);

  --font-display: ui-serif, "New York", Georgia, "Times New Roman", serif;
  --font-body:    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono:    ui-monospace, "SF Mono", "Roboto Mono", Menlo, Consolas, monospace;
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --paper:        #0A0D0F;
    --surface:      #1B2124;
    --surface-2:    #161B1E;
    --ink:          #F3F5F4;
    --ink-secondary:#C3C8C6;
    --muted:        #8A9295;
    --border:       rgba(255,255,255,0.10);
    --border-strong:rgba(255,255,255,0.16);
    --accent:       #3FA6A0;
    --accent-ink:   #06201F;
    --accent-soft:  rgba(63,166,160,0.16);
    --accent-soft-ink: #8FD9D3;
    --good:         #0ca30c;
    --good-text:    #0ca30c;
    --warning:      #fab219;
    --serious:      #ec835a;
    --critical:     #e66767;
    --series-1:     #3987e5;
    --series-2:     #d95926;
    --shadow-1:     0 1px 2px rgba(0,0,0,0.3);
    --scrim:        rgba(10,13,15,0.72);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --paper:        #0D1113;
  --surface:      #14181B;
  --surface-2:    #101416;
  --ink:          #F3F5F4;
  --ink-secondary:#C3C8C6;
  --muted:        #8A9295;
  --border:       rgba(255,255,255,0.10);
  --border-strong:rgba(255,255,255,0.16);
  --accent:       #3FA6A0;
  --accent-ink:   #06201F;
  --accent-soft:  rgba(63,166,160,0.16);
  --accent-soft-ink: #8FD9D3;
  --good:         #0ca30c;
  --good-text:    #0ca30c;
  --warning:      #fab219;
  --serious:      #ec835a;
  --critical:     #e66767;
  --series-1:     #3987e5;
  --series-2:     #d95926;
  --shadow-1:     0 1px 2px rgba(0,0,0,0.3);
  --scrim:        rgba(13,17,19,0.72);
}
:root[data-theme="light"] {
  color-scheme: light;
  --paper: #F3F4F1; --surface:#FFFFFF; --surface-2:#EAEBE6;
  --ink:#14181D; --ink-secondary:#4B5158; --muted:#868C8F;
  --border: rgba(20,24,29,0.10); --border-strong: rgba(20,24,29,0.16);
  --accent:#1E6E71; --accent-ink:#FFFFFF; --accent-soft:#DEEBEA; --accent-soft-ink:#12504F;
  --good:#0ca30c; --good-text:#006300; --warning:#fab219; --serious:#ec835a; --critical:#d03b3b;
  --series-1:#2a78d6; --series-2:#eb6834; --shadow-1: 0 1px 2px rgba(20,24,29,0.05);
  --scrim: rgba(243,244,241,0.72);
}

.rp-tabular { font-variant-numeric: tabular-nums; }

/* ---------- Page background + base type (scoped, not <body>, so we don't
   fight every un-redesigned page's own background/typography choices) ---- */
.rp-shell {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
}
/* No blanket ".rp-shell a { color: inherit }" here on purpose: with
   .rp-nav-item etc. being <a> tags, "a" in the selector made it MORE
   specific (0,1,1) than the single-class component rules (0,1,0) that are
   supposed to set their own color — inherit silently won, so every nav item
   rendered in --ink (white) instead of --ink-secondary regardless of state.
   Every link-like component below sets its own color explicitly instead. */
.rp-shell button { font-family: inherit; }
.rp-shell ::selection { background: var(--accent-soft); color: var(--accent-soft-ink); }

/* ---------- Sidebar ---------- */
.rp-sidebar {
  background: var(--surface-2);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 20px 14px;
  gap: 4px;
  /* Without this, the sidebar (a grid item next to .rp-main) stretches to
     match whichever column is taller — on any page with more content than
     one viewport-height, that's .rp-main, so .rp-sidebar-foot's
     margin-top:auto pushes "Upload data" down to the bottom of the whole
     PAGE, not the bottom of the visible viewport. Sticky pins it to the
     viewport instead, so the foot links stay reachable without scrolling
     to the very end of a long page. */
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.rp-brand { display: flex; align-items: center; gap: 10px; padding: 4px 8px 20px 8px; text-decoration: none; }
.rp-brand-mark {
  /* Real logo mark (static/images/blue_logo.svg) — keeps its own brand blue
     rather than being tinted to the app accent, same as any product that
     puts a company mark next to a product wordmark. */
  height: 22px; width: auto; flex-shrink: 0;
}
.rp-brand-name {
  font-family: var(--font-display); font-size: 1.2rem; font-weight: 600;
  letter-spacing: 0.2px; color: var(--ink);
}
.rp-nav-group { margin-bottom: 18px; }
.rp-nav-label {
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--muted); padding: 6px 10px 8px 10px;
}
.rp-nav-item {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--radius-sm);
  color: var(--ink-secondary); text-decoration: none; font-size: 0.88rem; font-weight: 500;
  position: relative;
}
.rp-nav-item svg { flex-shrink: 0; opacity: 0.85; }
.rp-nav-item:hover { background: rgba(20,24,29,0.05); color: var(--ink); text-decoration: none; }
.rp-nav-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.rp-nav-item.rp-active { background: var(--accent-soft); color: var(--accent-soft-ink); font-weight: 600; }
.rp-nav-item.rp-active svg { opacity: 1; }
.rp-nav-item.rp-locked { color: var(--muted); cursor: default; }
.rp-nav-item.rp-locked:hover { background: none; color: var(--muted); }
.rp-nav-item .rp-lock { margin-left: auto; opacity: 0.6; }
.rp-sidebar-foot { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; }

/* Upload Data — was styled identically to every other muted nav-item and
   easy to miss at the bottom of the sidebar; this makes it read as a
   real call-to-action instead of blending into the rest of the list. */
.rp-nav-item-cta {
  background: var(--accent-soft);
  color: var(--accent-soft-ink);
  font-weight: 700;
  border: 1px solid transparent;
}
.rp-nav-item-cta svg { opacity: 1; }
.rp-nav-item-cta:hover { background: var(--accent); color: var(--accent-ink); }
.rp-nav-item-cta.rp-active { background: var(--accent); color: var(--accent-ink); }

/* ---------- Topbar ---------- */
.rp-topbar {
  height: 60px; border-bottom: 1px solid var(--border); background: var(--surface);
  display: flex; align-items: center; flex-wrap: wrap; padding: 0 24px; gap: 8px 16px; position: sticky; top: 0; z-index: 50;
  font-family: var(--font-body); color: var(--ink);
}
/* flex-wrap above means a narrow viewport grows the bar taller instead of
   forcing horizontal scroll — but a wrapped row still needs somewhere to
   shrink to, so the hotel name/location truncate rather than push width. */
.rp-hotel-switch {
  display: flex; align-items: center; gap: 8px; background: none; border: 1px solid transparent;
  padding: 6px 10px; border-radius: var(--radius-sm); color: var(--ink); cursor: pointer; font-family: inherit;
  position: relative; min-width: 0; max-width: 100%;
}
.rp-hotel-switch:hover { border-color: var(--border-strong); }
.rp-hotel-switch .rp-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-hotel-switch .rp-name { font-weight: 600; font-size: 0.9rem; }
.rp-topbar-spacer { flex: 1; }

.rp-currency-select {
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--ink);
  padding: 6px 10px; border-radius: var(--radius-sm); font-size: 0.78rem; font-weight: 600;
  font-family: inherit; cursor: pointer;
}

.rp-lang-toggle { display: flex; gap: 4px; }
.rp-lang-toggle button {
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--ink-secondary);
  border-radius: var(--radius-sm); padding: 5px 8px; font-size: 0.74rem; font-weight: 700; cursor: pointer;
  font-family: inherit;
}
.rp-lang-toggle button.rp-on { background: var(--ink); color: var(--surface); border-color: var(--ink); }

.rp-theme-toggle {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border: 1px solid var(--border-strong);
  background: var(--surface); color: var(--ink-secondary); border-radius: var(--radius-sm);
  cursor: pointer; flex-shrink: 0;
}
.rp-theme-toggle:hover { color: var(--ink); border-color: var(--accent); }

.rp-avatar-btn {
  display:flex; align-items:center; gap:8px; border:1px solid var(--border-strong);
  background: var(--surface); border-radius: 999px; padding: 4px 12px 4px 4px; cursor:pointer;
  text-decoration: none; color: var(--ink); font-family: inherit;
}
.rp-avatar {
  width:26px; height:26px; border-radius:50%; background:var(--ink); color:var(--surface);
  display:flex; align-items:center; justify-content:center; font-size:0.7rem; font-weight:700;
}
.rp-avatar-btn .rp-who { font-size: 0.8rem; font-weight: 600; }
.rp-hotel-menu {
  position: absolute; top: 52px; left: 0; min-width: 200px; background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  padding: 6px; z-index: 60; display: none;
}
.rp-hotel-menu.rp-open { display: block; }
.rp-hotel-menu a, .rp-hotel-menu button {
  display: block; width: 100%; text-align: left; padding: 8px 10px; border-radius: var(--radius-sm);
  border: none; background: none; color: var(--ink); font-size: 0.84rem; cursor: pointer; text-decoration: none;
  font-family: inherit;
}
.rp-hotel-menu a:hover, .rp-hotel-menu button:hover { background: var(--paper); }
.rp-hotel-menu a.rp-active, .rp-hotel-menu button.rp-active { color: var(--accent-soft-ink); font-weight: 700; background: var(--accent-soft); }

/* ---------- Main / content ---------- */
.rp-main { display: flex; flex-direction: column; min-width: 0; }
.rp-content { padding: 28px 32px 48px 32px; max-width: 1800px; }

.rp-page-head { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 22px; gap: 20px; flex-wrap: wrap; }
.rp-page-head h1 { font-family: var(--font-display); font-size: 1.9rem; font-weight: 600; margin: 0 0 4px 0; letter-spacing: 0.1px; }
.rp-page-head .rp-sub { color: var(--ink-secondary); font-size: 0.9rem; }
.rp-freshness { display:flex; align-items:center; gap:7px; color: var(--muted); font-size: 0.8rem; padding: 6px 10px; border: 1px solid var(--border); border-radius: 999px; }
.rp-freshness .rp-dot { width:6px; height:6px; border-radius:50%; background: var(--good); box-shadow: 0 0 0 3px rgba(12,163,12,0.15); }

/* Confidence-in-pricing pill (include/rp_confidence_pill.html) — compact
   replacement for the old full-width confidence_banner.html. */
.rp-confidence-pill {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 12px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface);
}
.rp-confidence-label {
  font-size: 0.72rem; font-weight: 700; color: var(--ink-secondary);
  text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap;
}
.rp-confidence-track {
  width: 72px; height: 6px; border-radius: 3px; background: var(--border-strong);
  overflow: hidden; display: inline-block;
}
.rp-confidence-fill { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
.rp-confidence-pct { font-size: 0.78rem; font-weight: 700; color: var(--ink); }

/* ---------- KPI row ---------- */
/* auto-fit + a minmax floor, not a fixed column count: the grid itself
   decides how many 220px-minimum cards fit, reflowing all the way down to
   one column on a narrow viewport with no media query needed. Bare `1fr`
   tracks default to a content-based minimum (min-content), which is why a
   long value like "$90,681,633.06" could force the row wider than the
   viewport — minmax(220px, 1fr) overrides that with an explicit floor. */
.rp-kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; margin-bottom: 22px; }
/* position:relative unconditional here too — see the long comment on
   .rp-card above; same widget_overlay.html anchoring requirement. */
.rp-kpi-card { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px 18px; box-shadow: var(--shadow-1); }
.rp-kpi-label { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); margin-bottom: 10px; }
.rp-kpi-value { font-family: var(--font-mono); font-size: 2.2rem; font-weight: 700; letter-spacing: -0.01em; color: var(--accent); overflow-wrap: anywhere; }
.rp-kpi-sub { color: var(--muted); font-size: 0.9em; margin-top: 4px; }
.rp-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 0.72rem; font-weight: 700; padding: 3px 7px; border-radius: 999px; margin-top: 10px; }
.rp-chip.rp-good { background: rgba(12,163,12,0.12); color: var(--good-text); }
.rp-chip.rp-critical { background: rgba(208,59,59,0.12); color: var(--critical); }
.rp-chip.rp-neutral { background: rgba(134,140,143,0.15); color: var(--ink-secondary); }
.rp-chip svg { width: 11px; height: 11px; }

.rp-btn-primary {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  background: var(--accent); color: var(--accent-ink); font-size: 0.82rem; font-weight: 700;
  padding: 9px 16px; border-radius: 999px; text-decoration: none; border: none; cursor: pointer;
}
.rp-btn-primary:hover { filter: brightness(1.08); color: var(--accent-ink); text-decoration: none; }

/* ---------- Two column zone ---------- */
.rp-zone { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; align-items: start; }
/* Grid/flex items default to min-width:auto (their content's min-content
   size) — without this, a wide chart canvas or a long unwrapped value
   anywhere down the tree can stop the whole 2fr/1fr column from shrinking,
   even though the column's own track is a flexible fr unit. */
.rp-zone > * { min-width: 0; }

/* position:relative is UNCONDITIONAL here — it's the positioning context for
   include/widget_overlay.html's absolutely-positioned overlay. The macro
   renders that overlay for ANY state != "hidden" (no_upload, no_data,
   recomputing), but the caller only adds the .widget-gated modifier class
   for "no_upload" specifically (matching the original app's per-widget
   convention). Without position:relative here unconditionally, a card in
   "no_data"/"recomputing" state has no positioned ancestor, so the overlay's
   position:absolute + inset:0 escapes to the viewport and covers the whole
   page — that actually happened during redesign QA (a card in "no_data"
   painted a full-screen rgba(10,13,15,0.72) veil over the sidebar/topbar).
   overflow:hidden is deliberately NOT added here — pricing_dashboard.css's
   .widget-gated already adds its own overflow:hidden for the "no_upload"
   blur look; adding it unconditionally here too would clip calendar.js's
   own hover tooltips on cards that are never gated. */
.rp-card { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-1); min-width: 0; }
.rp-card-head { display: flex; justify-content: space-between; align-items: flex-start; padding: 18px 20px 4px 20px; }
.rp-card-title { font-size: 0.98rem; font-weight: 700; margin: 0; }
.rp-card-sub { color: var(--muted); font-size: 0.78rem; margin-top: 2px; }
.rp-legend { display: flex; gap: 14px; align-items: center; }
.rp-legend-item { display: flex; align-items: center; gap: 6px; font-size: 0.78rem; color: var(--ink-secondary); font-weight: 600; }
.rp-legend-swatch { width: 9px; height: 9px; border-radius: 2px; }

.rp-chart-wrap { padding: 6px 16px 14px 8px; position: relative; }
.rp-chart-callout {
  position: absolute; background: var(--ink); color: var(--surface); border-radius: 8px; padding: 8px 11px;
  font-size: 0.76rem; line-height: 1.5; box-shadow: 0 6px 18px rgba(0,0,0,0.18); pointer-events: none;
}
.rp-chart-callout .rp-tabular { font-weight: 700; }
.rp-chart-callout b { display:block; font-size: 0.7rem; opacity: 0.7; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 3px; }

.rp-right-rail { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

.rp-signal-list { padding: 6px 20px 16px 20px; display: flex; flex-direction: column; }
.rp-signal-row { display: flex; align-items: center; justify-content: space-between; padding: 11px 0; border-bottom: 1px solid var(--border); }
.rp-signal-row:last-child { border-bottom: none; }
.rp-signal-left { display: flex; align-items: center; gap: 10px; color: var(--ink-secondary); font-size: 0.85rem; font-weight: 600; }
.rp-signal-left svg { opacity: 0.75; }
.rp-pill { display: inline-flex; align-items: center; gap: 5px; font-size: 0.74rem; font-weight: 700; padding: 4px 9px; border-radius: 999px; }
.rp-pill.rp-good { background: rgba(12,163,12,0.12); color: var(--good-text); }
.rp-pill.rp-warning { background: rgba(250,178,25,0.16); color: #8a5b00; }
.rp-pill.rp-serious { background: rgba(236,131,90,0.16); color: #9c3f1c; }
.rp-pill.rp-neutral { background: rgba(134,140,143,0.15); color: var(--ink-secondary); }
.rp-pill svg { width: 10px; height: 10px; }

.rp-cal-wrap { padding: 4px 18px 16px 18px; }
/* Capped so day cells (aspect-ratio: 1, sized off the column's available
   width) don't balloon on wide screens — a 2fr/1fr .rp-zone right-rail can
   get quite wide on a large viewport, and without a cap each square cell
   scales up right along with it. 340px keeps cells at the ~46px they were
   designed at (matches the width this column resolved to before .rp-content
   grew to fill wide screens), centered under the full-width header. */
.rp-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; margin: 8px auto 0 auto; max-width: 340px; }
.rp-cal-dow { text-align:center; font-size: 0.66rem; color: var(--muted); font-weight: 700; padding-bottom: 4px; }
.rp-cal-day {
  aspect-ratio: 1; display:flex; flex-direction:column; align-items:center; justify-content:center;
  border-radius: 6px; font-family: var(--font-mono); font-size: 0.78rem; color: var(--ink-secondary); position: relative;
}
.rp-cal-day.rp-muted { color: var(--muted); opacity: 0.35; }
.rp-cal-day.rp-today { background: var(--accent); color: var(--accent-ink); font-weight: 700; }
.rp-cal-day .rp-mark { position:absolute; bottom:4px; width:4px; height:4px; border-radius:50%; }
.rp-cal-legend { display:flex; gap: 14px; margin-top: 10px; flex-wrap: wrap; }
.rp-cal-legend-item { display:flex; align-items:center; gap:6px; font-size: 0.74rem; color: var(--muted); }
.rp-cal-legend .rp-dot { width:6px; height:6px; border-radius:50%; }

/* Gated/locked widgets use the REAL app's existing include/widget_overlay.html
   macro + .widget-gated/.widget-gated-content/.gated-* classes (reskinned
   below), not a parallel rp-* system — that macro already encodes the real
   no_upload / no_data / recomputing states and the deep-link-to-upload
   behavior; duplicating it here would drift out of sync with it. */

@media (prefers-reduced-motion: no-preference) {
  .rp-nav-item, .rp-chip, .rp-pill { transition: background-color 0.15s ease, color 0.15s ease; }
}
@media (max-width: 980px) {
  .rp-zone { grid-template-columns: 1fr; }
  /* .rp-kpi-row no longer needs an override here — its auto-fit/minmax
     track sizing already reflows at every width without a media query. */
}
@media (max-width: 860px) {
  .rp-shell { grid-template-columns: 1fr; }
  .rp-sidebar { display: none; } /* mobile nav collapse is a follow-up; not in scope for this pass */
}

/* ============================================================================
   Reskin of the EXISTING gated-widget partial (templates/include/widget_overlay.html)
   — same selectors, new palette, sitewide. No markup changes required.
   ========================================================================= */
.widget-gated-content { filter: blur(4px); opacity: 0.5; }
.widget-gated-overlay {
  background: var(--scrim) !important;
  backdrop-filter: blur(2px);
  border-radius: inherit;
}
.gated-icon { color: var(--accent) !important; }
.gated-message { color: var(--ink) !important; }
.gated-link {
  background: var(--accent) !important;
  box-shadow: var(--shadow-1) !important;
  border-radius: 999px !important;
}
.gated-link:hover { background: var(--accent) !important; filter: brightness(1.08); box-shadow: var(--shadow-1) !important; transform: none !important; }
.gated-link-secondary { color: var(--accent) !important; border-color: var(--accent) !important; }
.gated-link-secondary:hover { background: var(--accent-soft) !important; color: var(--accent-soft-ink) !important; }

/* ============================================================================
   Kill the white frame around the shell. style3.css's #content{padding:20px}
   and mystyle.css's body{padding-bottom:100px} (plus body{background:#fafafa})
   were both designed for the OLD topnav layout and sit OUTSIDE .rp-shell —
   their light background was showing through as a border/strip around the
   dark shell. Scoped to .rp-shell-active (set on <body>/#content in
   base.html only when the shell renders) so un-redesigned pages keep their
   original spacing untouched.
   ========================================================================= */
body.rp-shell-active { padding-bottom: 0; background: var(--paper); overflow-x: hidden; }
#content.rp-shell-active { padding: 0; min-height: 0; }

/* ============================================================================
   Recomputing banner (include/recomputing_banner.html) — moved here from a
   hardcoded-hex <style> block in base.html's <head> so it uses the same
   tokens as everything else and actually adapts to dark mode instead of
   staying a fixed light-lavender gradient.
   ========================================================================= */
.recomputing-banner {
  display: flex; align-items: center; gap: 12px; padding: 8px 20px;
  background: var(--accent-soft);
  border-bottom: 1px solid var(--border-strong);
  color: var(--accent-soft-ink);
  font-size: 13px; font-weight: 500; line-height: 1.3;
}
.recomputing-banner i { color: var(--accent); font-size: 14px; }
.recomputing-banner-text { flex: 1; }
.recomputing-banner-link {
  color: var(--accent); font-weight: 600; text-decoration: none; font-size: 12px;
  padding: 4px 12px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); white-space: nowrap;
}
.recomputing-banner-link:hover { background: var(--surface); color: var(--accent-soft-ink); text-decoration: none; filter: brightness(0.97); }

/* ============================================================================
   Market page — detail list (Location Market Details), ghost button (Event/
   Price Trends), and shared loading/tooltip primitives that
   location_widgets.js / flight_price_trend.js / events_comparison.js /
   flight_price_comparison.js render via inline style="" using var(--x)
   directly (valid CSS, no JS resolution needed for plain style props — only
   Chart.js canvas colors need resolving to hex, done in the JS itself).
   ========================================================================= */
.rp-detail-list { display: flex; flex-direction: column; }
.rp-detail-row { display: flex; gap: 12px; padding: 13px 20px; border-bottom: 1px solid var(--border); position: relative; }
.rp-detail-row:last-child { border-bottom: none; }
.rp-detail-icon {
  width: 30px; height: 30px; border-radius: 8px; background: var(--paper);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0; color: var(--ink-secondary);
}
.rp-detail-body { flex: 1; min-width: 0; }
.rp-detail-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 3px; }
.rp-detail-label { font-size: 0.82rem; font-weight: 700; color: var(--ink); }
.rp-detail-status { font-size: 0.78rem; font-weight: 600; color: var(--accent); }
.rp-detail-text { font-size: 0.8rem; color: var(--ink-secondary); line-height: 1.4; }
.rp-detail-tooltip {
  display: none; position: absolute; bottom: 100%; left: 20px; z-index: 20;
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 12px; font-size: 0.82rem; width: 200px; box-shadow: 0 6px 18px rgba(0,0,0,0.15);
  margin-bottom: 8px; color: var(--ink-secondary);
}
.rp-detail-tooltip-title { font-weight: 700; color: var(--ink); margin-bottom: 6px; border-bottom: 1px solid var(--border); padding-bottom: 6px; }

.rp-ghost-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface); border: 1px solid var(--border-strong); color: var(--ink-secondary);
  font-size: 0.82rem; font-weight: 600; padding: 8px 14px; border-radius: var(--radius-sm); cursor: pointer;
}
.rp-ghost-btn:hover { border-color: var(--accent); color: var(--accent); }

.rp-widget-loading {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 20px; color: var(--accent); font-size: 0.85rem;
}
.rp-spinner {
  width: 16px; height: 16px; border: 2px solid var(--border-strong); border-top-color: var(--accent);
  border-radius: 50%; animation: rp-spin 0.8s linear infinite; display: inline-block; flex-shrink: 0;
}
@keyframes rp-spin { to { transform: rotate(360deg); } }
.rp-canvas-loading-overlay {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 10px;
  background: var(--scrim); backdrop-filter: blur(1px); z-index: 5; border-radius: inherit; color: var(--accent); font-size: 0.85rem;
}
.rp-info-panel { padding: 15px 20px; font-size: 0.85rem; color: var(--ink-secondary); }
.rp-info-panel strong { color: var(--ink); }
.rp-info-panel p { margin: 6px 0; }

/* ============================================================================
   Revenue Dashboard (templates/revenue.html + include/revenue/*) — compact
   KPI numbers living inside an already-carded widget (Revenue Metrics,
   RevPAR, ADR), so they deliberately have no card chrome of their own.
   Revenue Changes reuses .rp-signal-list/.rp-pill directly instead. */
/* Same auto-fit/minmax reflow as .rp-kpi-row above. The -2col variant just
   uses a taller floor so a right-rail-width card settles on ~2 columns
   instead of the full-width card's ~4, without a hardcoded count either way. */
.rp-mini-kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 14px; padding: 4px 20px 18px 20px; }
.rp-mini-kpi-row.rp-mini-kpi-row-2col { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.rp-mini-kpi { display: flex; flex-direction: column; gap: 5px; }
.rp-mini-kpi-label { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.rp-mini-kpi-value { font-family: var(--font-mono); font-size: 1.35rem; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; overflow-wrap: anywhere; }
.rp-mini-kpi-value.rp-loading { color: var(--muted); }
.rp-loading { animation: rp-pulse 1.5s ease-in-out infinite; }
@keyframes rp-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }

.rp-stale-banner {
  display: flex; align-items: flex-start; gap: 8px; margin: 0 20px 14px 20px;
  padding: 10px 14px; border-radius: var(--radius-sm); background: rgba(250,178,25,0.12);
  border-left: 3px solid var(--warning); color: #8a5b00; font-size: 0.8rem; line-height: 1.4;
}
.rp-stale-banner strong { font-weight: 700; }
@media (prefers-color-scheme: dark) { .rp-stale-banner { color: #f0c674; } }
:root[data-theme="dark"] .rp-stale-banner { color: #f0c674; }
:root[data-theme="light"] .rp-stale-banner { color: #8a5b00; }

/* Scoped reskin of info_widget.js's shared renderInfoWidget/showWidgetLoading
   output — targeted by container id (not a blanket class override) so
   un-redesigned pages using the same shared classes (Pricing, Oversight,
   Competitors) are unaffected. Structural bits (.details-collapsed/
   .details-expanded collapse mechanics) are colorless and stay as defined
   in pricing_dashboard.css. */
#info-list .info-list-item,
#revpar-info-list .info-list-item,
#adr-info-list .info-list-item {
  border-bottom-color: var(--border);
}
#info-list .info-list-label,
#revpar-info-list .info-list-label,
#adr-info-list .info-list-label {
  color: var(--ink-secondary);
}
#info-list .info-list-value,
#revpar-info-list .info-list-value,
#adr-info-list .info-list-value {
  color: var(--ink);
}
#info-list .placeholder-value,
#revpar-info-list .placeholder-value,
#adr-info-list .placeholder-value {
  color: var(--muted) !important;
  animation: rp-pulse 1.5s ease-in-out infinite;
}
#info-list .no-data-value,
#revpar-info-list .no-data-value,
#adr-info-list .no-data-value {
  color: var(--muted) !important;
}

/* ============================================================================
   Competitors page (templates/competitors.html) — manual price-entry form,
   data-collection status line/token box, date range input.
   #info-list here renders info_widget.js's "classic" (<li>) style, not the
   "modern" .info-list-item style Revenue uses above — different generated
   markup, same shared function, same scoped-by-id reskin approach. */
#info-list { list-style: none; padding: 0; margin: 0; }
#info-list li {
  padding: 12px 0; border-bottom: 1px solid var(--border);
  display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) 40px;
  align-items: start; gap: 12px; min-height: 40px;
}
#info-list li:last-child { border-bottom: none; }
#info-list .variable-description { grid-column: 1; font-weight: 600; color: var(--ink); word-wrap: break-word; overflow-wrap: break-word; min-width: 0; }
#info-list .variable-value { grid-column: 2; text-align: center; font-size: 1.05em; color: var(--ink-secondary); min-width: 0; word-wrap: break-word; overflow-wrap: break-word; }
#info-list .variable-value.no-data-value,
#info-list .variable-value.placeholder-value { color: var(--muted) !important; }
#info-list .placeholder-value { animation: rp-pulse 1.5s ease-in-out infinite; }

/* minmax(0, 1fr), not bare 1fr — a bare fr track's implicit minimum is its
   content's min-content size, so a long competitor name would stop the row
   from shrinking below that width. minmax(0, 1fr) lets it actually shrink. */
.rp-form-row { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 10px; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--border); }
.rp-form-row label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-form-row:last-of-type { border-bottom: none; }
.rp-form-row label { font-weight: 600; color: var(--ink); font-size: 0.85rem; }
/* input.rp-form-input (not just .rp-form-input) so this beats mystyle.css's
   input[type="text"]/input[type="password"] rules — an attribute selector
   combined with a type selector outweighs a bare class selector, so without
   the tag qualifier here mystyle.css's border:none silently wins even
   though rp_shell.css loads after it (found on the Support page's Subject
   field: identical specificity fixes it via source order, but attribute
   selectors need the extra type-selector weight to even tie). */
.rp-form-input, .rp-form-select, .rp-form-textarea,
input.rp-form-input, select.rp-form-select, textarea.rp-form-textarea {
  width: 100%; padding: 7px 9px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); font-family: inherit; font-size: 0.85rem;
}
.rp-form-textarea { min-height: 70px; font-family: var(--font-mono); font-size: 0.8rem; }
.rp-status-line { font-size: 0.85rem; color: var(--ink-secondary); padding: 9px 12px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); margin-bottom: 12px; }
.rp-code-box { flex: 1 1 320px; min-width: 0; overflow-wrap: anywhere; padding: 8px 10px; background: var(--ink); color: #68d391; border-radius: var(--radius-sm); font-size: 0.8rem; font-family: var(--font-mono); }
.rp-date-input {
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--ink);
  padding: 9px 12px; border-radius: var(--radius-sm); font-size: 0.84rem; font-family: var(--font-mono);
  cursor: pointer; width: 100%; text-align: left;
}
.rp-date-input:hover { border-color: var(--accent); }

/* ============================================================================
   Calendar (static/js/calendar.js — initCalendar). Real component: month
   nav, live event/holiday fetch, hover tooltips, click-to-select, an
   event-cards list. Extends the .rp-cal-grid/.rp-cal-day pattern already
   used for the day cells themselves (same classes, same visual language on
   both Home's plain instance and Market's full one) with the pieces that
   pattern didn't need yet: navigation, multi-event marks, tooltip, cards.
   ========================================================================= */
.rp-cal2-header {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 0 4px 12px 4px; flex-wrap: wrap;
}
.rp-cal2-nav {
  width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--ink-secondary);
  border-radius: var(--radius-sm); cursor: pointer; font-size: 0.7rem; flex-shrink: 0;
}
.rp-cal2-nav:hover { color: var(--accent); border-color: var(--accent); }
.rp-cal2-title { display: flex; align-items: center; gap: 6px; font-weight: 700; color: var(--ink); font-size: 0.88rem; }
.rp-cal2-month-select {
  border: none; background: none; color: var(--ink); font-weight: 700; font-size: 0.88rem;
  cursor: pointer; font-family: inherit; padding: 2px 4px; border-radius: var(--radius-sm);
}
.rp-cal2-month-select:hover { background: var(--paper); }
.rp-cal2-year { font-variant-numeric: tabular-nums; color: var(--ink); }

.rp-cal2-body { position: relative; }
.rp-cal2-spinner-overlay {
  position: absolute; inset: 0; display: none; align-items: center; justify-content: center;
  background: var(--scrim); backdrop-filter: blur(1px); z-index: 6; border-radius: var(--radius-sm);
}

.rp-cal-day.rp-has-marks { cursor: pointer; }
.rp-cal-day.rp-has-marks:hover { background: var(--paper); }
.rp-cal-day.rp-today.rp-has-marks:hover { background: var(--accent); filter: brightness(1.05); }
.rp-cal-day.rp-selected { box-shadow: inset 0 0 0 2px var(--accent); }
.rp-cal-day-num { line-height: 1.2; }
.rp-cal-day-marks { display: flex; gap: 2px; justify-content: center; align-items: center; height: 6px; margin-top: 1px; }
.rp-cal-day-marks .rp-mark { position: static; width: 4px; height: 4px; border-radius: 50%; flex-shrink: 0; }

.rp-cal-tooltip {
  position: fixed; z-index: 1000; max-width: 260px;
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 10px 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.18); font-size: 0.8rem; color: var(--ink-secondary);
}
.rp-cal-tooltip-date { font-weight: 700; color: var(--ink); margin-bottom: 6px; }
.rp-cal-tooltip-item { padding: 4px 0; border-bottom: 1px solid var(--border); }
.rp-cal-tooltip-item:last-child { border-bottom: none; }
.rp-cal-tooltip-item-title { font-weight: 700; }
.rp-cal-tooltip-item-sub { color: var(--muted); font-size: 0.76rem; margin-top: 1px; }

.rp-cal-cards { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.rp-cal-cards-heading { font-size: 0.82rem; font-weight: 700; color: var(--ink); margin-bottom: 10px; }
.rp-cal-controls { display: flex; gap: 10px; align-items: center; margin-top: 12px; }

/* Every event/holiday card for the month lives in one bounded, scrollable
   list — a month with many events/holidays scrolls internally instead of
   dumping an open-ended number of rows into page flow and pushing the
   whole page down. Same "cap it, let it scroll" idea as .rp-detail-list,
   just with an explicit max-height since this list is open-ended. */
.rp-cal-scroll-list {
  display: flex;
  flex-direction: column;
  max-height: 400px;
  overflow-y: auto;
}

/* ============================================================================
   Upload Data page (templates/data_connection.html) — data-sources table +
   status/info banners. */
.rp-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.rp-table th {
  text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--border-strong);
  color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700;
}
.rp-table td { padding: 10px 12px; border-bottom: 1px solid var(--border); color: var(--ink-secondary); }
.rp-table tr:last-child td { border-bottom: none; }

.rp-banner {
  display: flex; align-items: flex-start; gap: 10px; margin-bottom: 16px;
  padding: 12px 16px; border-radius: var(--radius-sm); border-left: 3px solid var(--border-strong);
  background: var(--surface-2); color: var(--ink-secondary); font-size: 0.85rem; line-height: 1.5;
}
.rp-banner strong { color: var(--ink); }
.rp-banner.rp-banner-info { border-left-color: var(--accent); background: var(--accent-soft); color: var(--accent-soft-ink); }
.rp-banner.rp-banner-warning { border-left-color: var(--warning); background: rgba(250, 178, 25, 0.12); color: #8a5b00; }
.rp-banner.rp-banner-success { border-left-color: var(--good); background: rgba(12, 163, 12, 0.1); color: var(--good-text); }
.rp-banner.rp-banner-danger { border-left-color: var(--critical); background: rgba(208, 59, 59, 0.1); color: var(--critical); }

.rp-drop-zone {
  border: 2px dashed var(--accent); border-radius: var(--radius); background: var(--accent-soft);
  padding: 48px 24px; text-align: center; margin-bottom: 20px; cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.rp-drop-zone.rp-drop-zone-active { background: var(--surface-2); border-color: var(--accent); }
.rp-drop-zone-icon { color: var(--accent); margin-bottom: 12px; }
.rp-drop-zone-title { color: var(--ink); font-size: 0.95rem; font-weight: 600; margin-bottom: 4px; }
.rp-drop-zone-sub { color: var(--muted); font-size: 0.8rem; margin-bottom: 20px; }
.rp-drop-zone-filename { color: var(--ink); font-weight: 600; font-size: 0.85rem; }
.rp-drop-zone-filename.rp-drop-zone-filename-selected { color: var(--good-text); }
