/* ============================================================
   ABCD Dictionary Search — app.css

   Brand palette (matches docs/stylesheets/extra.css for mkdocs):
     primary   #62272D  burgundy
     secondary #FDBF6F  warm orange
     info      #DEEBF7  pale blue
     warning   #FF7F00  orange
     danger    #E31A1C  red
     success   #33A02C  green

   Bootstrap's primary / secondary / info / etc. and the base
   typography are retinted via `bs_theme(...)` in app.R, so most
   components (buttons, .bg-primary, .text-primary, links) inherit
   the palette automatically. This file adds:
     • layout + responsive (mobile) rules
     • brand polish that SASS theming doesn't cover (reactable
       header tint, tab underline, row hover, etc.)
   ============================================================ */

/* ============================================================
   1. Base layout
   ============================================================ */
/* Scale all typography to 80% of the default. Bootstrap/bslib sizes text in
   rem, which is relative to the root font size, so shrinking the root (16px ->
   12.8px) proportionally reduces every font size across the app in one place.
   (rem-based spacing scales too, keeping the layout proportional.) */
html { font-size: 80%; }

.card { height: 100%; }
.form-group { margin-bottom: 15px; }
.no-gap { gap: 0 !important; }

/* Desktop 1:3:1 layout — shrink both sidebars so the middle table gets 3/5 of
   the width. Each sidebar is 20vw of the viewport; the outer main is then 80vw,
   and inside the results card the right sidebar takes another 20vw, leaving the
   table ~60vw. Expressing both in vw (not container %) keeps the ratio exact
   despite the right sidebar being nested inside the card. This overrides
   bslib's inline --_sidebar-width, so !important is required. Scoped to desktop
   (>=769px): below that the sidebars are overlays and keep their px widths so
   they stay usable. Direct-child :has() disambiguates the two nested layouts —
   the outer layout also *contains* #right_sidebar as a deep descendant. */
@media (min-width: 769px) {
  .bslib-sidebar-layout:has(> #left_sidebar),
  .bslib-sidebar-layout:has(> #right_sidebar) {
    --_sidebar-width: 20vw !important;
  }
}

.scrollable-checkboxes {
  max-height: 200px;
  overflow-y: auto;
  padding: 5px;
  border: 1px solid #e9ecef;
  border-radius: 4px;
  background-color: #f8f9fa;
}

.filter-actions {
  font-size: 0.8rem;
  margin-bottom: 5px;
}
.filter-actions a { color: var(--bs-primary, #62272D); }

/* ============================================================
   2. Brand polish
   ============================================================ */

/* App header banner */
.app-header {
  background: var(--bs-primary, #62272D) !important;
  color: #fff;
  border-bottom: 3px solid var(--bs-secondary, #FDBF6F);
}
.app-header h2 {
  font-weight: 700;
  letter-spacing: 0.01em;
}

/* Sidebar card-header (Search Parameters / Refine Results) */
.bslib-sidebar .card-header {
  background: var(--bs-info, #DEEBF7);
  color: var(--bs-primary, #62272D);
  font-weight: 700;
  border-bottom: 2px solid var(--bs-primary, #62272D);
}

/* Tabs: active tab underlined in brand burgundy */
.nav-tabs .nav-link.active {
  border-bottom: 3px solid var(--bs-primary, #62272D) !important;
  color: var(--bs-primary, #62272D) !important;
  font-weight: 700;
}

/* Reactable header row tinted with brand-info pale blue */
#results_table .rt-th {
  background: var(--bs-info, #DEEBF7);
  color: #1a1a1a;
  font-weight: 700;
}

/* Subtle row hover in warm orange */
#results_table .rt-tr-highlight:hover .rt-td {
  background: rgba(253, 191, 111, 0.18) !important;
}

/* Click-cue for rows (row-details modal trigger) */
#results_table .rt-tr:not(.rt-tr-header):not(.rt-tr-filter) {
  cursor: pointer;
}

/* Selectize multi-select tags (filter dropdowns) — brand burgundy chips */
.selectize-input .item {
  background: var(--bs-primary, #62272D) !important;
  color: #fff !important;
  border-color: var(--bs-primary, #62272D) !important;
}
.selectize-input .item .remove {
  color: #fff !important;
  border-left-color: rgba(255, 255, 255, 0.35) !important;
}
.selectize-input .item .remove:hover {
  background: rgba(255, 255, 255, 0.15) !important;
}
.selectize-dropdown .active {
  background: var(--bs-info, #DEEBF7) !important;
  color: var(--bs-primary, #62272D) !important;
}

/* Row-details modal */
/* Keep the modal above a bslib full-screen card (which sits at a very high
   z-index). Otherwise clicking a row while the table/sidebar is expanded to
   full screen opens the details modal *behind* the expanded card. */
.modal { z-index: 100050 !important; }
.modal-backdrop { z-index: 100040 !important; }
.modal-header {
  border-bottom-width: 2px;
  border-bottom-color: var(--bs-primary, #62272D);
}
.row-details-table { table-layout: fixed; width: 100%; }
.row-details-table th,
.row-details-table td {
  word-break: break-word;
  overflow-wrap: anywhere;
  white-space: normal;
  vertical-align: top;
}
.row-details-table th {
  width: 30%;
  color: var(--bs-primary, #62272D);
}

/* ============================================================
   3. Mobile (≤768px): structural overrides + responsive table
   ============================================================ */
@media (max-width: 768px) {

  /* 3.1 Allow the page to scroll vertically on mobile
         (page_fillable locks overflow:hidden by default) */
  html, body {
    overflow: auto !important;
    height: auto !important;
  }
  .bslib-page-fill {
    height: auto !important;
    min-height: 100vh !important;
    overflow: visible !important;
  }

  /* 3.2 Let the outer layout and card grow with content */
  .bslib-sidebar-layout:not(.no-gap),
  .bslib-sidebar-layout:not(.no-gap) > [role='main'] {
    height: auto !important;
    overflow: visible !important;
  }
  .card:has(.bslib-sidebar-layout.no-gap) {
    height: auto !important;
    min-height: 0 !important;
    overflow: visible !important;
  }

  /* 3.3 Switch the inner (right-sidebar) layout from CSS grid
         to flex column so the table sits on TOP and the filter
         panel stacks BELOW */
  .bslib-sidebar-layout.no-gap,
  .bslib-sidebar-layout.sidebar-right.no-gap {
    display: flex !important;
    flex-direction: column !important;
    height: auto !important;
    min-height: 0 !important;
    overflow: visible !important;
  }

  /* 3.4 Table area: full width, fixed scrollable height */
  .bslib-sidebar-layout.no-gap > [role='main'],
  .bslib-sidebar-layout.no-gap > .bslib-main {
    order: 1 !important;
    width: 100% !important;
    height: 55vh !important;
    min-height: 200px !important;
    overflow: auto !important;
    grid-column: unset !important;
  }

  /* 3.5 Right sidebar: full width, stacked below, always visible
         (when bslib hasn't closed it — see 3.9 below) */
  .bslib-sidebar-layout.no-gap > aside,
  .bslib-sidebar-layout.no-gap > .bslib-sidebar {
    display: block !important;
    order: 2 !important;
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    max-height: none !important;
    overflow-y: auto !important;
    border-left: none !important;
    border-top: 1px solid #dee2e6 !important;
    grid-column: unset !important;
  }

  /* 3.6 Keep the bslib collapse toggle visible so users can
         re-open the right filter panel after it auto-hides */
  .no-gap .collapse-toggle {
    display: flex !important;
    z-index: 5;
  }

  /* 3.7 Cap reactable so it doesn't overflow its container */
  #results_table {
    height: 55vh !important;
  }

  /* 3.8 Compact, mobile-friendly table cells */

  /* reactable sets an inline min-width equal to the SUM of every column's
     minWidth (totalMinWidth) on the table/header/body/row flex containers, so
     the whole row can't shrink below ~560px (name 180 + label 380) — it
     overflows the viewport regardless of how individual cells are sized. This
     is the real cause of the horizontal overflow; drop that floor on mobile so
     rows shrink to the viewport and the cells (below) can wrap to fit. */
  #results_table .rt-table,
  #results_table .rt-thead,
  #results_table .rt-tbody,
  #results_table .rt-tr {
    min-width: 0 !important;
  }

  #results_table .rt-td,
  #results_table .rt-th {
    padding: 4px 6px !important;
    font-size: 0.8rem !important;
    line-height: 1.25 !important;
    /* Let the two visible columns shrink to share the viewport width instead
       of overflowing. Each colDef sets a minWidth (name 180, label 380) that
       reactable applies as an inline min-width with flex-shrink:0, so on a
       narrow screen the label column can't shrink below 380px — it overflows
       and .rt-td-inner{overflow:hidden} clips the text. Dropping the min-width
       floor and re-enabling shrink lets flex compress both columns to fit;
       reactable's flex-grow (proportional to minWidth) keeps a ~1:2 split, and
       the text wraps (see .rt-td rule below) rather than being cut off. */
    min-width: 0 !important;
    flex-shrink: 1 !important;
  }
  #results_table .rt-td {
    white-space: normal !important;
    word-break: break-word !important;
    overflow-wrap: anywhere !important;
  }
  #results_table .rt-page-info,
  #results_table .rt-page-size {
    display: none !important;
  }
  #results_table .rt-search {
    font-size: 0.85rem !important;
    margin-bottom: 4px !important;
  }

  /* 3.9 When bslib marks the right sidebar closed, fully hide it
         (our flex-column override would otherwise keep it visible). */
  .bslib-sidebar-layout.no-gap[data-bslib-sidebar-open='closed'] > aside,
  .bslib-sidebar-layout.no-gap[data-bslib-sidebar-open='closed'] > .bslib-sidebar,
  .bslib-sidebar-layout.no-gap > .bslib-sidebar[aria-hidden='true'],
  .bslib-sidebar-layout.no-gap > aside[aria-hidden='true'] {
    display: none !important;
  }
  /* When closed, let the table area take all available height */
  .bslib-sidebar-layout.no-gap[data-bslib-sidebar-open='closed'] > [role='main'],
  .bslib-sidebar-layout.no-gap[data-bslib-sidebar-open='closed'] > .bslib-main {
    height: auto !important;
    min-height: 70vh !important;
  }

  /* 3.10 Make the row-details modal fit narrow screens */
  .modal-dialog,
  .modal-dialog.modal-lg {
    margin: 0.5rem !important;
    max-width: calc(100% - 1rem) !important;
  }
  .modal-body { padding: 0.75rem !important; }
}

/* ==========================================================================
   4. Guided tour (cicerone / driver.js 0.9.x)
   ==========================================================================
   The app shell is page_fillable() — a non-scrolling, overflow-clipped flex
   viewport. driver.js positions its popover with `position: absolute`, so any
   part of it that lands over a clipped container edge gets cut off ("the tour
   dialog does not fit into the app window"). Because the window itself never
   scrolls in a fillable page, page coordinates equal viewport coordinates, so
   promoting the popover to `position: fixed` keeps driver.js's computed
   left/top correct while freeing it from ancestor overflow clipping.
   The width/height caps keep the popover inside small windows. */
#driver-popover-item {
  position: fixed !important;
  max-width: min(92vw, 340px) !important;
  max-height: 85vh !important;
  overflow-y: auto !important;
  box-sizing: border-box;
}

/* Disable the guided tour on small screens (matches the 768px mobile
   breakpoint used elsewhere): the sidebars collapse at this width, so tour
   highlights would frame hidden controls. The auto-start is suppressed in JS;
   this hides the manual "Take a tour" launcher so there's no way in. */
@media (max-width: 768px) {
  #start_tour {
    display: none !important;
  }
}
