/* base.css — app-wide theme tokens and global styles only.
   Per-module styling lives in www/styles/<module>.css, loaded by that module.
   Do NOT accumulate module styles here. */

/* Custom design tokens. Light mode is the default (:root); dark mode overrides
   live under [data-bs-theme="dark"]. Bootstrap 5.3 sets that attribute on <html>
   when the Settings dark-mode toggle is on. Style app components against these
   tokens (var(--ik-*)) rather than hard-coded colours so they follow the mode. */
:root {
  --ik-accent: #cf6819;
}

[data-bs-theme="dark"] {
  --ik-accent: #e8924d; /* brighter burnt-orange so it reads on dark surfaces */
}

/* Modal title convention: a small muted subtitle (e.g. an id) under the title. */
.ik-modal-subtitle { font-size: 0.78rem; font-weight: 400; color: var(--bs-secondary-color, #6c757d); margin-top: 0.1rem; }

/* Review-page heading convention: the Data → Quality views (Camera review, Trap review,
   Duplicate window) each lead with a bold page title. */
.ik-review-head { font-weight: 700; margin: 0 0 0.6rem; }
/* review-page heading + its inline help (?) button on one row */
.ik-review-headrow { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.6rem; }
.ik-review-headrow .ik-review-head { margin: 0; }

/* "← Back" link on deeper drill-modal tabs (see .ik_tab_back). Subtle — the tab headers remain. */
.ik-tab-back { display: inline-block; font-size: 0.82rem; margin-bottom: 0.55rem;
  color: var(--bs-secondary-color, #6c757d); text-decoration: none; cursor: pointer; }
.ik-tab-back:hover { color: var(--ik-accent, #e8924d); }

/* Inline help: a small "?" / "i" button (.ik_info) that opens a description modal. */
.ik-info-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.2rem; height: 1.2rem; padding: 0; border: none; border-radius: 50%;
  background: var(--bs-secondary-bg, #e9ecef); color: var(--bs-secondary-color, #6c757d);
  cursor: pointer; line-height: 1; font-size: 0.72rem; vertical-align: middle; flex: 0 0 auto;
  transition: background-color 0.15s, color 0.15s;
}
.ik-info-btn:hover { background: var(--ik-accent, #e8924d); color: #fff; }
.ik-info-modal .modal-body { line-height: 1.5; }
.ik-info-modal .modal-body h6 { margin: 0.9rem 0 0.25rem; font-weight: 600; }
.ik-info-modal .modal-body p:last-child { margin-bottom: 0; }

/* ── Data-table interaction standard (app-wide) ───────────────────────────────────────────
   Use DT class "stripe hover row-border" for zebra striping + hover. A row with ONE action
   gets class "ik-row-click" + DT selection="single" → the whole row is clickable (pointer).
   A row with MULTIPLE distinct actions instead makes each actionable cell an .ik-link (the
   cell-filling link below), no row selection. */
table.dataTable.ik-row-click tbody tr { cursor: pointer; }
/* per-cell action link for multi-action rows — fills the cell so the whole cell is the target */
td .ik-link, .ik-link {
  display: inline-block; width: 100%; font-weight: 600; text-decoration: underline;
  text-underline-offset: 2px; cursor: pointer; color: inherit;
}
.ik-link:hover { color: var(--ik-accent, #e8924d); }
/* small inline status badge (e.g. a trap's bait change) */
.ik-badge {
  display: inline-block; padding: 0.05rem 0.4rem; border-radius: 0.7rem; font-size: 0.72rem;
  font-weight: 600; line-height: 1.4;
}
.ik-badge-changed { background: #fff3cd; color: #8a6d3b; }

/* ── App-wide busy spinner for slow PLOTS ─────────────────────────────────────────────────
   Shiny marks an output `.recalculating` while it computes — including the very first render,
   from page load until the plot is drawn — but its only built-in cue is a faint fade that's
   easy to miss on a slow plot (e.g. "Are we winning?"). Overlay a clear centred spinner so a
   new user sees the app is working. Scoped to plot outputs (leaflet/widgets manage their own).
   We pin the wrapper opaque and fade only the <img>, so the spinner itself stays crisp. */
.shiny-plot-output { position: relative; }
.shiny-plot-output.recalculating { opacity: 1 !important; }
.shiny-plot-output.recalculating > img { opacity: 0.35; transition: opacity 0.2s; }
.shiny-plot-output.recalculating::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 2.4rem; height: 2.4rem;
  margin: -1.2rem 0 0 -1.2rem; border-radius: 50%; z-index: 5;
  border: 3px solid var(--bs-border-color, #ced4da); border-top-color: var(--ik-accent, #cf6819);
  animation: ik-spin 0.7s linear infinite;
}
@keyframes ik-spin { to { transform: rotate(360deg); } }

/* ── Sidebar credit footer ───────────────────────────────────────────────────────────────
   Small italic byline pinned to the bottom of the data-selection rail. bslib's .sidebar-content
   is a flex column filling the rail height, so margin-top:auto pushes the credit to the bottom. */
.bslib-sidebar-layout > .sidebar > .sidebar-content { display: flex; flex-direction: column; }
.ik-sidebar-foot {
  margin-top: auto; padding-top: 1.25rem; font-size: 0.72rem; font-style: italic;
  line-height: 1.45; color: var(--bs-secondary-color, #6c757d);
}
.ik-sidebar-foot a { color: inherit; text-decoration: underline; }
.ik-sidebar-foot a:hover { color: var(--ik-accent, #cf6819); }
