/* ==========================================================================
   HydrologyHub platform stylesheet
   --------------------------------------------------------------------------
   The shared look-and-feel for every *.hydrologyhub.com app. One file with
   two parts:

   Part 1, platform identity (sections 1-11): color tokens, Bootstrap
   overrides, navbar, hover dropdowns, welcome card, footer, dashboard iframe
   layout, About page, tooltip/popover styling, Dash core component theming,
   and Bootstrap's own buttons, tabs, cards, and row gutters restyled to the
   platform look (section 11), so dbc components need no extra class.

   Part 2, reusable widgets (sections 12-17): dashboard card extras, round
   help buttons, modal windows, Leaflet controls, dataset selector, map legend,
   forms and images, auto-grid. Rules for a widget match nothing until an app
   uses its class, so an app that doesn't use a widget isn't affected.

   Consolidated from:
     - flask_dash_base/src/website/assets/supplement.css   (template)
     - OWRD_Precip_WebApp/src/website/assets/supplement.css (Oregon Extreme Precip)
     - DCP_Tool/src/website/assets/supplement.css           (Texas Reservoir Drought Monitor)

   See hydrologyhub-assets.md (next to the template README) for the full
   class catalog, the version history, and what each version changes for
   the apps that copy this file.

   Source of truth: hydrologyhub repo, flask_dash_base/src/website/assets/.
   Copy into apps unchanged; put app overrides in supplement.css.

   Load order: bootstrap.css -> hydrologyhub.css -> the app's own
   supplement.css (app-specific, wins last). Flask's base.html links them in
   that order. Dash loads assets/ alphabetically, which gives the same order.
   See "CSS and JS layers" in the template README.
   ========================================================================== */
/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root,
[data-bs-theme=light] {
  /* Platform palette (WEST colors). Use --hh-* in new CSS. */
  --hh-blue: #3f50a0;            /* dark blue  (63, 80, 160)  */
  --hh-blue-rgb: 63, 80, 160;
  --hh-light-blue: #2fa4e7;      /* light blue (47, 164, 231) */
  --hh-light-blue-rgb: 47, 164, 231;
  --hh-green: #56803d;           /* green      (86, 128, 61)  */
  --hh-green-rgb: 86, 128, 61;

  /* Neutrals (from DCP_Tool's shell). */
  --hh-ink: #354052;
  --hh-muted: #5e6d81;
  --hh-muted-strong: #52627a;
  --hh-border: #dbe3ed;
  --hh-page-bg: #f7f9fc;
  --hh-card-shadow: 0 0.2rem 0.75rem rgba(38, 56, 85, 0.09);

  /* Layout. --hh-header-height is measured by hydrologyhub.headerHeight.init()
     (hydrologyhub.js); rules fall back to the navbar minimum before it runs. */
  --hh-navbar-min-height: 7vh;
  --hh-logo-height: 8vh;
  --hh-welcome-logo-max: 420px;
  --hh-footer-logo-max: 250px;

  /* Stacking: overlays must sit above Leaflet controls (z-index 1000). */
  --hh-z-overlay: 20000;   /* welcome card / modals */
  --hh-z-popover: 20010;   /* tooltips, popovers, date-picker popups */

  /* Bootstrap overrides shared by all current apps. --bs-primary-rgb matches
     --bs-primary since 0.5.0 (it was light blue before), so .text-primary,
     .bg-primary, .border-primary, and dbc color="primary" render dark blue.
     Bootstrap's --bs-tertiary-color(-rgb) are no longer overridden; the green
     accent is var(--hh-green). */
  --bs-primary: #3F50A0;
  --bs-heading-color: #3F50A0;
  --bs-primary-rgb: 63, 80, 160;
  --bs-link-color: #3F50A0;
  --bs-link-hover-color: #2fa4e7;
  --bs-link-color-rgb: 63, 80, 160;
  --bs-link-hover-color-rgb: 47, 164, 231;
  --bs-sliders-color-rgb: 86, 128, 61;
}

.bg-primary {
  --bs-bg-opacity: 1;
  background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;
}

.bg-secondary {
  --bs-bg-opacity: 1;
  background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;
}


/* --------------------------------------------------------------------------
   2. Page shell
   <body class="main-container hh-shell {% block body_class %}{% endblock %}">
     <header class="sticky-top bg-white border-bottom"> navbar </header>
     <main class="container-fluid ..."> ... </main>
     <footer class="hh-footer text-center"> ... </footer>
   </body>
   -------------------------------------------------------------------------- */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  overflow-x: hidden;            /* no horizontal page scrollbar */
}

.main-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  position: relative;            /* positioning context */
}

.main-container > main {
  flex: 1 0 auto;                /* pushes the footer to the bottom */
}

/* Tinted page background and ink color. The platform default since 0.3.0:
   put .hh-shell on <body> in both base.html and dash_app_index.txt. Without
   it, pages render on plain white. (.dcp-shell is DCP_Tool's older name.) */
body.hh-shell,
body.dcp-shell {
  color: var(--hh-ink);
  background: var(--hh-page-bg);
}

/* Bootstrap's light-grey surfaces wash out against the tinted background,
   so the About sidebar and secondary alerts become white with the
   platform card border. */
.hh-shell .alert-secondary {
  --bs-alert-bg: var(--bs-white);
  --bs-alert-border-color: var(--hh-border);
}

html, body {
  scroll-behavior: auto;
  scroll-padding-top: 100px;     /* keep sticky header clear of #anchor targets */
}

body.overflow-auto {
  overflow-y: auto;
}

body.overflow-hidden {
  overflow-y: hidden;
}

.text-disclaimer {
  color: var(--bs-danger);
}


/* --------------------------------------------------------------------------
   3. Navbar
   Markup contract (see CLAUDE.md "Navbar collapse layout contract"):
   <nav class="navbar navbar-expand-xl main-navbar">
     <div class="container-fluid d-flex justify-content-between figure-logo-container">
       <a class="navbar-brand navbar-brand-slot">App name</a>        (1)
       <button class="navbar-toggler">...</button>                  (2)
       <div class="collapse navbar-collapse navbar-center">
         <ul class="navbar-nav mx-auto navbar-nav-center">...</ul>
       </div>
       <div class="navbar-logo-slot d-flex">                         (3)
         <img class="figure-logo img-fluid"> <span class="west-wordmark d-none">
       </div>
     </div>
   </nav>
   Exactly three visible flex children while collapsed, so the toggler centers.
   -------------------------------------------------------------------------- */
.navbar {
  border-bottom: 2px solid var(--bs-primary);
  --bs-navbar-padding-y: 0rem;
  min-height: var(--hh-navbar-min-height);
}

.navbar-collapse {
  flex-basis: 100%;
  flex-grow: 1;
  align-items: center;
  padding: 1%;
  background-color: white;
}

.main-navbar {
  position: relative;
  justify-content: flex-start;
}

/* Desktop: center the nav links between the app name and the logo. */
@media (min-width: 1200px) {
  .main-navbar .navbar-center {
    position: absolute;
    left: 50%;
    width: max-content;
    transform: translateX(-50%);
    flex: 0 0 auto;
    padding: 0;
    background-color: transparent;
  }

  .main-navbar .navbar-nav-center {
    align-items: center;
  }
}

/* Application name in the navbar (from DCP_Tool; the template uses the class
   in base.html but its stylesheet never defined it). */
.navbar-brand-slot {
  max-width: min(48vw, 510px);
  color: var(--hh-blue);
  font-size: clamp(1rem, 1.6vw, 1.35rem);
  font-weight: 700;
  line-height: 1.2;
  white-space: normal;
}

.navbar-brand-slot:hover {
  color: var(--hh-light-blue);
}

.nav-link.active {
  border-bottom: 2px solid var(--hh-green);
  border-top: 2px solid var(--hh-green);
  height: 100%;
  width: auto;
  position: relative;
  font-weight: 600;
}

.figure-logo {
  margin-bottom: 0.01rem;
  line-height: 1;
  width: auto;
  height: var(--hh-logo-height);
}

.figure-logo-container {
  display: flex;
  align-items: center;
  /* Below navbar-expand-xl Bootstrap lets .navbar children wrap. If the logo
     slot wraps to its own row, space-between pushes the toggler to the far
     right instead of the middle. nowrap keeps all three on one row; the brand
     text still wraps inside its own box. (Fix from DCP_Tool.) */
  flex-wrap: nowrap;
}

/* Text fallback shown when the partner logo image fails to load. */
.west-wordmark {
  color: var(--hh-blue);
  font-family: Arial, sans-serif;
  font-size: clamp(1.4rem, 2vw, 2rem);
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1;
}


/* --------------------------------------------------------------------------
   4. Hover dropdown menus in the navbar
   <li class="nav-item dropdown">
     <a class="nav-link btn mx-1 mx-sm-2 mx-md-3">Section</a>
     <ul class="dropdown-menu"><li><a class="dropdown-item">...</a></li></ul>
   </li>
   Menus open on hover, are centered under their parent on desktop, and hide
   Bootstrap's caret.
   -------------------------------------------------------------------------- */
.dropdown-menu {
  background-color: rgba(255, 255, 255, 0.9);
  text-align: center;
}

@media (min-width: 1200px) {
  .dropdown-menu {
    left: 50%;
    transform: translateX(-50%);
  }
}

.nav-item.dropdown .dropdown-menu {
  display: none;
}

.nav-item.dropdown:hover .dropdown-menu,
.nav-item.dropdown.active .dropdown-menu {
  display: block;
  margin-top: 0;
}

.nav-link.dropdown-toggle::after {
  display: none;
}

.dropdown-item {
  display: block;
  width: 100%;
  padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);
  clear: both;
  font-weight: 400;
  color: var(--bs-dropdown-link-color);
  text-align: inherit;
  text-decoration: none;
  white-space: nowrap;
  background-color: transparent;
  border: 0;
  border-radius: var(--bs-dropdown-item-border-radius, 0);
}

.dropdown-item:hover,
.dropdown-item:focus {
  color: var(--bs-dropdown-link-color);
  background-color: rgba(var(--bs-link-hover-color-rgb), 0.3);
}

.dropdown-item.active,
.dropdown-item:active {
  color: var(--bs-dropdown-link-active-color);
  text-decoration: none;
  background-color: rgba(var(--bs-link-hover-color-rgb));
}

.dropdown-item.disabled,
.dropdown-item:disabled {
  color: var(--bs-dropdown-link-disabled-color);
  pointer-events: none;
  background-color: transparent;
}


/* --------------------------------------------------------------------------
   5. Welcome (entry) card
   <div class="hh-welcome-overlay" id="hh-welcome" role="dialog" aria-modal="true" aria-labelledby="welcome-title" tabindex="-1">
     <div class="modal-content-welcome">
       <img class="welcome-logo" src=".../HydrologyHub_Logo_Blues4.png" alt="HydrologyHub">
       <h4 id="welcome-title">Welcome to ... on HydrologyHub</h4> <hr> ...
       <h6 class="text-disclaimer">Disclaimer</h6> ...
       <button class="btn btn-primary hh-btn--dismiss">Accept and Dismiss</button>
     </div>
   </div>
   The overlay is scoped to the welcome card since 0.5.0. Before that, every
   .modal was restyled, including dbc.Modal. Markup that still uses
   <div class="modal"> around .modal-content-welcome keeps working through
   the :has() selector, but move it to .hh-welcome-overlay.
   -------------------------------------------------------------------------- */
.hh-welcome-overlay,
.modal:has(> .modal-content-welcome) {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.1);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: var(--hh-z-overlay);
}

/* Bootstrap / dbc.Modal keep Bootstrap's own layout, raised above Leaflet
   controls and map overlays (OWRD's dataset selector sits at 1200). */
.modal {
  --bs-modal-zindex: var(--hh-z-overlay);
}

.modal-backdrop {
  --bs-backdrop-zindex: calc(var(--hh-z-overlay) - 5);
}

.modal-content-welcome {
  background-color: white;
  padding: 2rem;
  border-radius: 10px;
  border: 5px solid var(--bs-primary);
  text-align: center;
  margin: auto;
  width: 90%;
  font-size: 1.1rem;
  overflow: auto;
  overflow-y: auto;
  max-height: calc(100vh - 40px);   /* fits short landscape screens */
}

.modal-content-welcome h4 {
  font-size: 1.5rem;
}

.modal-content-welcome h6 {
  font-size: 1.2rem;
}

.welcome-logo {
  display: block;
  width: min(100%, var(--hh-welcome-logo-max));
  height: auto;
  margin: 0 auto 1rem;
}


/* --------------------------------------------------------------------------
   6. Footer
   One HydrologyHub logo footer per scrolling document:
     Flask pages:  <footer class="hh-footer text-center"><img class="footer-logo"></footer>
     Dash iframe:  <body class="hh-dash-document hh-shell"> {%app_entry%} <footer class="hh-footer ...">
   Use the hh-* names. The dcp-* names (inherited from DCP_Tool) are
   deprecated aliases kept so older markup still renders; they will be
   removed in a later version.
   -------------------------------------------------------------------------- */
.hh-footer,
.dcp-footer {
  flex-shrink: 0;
  margin-top: 0.5rem;
  padding: 0.5rem 0.75rem;
  border-top: 1px solid var(--hh-border);
  background: #fff;
}

.footer-logo {
  display: block;
  width: min(100%, var(--hh-footer-logo-max));
  height: auto;
  margin: 0 auto;
}

/* Dash index document: footer sits after {%app_entry%} at the bottom. */
.hh-dash-document,
.dcp-dash-document {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.hh-dash-document > .hh-footer,
.hh-dash-document > .dcp-footer,
.dcp-dash-document > .hh-footer,
.dcp-dash-document > .dcp-footer {
  margin-top: auto;
}


/* --------------------------------------------------------------------------
   7. Dashboard page (Flask page that embeds the Dash iframe)
   <body class="main-container hh-shell hh-dashboard-page">
     <main class="container-fluid"><div class="hh-dashboard-content">
       <iframe id="dash-iframe" class="hh-dash-iframe" src="/dash_app/"></iframe>
     </div></main>
   (no outer footer on this route; the Dash document draws it)
   The page is fixed at viewport height; the iframe's own document scrolls.
   Use the hh-* names. analysis-page/-content/-iframe are deprecated aliases
   (the template's older names). DCP_Tool's dcp-drought-page/-content and
   dcp-dash-iframe are not defined here; move that markup to the hh-* names.
   -------------------------------------------------------------------------- */
body.analysis-page,
body.hh-dashboard-page {
  height: 100vh;
  overflow: hidden;
}

.analysis-page > main,
.hh-dashboard-page > main {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  padding: 0.25rem 0.25rem 0 !important;
}

.analysis-content,
.hh-dashboard-content {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}

.analysis-iframe,
.hh-dash-iframe {
  display: block;
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  border: 0;
  background: #fff;
}


/* --------------------------------------------------------------------------
   8. About / documentation pages
   Sidebar nav (col-md-2, .sidebar) + content column (.about-col) of
   .about-card sections, each <section id="..."> highlighted when targeted.
   -------------------------------------------------------------------------- */
/* About layout. .about-page goes on the content wrapper (template, OWRD) or on
   <body> (DCP_Tool); every rule below works with either placement.

   clip, not hidden: overflow: hidden makes an element a scroll container, and
   a scroll-container ancestor stops the sticky .sidebar from sticking. The
   compound selector beats .container-fluid-cust's overflow: hidden. */
.about-page,
.container-fluid-cust.about-page {
  overflow-x: clip;
  overflow-y: visible;
}

/* Run the sidebar/content row from the header's bottom edge to the footer:
   no top or bottom padding on <main>, and no top margin on the footer. The
   top padding is zeroed here, not on the wrapper, so it also clears app
   padding (DCP_Tool's .dcp-shell-main) and the template's py-3 utility. */
main:has(.about-page),
body.about-page > main {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

/* Let the sidebar column reach the page edge. Bootstrap's .row overhangs
   its parent by half a gutter, and overflow-x: clip cuts that overhang off,
   leaving a strip of page background beside the white sidebar column. So
   drop <main>'s side padding and the sidebar row's negative side margins. */
main:has(.about-page),
body.about-page > main {
  padding-left: 0;
  padding-right: 0;
}

/* Fill the space between the header and the footer, however short the page.
   <main> and the About wrapper grow to the viewport, and the row grows to fill
   them, so the sidebar and content column always run the full height.

   The row also reaches 1px under the header's and the footer's borders. Those
   borders go transparent on About pages, and background-clip: padding-box keeps
   the header's and footer's fills off the border line, so the column's blue
   sides meet the navbar's blue rule and the footer's edge with no gap. */
main:has(.about-page),
body.about-page > main {
  display: flex;
  flex-direction: column;
}

.container-fluid-cust.about-page {
  display: flex;
  flex-direction: column;
  flex: 1 0 auto;
  height: auto;
}

.about-page .row:has(.sidebar) {
  flex: 1 0 auto;
  margin-left: 0;
  margin-right: 0;
  margin-top: calc(-1 * var(--bs-border-width));
  margin-bottom: calc(-1 * var(--bs-border-width));
}

body:has(.about-page) > header,
body.about-page > header {
  /* !important: the header's border-bottom utility class sets its color that way. */
  border-bottom-color: transparent !important;
  background-clip: padding-box;
}

main:has(.about-page) ~ .hh-footer,
main:has(.about-page) ~ .dcp-footer,
body.about-page > .hh-footer,
body.about-page > .dcp-footer {
  margin-top: 0;
  border-top-color: transparent;
  background-clip: padding-box;
}

/* Sidebar column painted full height. White on the tinted shell, where
   Bootstrap's light grey disappears. The sidebar is hidden below md. */
@media (min-width: 768px) {
  .hh-shell .about-sidebar-col,
  .hh-shell .sidebar {
    background: var(--bs-white);
  }
}

.sidebar {
  position: sticky;
  top: var(--hh-header-height, var(--hh-navbar-min-height));
  width: 100%;
  max-height: calc(100vh - var(--hh-header-height, var(--hh-navbar-min-height)));
  overflow-y: auto;
  background: rgba(var(--bs-light-rgb), 1);
  z-index: 3;
}

@media (max-width: 767.98px) {
  .sidebar {
    position: static;
    max-height: none;
  }
}

.content-section {
  height: auto;
  min-height: 0;
  z-index: 2;
}

.container-fluid-cust {
  height: 100%;
  position: relative;
  overflow-x: hidden;
  overflow-y: hidden;
}

.about-col {
  width: 83.333333%;              /* col-10 */
  margin-left: auto;
  margin-right: auto;
  padding-left: 0;
  padding-right: 0;
  border-left: 1px solid var(--bs-primary);
  border-right: 1px solid var(--bs-primary);
}

.about-card {
  --bs-card-spacer-y: 1rem;
  --bs-card-spacer-x: 1rem;
  --bs-card-title-spacer-y: 0.5rem;
  --bs-card-border-width: var(--bs-border-width);
  --bs-card-border-radius: var(--bs-border-radius);
  --bs-card-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width)));
  --bs-card-cap-padding-y: 0.5rem;
  --bs-card-cap-padding-x: 1rem;
  --bs-card-cap-bg: rgba(var(--bs-body-color-rgb), 0.03);
  --bs-card-bg: var(--bs-body-bg);
  --bs-card-img-overlay-padding: 1rem;
  --bs-card-group-margin: 0.75rem;
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  color: var(--bs-body-color);
  word-wrap: break-word;
  background-color: var(--bs-card-bg);
  background-clip: border-box;
  border: var(--bs-card-border-width) solid var(--bs-primary);
  border-radius: var(--bs-card-border-radius);
  width: 95%;
  margin: 2rem auto;
  padding: 1rem;
}

.about-section {
  text-align: center;
}

section:target {
  outline: 4px solid var(--hh-green);
  background-color: var(--bs-white);
}

/* Plain centered content card for simple Flask pages (DCP_Tool .dcp-page-card). */
.hh-page-card {
  max-width: 920px;
  margin: 1.5rem auto;
  padding: 1.5rem;
  border: 1px solid var(--hh-border);
  border-radius: 0.5rem;
  background: #fff;
  box-shadow: 0 0.25rem 0.75rem rgba(38, 56, 85, 0.08);
}

.hh-page-card h1 {
  margin-bottom: 0.25rem;
  color: var(--hh-blue);
  font-size: 1.6rem;
  font-weight: 700;
}


/* --------------------------------------------------------------------------
   9. Tooltips and popovers (dbc.Tooltip / dbc.Popover)
   Light background, green border and arrow, wide enough for short lists,
   fixed-position so showing one does not resize the page.
   -------------------------------------------------------------------------- */
.tooltip-inner {
  background-color: rgba(var(--bs-light-rgb), 1);
  color: black;
  border: 2px solid var(--hh-green);
  max-width: 30vw !important;
  white-space: normal;
  text-align: left;
  font-size: 1rem;
}

.tooltip-inner ul,
.tooltip-inner ol {
  padding-left: 1.2em;
  margin: 0;
  text-align: left;
  list-style-position: outside;
}

.bs-tooltip-top .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before {
  border-top-color: var(--bs-success);
}

.bs-tooltip-end .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before {
  border-right-color: var(--bs-success);
}

.bs-tooltip-bottom .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before {
  border-bottom-color: var(--bs-success);
}

.bs-tooltip-start .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {
  border-left-color: var(--bs-success);
}

.bs-tooltip-auto,
.bs-tooltip-top,
.bs-tooltip-end,
.bs-tooltip-bottom,
.bs-tooltip-start {
  position: fixed !important;
  z-index: var(--hh-z-popover) !important;
}

.popover {
  max-width: 50vw;
  z-index: var(--hh-z-popover) !important;
}

.popover-header {
  font-size: var(--bs-popover-header-font-size);
  color: var(--hh-green);
  font-weight: bold;
}


/* --------------------------------------------------------------------------
   10. Dash core component theming
   -------------------------------------------------------------------------- */
/* dcc.Slider / dcc.RangeSlider (Dash 3) track + handle color: platform green. */
.dash-slider-root {
  --Dash-Fill-Interactive-Strong: rgb(var(--bs-sliders-color-rgb));
  --Dash-Fill-Disabled: rgba(var(--bs-sliders-color-rgb), 0.2);
}

/* dcc.DatePicker* popups default to z-index 500, which puts them under
   Leaflet's controls (1000) when a map shares the card. (From DCP_Tool.) */
.dash-datepicker-content {
  z-index: var(--hh-z-popover) !important;
}


/* --------------------------------------------------------------------------
   11. Bootstrap components: buttons, tabs, cards, row gutters
   Bootstrap's own classes take the platform look through Bootstrap 5.3's
   component variables, so dbc components look right as written:
     dbc.Button("Run", color="primary", outline=True)   outlined default
     dbc.Button("Save", color="primary")                filled
     dbc.Tabs([...]), dbc.Card([dbc.CardHeader(...), dbc.CardBody(...)])
   Appearance only (color, border, radius, shadow, weight, padding); nothing
   here changes display or positioning. Other button colors (secondary,
   danger, link, ...) keep the Cerulean look.

   Deprecated aliases, to be removed in 0.7.0: hh-btn, hh-btn--primary,
   hh-card, hh-card-header, hh-dashboard-tabs, hh-gutter-rows. They render as
   in 0.5.0, on Bootstrap elements and on plain ones (html.Button, html.Div).
   -------------------------------------------------------------------------- */
/* Contrast (WCAG AA needs 4.5:1 for text): --hh-btn-outline-text on white is
   about 7.3:1, black on --hh-light-blue about 7.6:1. Light-blue text on white
   (Cerulean's outline look) is about 2.8:1, and white on light blue is too. */
:root {
  /* Fill on hover. A darker shade of --hh-light-blue. */
  --hh-btn-hover-bg: #288bc4;
  /* Text on filled buttons. */
  --hh-btn-text: #000000;
  /* Text and border on the outlined default. */
  --hh-btn-outline-text: var(--hh-blue);
  /* Row gutter in the Dash document; also the gap between cards. Matches
     Bootstrap spacer-1. */
  --hh-card-gutter: 0.25rem;
}

/* Buttons: 2px border, roomier padding, light-blue focus ring, and no
   Cerulean text shadow. */
.btn-primary,
.btn-outline-primary,
.hh-btn {
  --bs-btn-padding-y: 0.5rem;
  --bs-btn-padding-x: 1rem;
  --bs-btn-border-width: 2px;
  --bs-btn-focus-shadow-rgb: var(--hh-light-blue-rgb);
  text-shadow: none;
}

/* Bootstrap's .btn-sm sets its padding with the same specificity, earlier,
   so restore it for dbc size="sm". (.btn-lg's padding is the same as ours.) */
.btn-sm:is(.btn-primary, .btn-outline-primary) {
  --bs-btn-padding-y: 0.25rem;
  --bs-btn-padding-x: 0.5rem;
}

/* Outlined default: dark-blue text and border on white; light-blue fill
   with black text on hover and press. */
.btn-outline-primary,
.hh-btn {
  --bs-btn-color: var(--hh-btn-outline-text);
  --bs-btn-bg: var(--bs-white);
  --bs-btn-border-color: var(--hh-btn-outline-text);
  --bs-btn-hover-color: var(--hh-btn-text);
  --bs-btn-hover-bg: var(--hh-light-blue);
  --bs-btn-hover-border-color: var(--hh-light-blue);
  --bs-btn-active-color: var(--hh-btn-text);
  --bs-btn-active-bg: var(--hh-light-blue);
  --bs-btn-active-border-color: var(--hh-light-blue);
  --bs-btn-disabled-color: var(--hh-btn-outline-text);
  --bs-btn-disabled-bg: var(--bs-white);
  --bs-btn-disabled-border-color: var(--hh-btn-outline-text);
}

/* Filled: light blue with black text, darker on hover and press. */
.btn-primary,
.hh-btn--primary {
  --bs-btn-color: var(--hh-btn-text);
  --bs-btn-bg: var(--hh-light-blue);
  --bs-btn-border-color: var(--hh-light-blue);
  --bs-btn-hover-color: var(--hh-btn-text);
  --bs-btn-hover-bg: var(--hh-btn-hover-bg);
  --bs-btn-hover-border-color: var(--hh-btn-hover-bg);
  --bs-btn-active-color: var(--hh-btn-text);
  --bs-btn-active-bg: var(--hh-btn-hover-bg);
  --bs-btn-active-border-color: var(--hh-btn-hover-bg);
  --bs-btn-disabled-color: var(--hh-btn-text);
  --bs-btn-disabled-bg: var(--hh-light-blue);
  --bs-btn-disabled-border-color: var(--hh-light-blue);
}

/* Cerulean paints .btn-primary with gradients; the platform fill is flat. */
.btn-primary,
.btn-primary:hover,
.btn-primary:active,
.btn-check:checked + .btn-primary {
  background-image: none;
}

/* Welcome-card "Continue" (not deprecated): the filled button with a red
   outline, bold. <button class="btn btn-primary hh-btn--dismiss">. The
   0.4.0-0.5.0 markup "hh-btn hh-btn--dismiss" also works. */
.hh-btn--dismiss {
  --bs-btn-color: var(--hh-btn-text);
  --bs-btn-bg: var(--hh-light-blue);
  --bs-btn-border-color: var(--bs-danger);
  --bs-btn-hover-color: var(--hh-btn-text);
  --bs-btn-hover-bg: var(--hh-btn-hover-bg);
  --bs-btn-hover-border-color: var(--bs-danger);
  --bs-btn-active-color: var(--hh-btn-text);
  --bs-btn-active-bg: var(--hh-btn-hover-bg);
  --bs-btn-active-border-color: var(--bs-danger);
  --bs-btn-font-weight: 700;
  margin-top: 1rem;
}

/* Deprecated alias (remove in 0.7.0): .hh-btn without .btn (html.Button,
   <a>) draws Bootstrap's button box itself, from the variables above. */
.hh-btn {
  display: inline-block;
  padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);
  border: var(--bs-btn-border-width) solid var(--bs-btn-border-color);
  border-radius: var(--bs-border-radius);
  font-size: 1rem;
  font-weight: var(--bs-btn-font-weight, 400);
  line-height: 1.5;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  color: var(--bs-btn-color);
  background-color: var(--bs-btn-bg);
  background-image: none;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.hh-btn:hover {
  color: var(--bs-btn-hover-color);
  background-color: var(--bs-btn-hover-bg);
  border-color: var(--bs-btn-hover-border-color);
}

.hh-btn:active {
  color: var(--bs-btn-active-color);
  background-color: var(--bs-btn-active-bg);
  border-color: var(--bs-btn-active-border-color);
}

.hh-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), 0.5);
}

.hh-btn:disabled,
.hh-btn.disabled {
  color: var(--bs-btn-disabled-color);
  background-color: var(--bs-btn-disabled-bg);
  border-color: var(--bs-btn-disabled-border-color);
  opacity: 0.65;
  pointer-events: none;
}

/* Tabs (dbc.Tabs): dark-blue 2px underline, muted semibold labels, the
   active tab outlined in blue. The links keep 1px borders and Bootstrap's
   1px overlap, so the active tab cuts into the top half of the underline.
   hh-dashboard-tabs is a deprecated alias that needs no rules of its own. */
.nav-tabs {
  --bs-nav-link-color: var(--hh-muted-strong);
  --bs-nav-link-hover-color: var(--hh-blue);
  --bs-nav-link-font-weight: 600;
  --bs-nav-tabs-border-color: var(--hh-blue);
  --bs-nav-tabs-border-radius: 0.4rem;
  --bs-nav-tabs-link-hover-border-color: var(--hh-border);
  --bs-nav-tabs-link-active-color: var(--hh-blue);
  --bs-nav-tabs-link-active-bg: var(--bs-white);
  --bs-nav-tabs-link-active-border-color: var(--hh-blue) var(--hh-blue) var(--bs-white);
  gap: 0.3rem;
  border-bottom-width: 2px;
}

/* Section 3's 2px .nav-link.active rules are for the navbar and About
   sidebar; tab links keep Bootstrap's 1px border. */
.nav-tabs .nav-link {
  border-width: var(--bs-nav-tabs-border-width);
}

/* Content sits just under the tab line, so don't add mt-* to its first child. */
.nav-tabs + .tab-content {
  padding-top: 0.125rem;
}

/* Cards (dbc.Card, dbc.CardHeader): platform border, 0.5rem radius, soft
   shadow, and a white header with a centered dark-blue bold title. Plain
   .card doesn't clip its content; add Bootstrap's overflow-hidden utility
   where content must be cut at the rounded corners. */
.card {
  --bs-card-border-color: var(--hh-border);
  --bs-card-border-radius: 0.5rem;
  --bs-card-inner-border-radius: calc(0.5rem - var(--bs-card-border-width));
  --bs-card-box-shadow: var(--hh-card-shadow);
  --bs-card-cap-bg: var(--bs-white);
  --bs-card-cap-color: var(--hh-blue);
  box-shadow: var(--bs-card-box-shadow);
}

.card-header {
  font-size: 0.95rem;
  font-weight: 700;
  text-align: center;
}

/* Deprecated aliases (remove in 0.7.0). Same look on any element. .hh-card
   also clips its content (overflow: hidden), which plain .card does not. */
.hh-card {
  overflow: hidden;
  border: 1px solid var(--hh-border);
  border-radius: 0.5rem;
  box-shadow: var(--hh-card-shadow);
}

.hh-card-header {
  border-bottom: 1px solid var(--hh-border);
  color: var(--hh-blue);
  background: var(--bs-white);
  font-size: 0.95rem;
  font-weight: 700;
  text-align: center;
}

/* Row gutters inside the Dash document: --hh-card-gutter both ways, which
   also spaces stacked cards (don't add mb-* to the columns). Flask pages
   keep Bootstrap's 1.5rem. A Bootstrap gutter utility on the row wins for
   its axis: g-* / gx-* (and responsive g-md-*, ...) for x, g-* / gy-* for y. */
.hh-dash-document .row:not([class^="g-"], [class*=" g-"], [class^="gx-"], [class*=" gx-"]) {
  --bs-gutter-x: var(--hh-card-gutter);
}

.hh-dash-document .row:not([class^="g-"], [class*=" g-"], [class^="gy-"], [class*=" gy-"]) {
  --bs-gutter-y: var(--hh-card-gutter);
}

/* Deprecated alias (remove in 0.7.0): on a container (every .row inside,
   anywhere, including Flask pages) or on the dbc.Row itself. Unlike the
   rule above, it also overrides the row's g-* utilities. */
.hh-gutter-rows .row,
.row.hh-gutter-rows {
  --bs-gutter-x: var(--hh-card-gutter);
  --bs-gutter-y: var(--hh-card-gutter);
}


/* ==========================================================================
   PART 2: reusable widgets (sections 12-17)
   Each rule targets a class that an app opts into by using it in markup or
   Python. Nothing here changes the platform identity in Part 1.
   ========================================================================== */
/* --------------------------------------------------------------------------
   12. Dashboard card extras  (from DCP_Tool .dcp-control-card / -graph-card / ...)
   The card look itself is Bootstrap's .card, restyled in section 11:
   dbc.Card(className="hh-plot-card-fixed", children=[
       dbc.CardHeader(className="hh-card-header-with-controls", ...),
       dbc.CardBody(className="hh-graph-body", ...)])
   -------------------------------------------------------------------------- */
.hh-card-gap {
  gap: var(--hh-card-gutter) !important;
}

/* Title stays centered when the header is d-flex with a button on the right. */
:is(.card-header, .hh-card-header).d-flex.justify-content-between > *:first-child {
  flex: 1;
  text-align: center;
}

/* Two-row header: centered title + help button on row 1, controls (radio
   buttons etc.) centered on row 2. Hiding row 2 collapses it cleanly.
   <div class="card-header hh-card-header-with-controls">
     <span>Title</span>
     <div class="hh-card-header-info"><button class="method-info-button">?</button></div>
     <div class="hh-card-header-controls d-flex">...</div>
   </div> */
.hh-card-header-with-controls {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  row-gap: 0.25rem;
  column-gap: 0.5rem;
}

.hh-card-header-with-controls > :first-child {
  grid-column: 2;
  grid-row: 1;
}

.hh-card-header-info {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
}

.hh-card-header-controls {
  grid-column: 1 / -1;
  grid-row: 2;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  font-size: 0.85rem;
  font-weight: 400;
}

.hh-card-header-controls .form-check {
  margin: 0 0.5rem;
}

/* Collapsible card header link. */
.hh-collapse-toggle {
  color: inherit;
  font-weight: inherit;
  text-decoration: none;
}

.hh-collapse-toggle:hover,
.hh-collapse-toggle:focus {
  color: var(--hh-light-blue);
  text-decoration: none;
}

.hh-collapse-toggle-icon {
  font-size: 1.15rem;
  line-height: 1;
}

/* Control-panel text. */
.hh-control-intro {
  color: var(--hh-muted);
  font-size: 0.9rem;
  line-height: 1.45;
}

.hh-control-label {
  display: block;
  margin: 1.15rem 0 0.45rem;
  color: var(--hh-blue);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.hh-control-label:first-of-type {
  margin-top: 0;
}

/* Dropdown / date-input borders inside a control card. */
.hh-card .Select-control,
.hh-card .DateInput_input {
  border-color: #aebed1 !important;
  border-radius: 0.375rem;
}

.hh-card .Select-control:hover,
.hh-card .DateInput_input:focus {
  border-color: var(--hh-light-blue) !important;
}

/* Graph body: center a dcc.Graph and let it fill the card. */
.hh-graph-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 330px;
  background: #fff;
}

.hh-graph-body > div {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.hh-graph,
.hh-graph .dash-graph,
.hh-graph .dash-graph > div {
  width: 100%;
  height: 100%;
}

.hh-graph {
  margin: auto;
  min-width: 0;
}

/* Fixed-height plot card. A Plotly graph with autosize + height:100% needs a
   container with a definite height at first paint, otherwise it renders at
   the wrong height or gets cut off intermittently. */
.hh-plot-card-fixed {
  height: 460px;
}

.hh-plot-card-fixed > .card-body {
  min-height: 0;                   /* let the body shrink inside the fixed card */
}

/* Opt-in: let a card that is stretched to its row's height on desktop
   (e.g. a control panel beside a graph) shrink to its content once the
   columns stack. Other cards keep their height (.h-100, .hh-plot-card-fixed).
   Added in 0.2.0; before that this applied to every .hh-card. */
@media (max-width: 991.98px) {
  .hh-card-fluid-mobile {
    height: auto !important;
  }

  .hh-graph-body {
    min-height: 400px;
  }
}


/* --------------------------------------------------------------------------
   13. Round icon buttons ("?" help, "+" expand-plot)
   Base look: html.Button("?", className="hh-icon-btn"). The placement classes
   below also take the base look, so existing markup keeps working:
     method-info-button  "?" in a card's bottom-right corner (OWRD)
     expand-plot-button  "+" left of the "?" (OWRD)
   Variants, applied to the button inside a card:
     .card-header         inline, 26px, green border, black glyph (DCP_Tool;
                          also .hh-card-header, the deprecated alias)
     .hh-card-info-corner small, quiet, top-right (DCP_Tool)
   -------------------------------------------------------------------------- */
.hh-icon-btn,
.method-info-button,
.expand-plot-button {
  display: inline-block;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 2px solid var(--hh-green);
  border-radius: 50%;
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.5;
  text-align: center;
  vertical-align: middle;
  color: var(--bs-gray-700);
  background-color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  user-select: none;
  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,
    border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.hh-icon-btn:hover,
.hh-icon-btn:active,
.hh-icon-btn:focus-visible,
.method-info-button:hover,
.method-info-button:active,
.method-info-button:focus-visible,
.expand-plot-button:hover,
.expand-plot-button:active,
.expand-plot-button:focus-visible {
  color: #000;
  background-color: var(--bs-gray-200);
  border-color: var(--bs-gray-200);
}

/* Keyboard focus uses the platform's light-blue ring, as the buttons do. */
.hh-icon-btn:focus-visible,
.method-info-button:focus-visible,
.expand-plot-button:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 0.25rem rgba(var(--hh-light-blue-rgb), 0.5);
}

/* Corner placement. The card needs position: relative (Bootstrap's .card has it). */
.method-info-button,
.expand-plot-button {
  position: absolute;
  bottom: 10px;
  margin: 10px;
}

.method-info-button {
  right: 10px;
}

.expand-plot-button {
  right: 50px;                     /* sits left of the info button */
}

/* Inside a card header: inline, 26px, green border, black glyph. */
:is(.card-header, .hh-card-header) :is(.hh-icon-btn, .method-info-button) {
  position: static;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  margin: 0 0 0 0.5rem;
  color: #000;
  border-color: var(--hh-green);
  font-size: 0.85rem;
  line-height: 1;
}

:is(.card-header, .hh-card-header) :is(.hh-icon-btn, .method-info-button):is(:hover, :focus) {
  color: #000;
  background-color: var(--bs-gray-200);
  border-color: var(--bs-gray-200);
}

/* Inside .hh-card-info-corner: small and quiet, for header-less cards. */
.hh-card-info-corner .hh-icon-btn,
.hh-card-info-corner .method-info-button {
  position: absolute;
  top: 0.35rem;
  right: 0.35rem;
  bottom: auto;
  margin: 0;
  width: 20px;
  height: 20px;
  border: 1px solid #b8c2cc;
  color: #7b8794;
  background-color: transparent;
  font-size: 0.7rem;
}

.hh-card-info-corner .hh-icon-btn:hover,
.hh-card-info-corner .hh-icon-btn:focus,
.hh-card-info-corner .method-info-button:hover,
.hh-card-info-corner .method-info-button:focus {
  color: #000;
  background-color: var(--bs-gray-200);
  border-color: var(--bs-gray-200);
}


/* --------------------------------------------------------------------------
   14. Modal windows (dbc.Modal content variants)
   Both variants center their dialog in a lightly tinted full-screen layer.
   Until 0.5.0 they got that from a global .modal rule; it is now scoped here.
   -------------------------------------------------------------------------- */
.modal.modal-content-plots.show,
.modal.explorer-report-modal.show {
  display: flex !important;        /* react-bootstrap sets display: block inline */
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.1);
}

/* Expanded-plot modal: dbc.Modal(className="modal-content-plots") */
.modal-content-plots {
  background-color: white;
  padding: 2rem;
  border-radius: 10px;
  border: 5px solid var(--bs-primary);
  text-align: center;
  margin: auto;
  max-width: 65%;
  max-height: 97%;
  overflow: auto;
}

.modal.modal-content-plots {
  width: 100vw;
  max-width: none;
  height: 100vh;
  max-height: none;
  padding: 0;
  border: 0;
  background-color: rgba(0, 0, 0, 0.1);
}

.modal.modal-content-plots .modal-dialog {
  width: 65vw;
  max-width: 1100px;
  margin-left: auto;
  margin-right: auto;
}

.modal.modal-content-plots .modal-content {
  border: 5px solid var(--bs-primary);
  border-radius: 10px;
  max-height: 97vh;
  overflow: auto;
}

/* Full-height report/confirm window with fixed header + footer and a
   scrolling body (OWRD's report, downloads, and confirm-input windows).
   dbc.Modal(className="explorer-report-modal", children=
     html.Div(className="explorer-report-modal-shell", children=
       html.Div(className="hh-modal-window", children=[
         html.Div(className="explorer-report-window-header"),
         html.Div(className="explorer-report-window-body"),
         html.Div(className="explorer-report-window-footer")]))) */
.explorer-report-modal .modal-dialog {
  max-width: 100vw !important;
  width: 100vw !important;
  height: 100vh !important;
  margin: 0 !important;
}

.explorer-report-modal .modal-content {
  background: transparent;
  border: none;
  border-radius: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.explorer-report-modal-shell {
  display: flex;
  align-items: stretch;
  justify-content: center;
  width: 100%;
  height: 100vh;
  padding: 0 1rem;
  overflow: hidden;
}

.explorer-report-modal-shell-body {
  padding: 0;
}

/* OWRD targets these by element ID; .hh-modal-window is the class form. */
.hh-modal-window {
  width: 75vw;
  height: 100vh;
  background-color: white;
  border: 5px solid var(--bs-primary);
  border-radius: 10px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.explorer-report-window-header {
  flex: 0 0 auto;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--bs-border-color);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.explorer-report-window-header .modal-title {
  margin-bottom: 0;
}

.explorer-report-window-body {
  flex: 1 1 auto;
  padding: 0.5rem;
  overflow: auto;
}

.explorer-report-window-footer {
  flex: 0 0 auto;
  padding: 0.75rem 1rem;
  border-top: 1px solid var(--bs-border-color);
}


/* --------------------------------------------------------------------------
   15. Dash-Leaflet maps
   See docs/dash-leaflet-notes.md for the Python side.
   -------------------------------------------------------------------------- */
/* Leaflet focuses clicked vector layers (tabindex for a11y), drawing the
   browser focus rectangle. Selection feedback comes from hideout/style. */
.leaflet-interactive:focus {
  outline: none;
}

/* Live "Lat, Lng" readout created by hydrologyhub.leaflet.displayCoords. */
.coordinate-display {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  padding: 1px 4px;
  border-radius: 2px;
  background-color: rgba(255, 255, 255, 0.7);
  font-family: Arial, sans-serif;
  font-size: 12px;
  pointer-events: none;
}

/* Bottom-right dl.LayersControl restyled as a green pill labelled
   "Available Datasets". Change the label per app with --hh-layers-label. */
.leaflet-bottom.leaflet-right .leaflet-control-layers {
  padding: 0;
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 40px;
}

.leaflet-bottom.leaflet-right .leaflet-control-layers.leaflet-control-layers-expanded {
  padding: 0;
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 20px 20px 4px 4px;
}

.leaflet-bottom.leaflet-right .leaflet-control-layers > .leaflet-control-layers-toggle {
  background-image: none !important;
  width: 15vw;
  min-width: 150px;
  height: auto;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 4px solid var(--hh-green);
  border-radius: 50px;
  margin: 0;
  padding: 0;
  background-color: rgba(var(--bs-success-rgb), 0.1);
  box-shadow: 24px 12px 12px rgba(0, 0, 0, 0.2);
  cursor: pointer;
}

.leaflet-bottom.leaflet-right .leaflet-control-layers > .leaflet-control-layers-toggle::before {
  content: var(--hh-layers-label, 'Available Datasets');
  color: var(--bs-primary);
  font-size: 1rem;
  font-weight: 600;
  padding: 4px 7px;
  display: inline-block;
  text-align: center;
  width: 100%;
}

/* Dash-built replacement for that control (OWRD): same pill look, but the
   options are real Dash checklist/radio inputs, so callbacks can read them.
   html.Div(className="dataset-selector-wrap", style={position:absolute, right, bottom, zIndex:1200}, children=
     dbc.Card(className="dataset-selector-card", children=[
       dbc.CardHeader(className="dataset-selector-header", children=
         html.Button(className="dataset-selector-toggle", children=[
           html.Span("Available Datasets", className="dataset-selector-title"),
           html.Span("›", className="dataset-selector-chevron")])),
       dbc.CardBody(className="dataset-selector-body", children=[
         dbc.Checklist(className="dataset-selector-options",
                       input_class_name="dataset-selector-input",
                       label_class_name="dataset-selector-label"),
         html.Div(className="selected-highlight-toggle", children=dbc.Switch(
                       input_class_name="selected-highlight-input",
                       label_class_name="selected-highlight-label"))])]))
   Opens on hover or keyboard focus. */
.dataset-selector-wrap {
  width: 15vw;
  min-width: 220px;
  max-width: 320px;
}

.dataset-selector-card {
  overflow: hidden;
  border: 4px solid var(--hh-green);
  border-radius: 40px;
  background-color: rgba(255, 255, 255, 0.9);
  box-shadow: 24px 12px 12px rgba(0, 0, 0, 0.2);
  transition: border-radius 0.15s ease;
}

.dataset-selector-wrap:hover .dataset-selector-card,
.dataset-selector-wrap:focus-within .dataset-selector-card {
  border-radius: 20px 20px 4px 4px;
}

.dataset-selector-header {
  padding: 0;
  border-bottom: none;
  background-color: rgba(var(--bs-success-rgb), 0.1);
}

.dataset-selector-toggle {
  position: relative;
  width: 100%;
  display: flex;
  align-items: center;
  padding: 4px 10px;
  border: none;
  background: transparent;
  color: var(--bs-primary);
  font-size: 1rem;
  font-weight: 600;
  text-align: center;
  cursor: default;
}

.dataset-selector-title {
  display: block;
  width: 100%;
  text-align: center;
}

.dataset-selector-chevron {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  min-width: 1rem;
  text-align: right;
  font-size: 0.95rem;
  transition: transform 0.15s ease;
}

.dataset-selector-wrap:hover .dataset-selector-chevron,
.dataset-selector-wrap:focus-within .dataset-selector-chevron {
  transform: translateY(-50%) rotate(90deg);
}

.dataset-selector-body {
  padding: 0.55rem 0.85rem 0.7rem;
  display: none;
}

.dataset-selector-wrap:hover .dataset-selector-body,
.dataset-selector-wrap:focus-within .dataset-selector-body {
  display: block;
}

.dataset-selector-options .form-check {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  margin-bottom: 0.45rem;
}

.dataset-selector-options .form-check:last-child {
  margin-bottom: 0;
}

.dataset-selector-input {
  margin-top: 0.2rem;
  border-color: var(--hh-green);
}

.dataset-selector-input:checked,
.selected-highlight-input:checked {
  background-color: var(--bs-primary);
  border-color: var(--bs-primary);
}

.dataset-selector-label {
  color: var(--bs-primary);
  font-size: 0.92rem;
  line-height: 1.25;
  cursor: pointer;
}

.selected-highlight-toggle {
  margin-top: 0.65rem;
  padding-top: 0.55rem;
  border-top: 1px solid rgba(var(--bs-primary-rgb), 0.15);
}

.selected-highlight-toggle .form-check {
  margin-bottom: 0;
}

.selected-highlight-input {
  border-color: var(--hh-green);
}

.selected-highlight-label {
  color: var(--bs-primary);
  font-size: 0.9rem;
}

@media (max-width: 992px) {
  .dataset-selector-wrap {
    width: min(72vw, 320px);
    min-width: 0;
  }
}

/* Map legend row under a map (DCP_Tool .dcp-map-legend). Set each swatch's
   border/background inline or with an app class.
   <div class="hh-map-legend">
     <span class="hh-map-legend-item"><span class="hh-map-legend-swatch" style="border-color:#3f50a0"></span>Brazos</span>
   </div> */
.hh-map-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.5rem 0.9rem;
  margin-top: 0.5rem;
  font-size: 0.8rem;
}

.hh-map-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.hh-map-legend-swatch {
  display: inline-block;
  width: 0.9rem;
  height: 0.9rem;
  border: 3px solid;
  border-radius: 0.15rem;
  background: #fff;
}


/* --------------------------------------------------------------------------
   16. Forms and images
   -------------------------------------------------------------------------- */
/* Bootstrap-style invalid icon on a dcc.Input with pattern/min/max.
   html.Div(className="lat-long-input", children=dcc.Input(type="number", min=..., max=...)) */
.lat-long-input input:invalid {
  border-color: #dc3545;
  padding-right: calc(1.5em + 0.75rem);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right calc(0.375em + 0.1875rem) center;
  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
  outline: none;
}

/* Bordered figure on About pages; add .expandable-hover to zoom on hover. */
.img-domain {
  width: 25vw;
  min-width: 100px;
  height: auto;
  border: 5px solid var(--bs-primary);
}

.img-domain.expandable-hover {
  transition: transform 0.3s ease;
}

.img-domain.expandable-hover:hover {
  transform: scale(2);
}


/* --------------------------------------------------------------------------
   17. Layout helpers
   -------------------------------------------------------------------------- */
/* Width-driven grid with an even column split (e.g. 6 -> 3+3 -> 2+2+2), sized
   from the container's own width rather than the viewport. Column count is
   set by hydrologyhub.autoGrid in hydrologyhub.js; defaults to 2 before
   the script runs. (Generalized from DCP_Tool's gauge row.)
   <div class="hh-auto-grid" data-hh-item-width="182" data-hh-columns="6,3,2"> */
.hh-auto-grid {
  display: grid;
  grid-template-columns: repeat(var(--hh-grid-cols, 2), minmax(0, 1fr));
  justify-items: center;
  justify-content: center;
  gap: 0.5rem;
}

/* Explorer layout (tabs column + map column): fixed-height panes on desktop,
   stacked and page-scrolling below lg. OWRD uses 992px; the template had
   768px. 992px is used here because the panes are unusable when squeezed. */
@media (max-width: 992px) {
  .dash-main-container,
  .dash-main-row {
    height: auto !important;
    overflow: visible !important;
  }

  .dash-main-col {
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
  }

  .dash-tabs-col,
  .dash-map-col {
    overflow-y: visible !important;
  }
}
