/*
  Triumvirate site CSS — supplements Tailwind (CDN) with the `light:`
  variant utilities the templates use.

  Tailwind ships `dark:` but not `light:`. We add it via these rules:
  every `light:X` utility in the templates needs a matching `html.light .light\:X`
  rule here. The list is exhaustive against the current template surface —
  if a NEW `light:` class appears in HTML, add a rule below.

  Rationale: this is a small, finite, hand-maintained list. A full
  CSS-variables refactor would be cleaner but would mean editing every
  Tailwind utility used. Not worth it at this site size.
*/

/* --- Backgrounds --- */
html.light .light\:bg-bone        { background-color: #F5EFE0; }
html.light .light\:bg-bone\/40    { background-color: rgba(245, 239, 224, 0.4); }
html.light .light\:bg-bone\/95    { background-color: rgba(245, 239, 224, 0.95); }
html.light .light\:bg-emerald-700 { background-color: #047857; }
html.light .light\:bg-amber-700   { background-color: #b45309; }
html.light .light\:bg-red-700     { background-color: #b91c1c; }

/* --- Text colours --- */
html.light .light\:text-ink       { color: #1F242C; }
html.light .light\:text-ink\/25   { color: rgba(31, 36, 44, 0.25); }
html.light .light\:text-ink\/40   { color: rgba(31, 36, 44, 0.40); }
html.light .light\:text-ink\/45   { color: rgba(31, 36, 44, 0.45); }
html.light .light\:text-ink\/50   { color: rgba(31, 36, 44, 0.50); }
html.light .light\:text-ink\/55   { color: rgba(31, 36, 44, 0.55); }
html.light .light\:text-ink\/60   { color: rgba(31, 36, 44, 0.60); }
html.light .light\:text-ink\/65   { color: rgba(31, 36, 44, 0.65); }
html.light .light\:text-ink\/70   { color: rgba(31, 36, 44, 0.70); }
html.light .light\:text-ink\/75   { color: rgba(31, 36, 44, 0.75); }
html.light .light\:text-ink\/80   { color: rgba(31, 36, 44, 0.80); }
html.light .light\:text-bone      { color: #F5EFE0; }
html.light .light\:text-emerald-700 { color: #047857; }
html.light .light\:text-amber-700   { color: #b45309; }
html.light .light\:text-red-700     { color: #b91c1c; }

/* --- Borders & dividers --- */
html.light .light\:border-ink     { border-color: #1F242C; }
html.light .light\:border-ink\/15 { border-color: rgba(31, 36, 44, 0.15); }
html.light .light\:border-ink\/20 { border-color: rgba(31, 36, 44, 0.20); }
html.light .light\:border-ink\/30 { border-color: rgba(31, 36, 44, 0.30); }
html.light .light\:divide-ink\/15 > * + * { border-color: rgba(31, 36, 44, 0.15); }

/* --- Hover states --- */
html.light .light\:hover\:text-ink:hover           { color: #1F242C; }
html.light .light\:hover\:text-bone:hover          { color: #F5EFE0; }
html.light .light\:hover\:border-ink:hover         { border-color: #1F242C; }

/*
  Body bg/text — fights the inline `bg-slate text-parchment` (which are dark
  defaults). !important wins regardless of stylesheet load order, which the
  Tailwind CDN doesn't strictly guarantee.
*/
html.light body {
  background-color: #F5EFE0 !important;
  color: #1F242C !important;
}

/* Cormorant looks better with a touch more letter-spacing at display sizes. */
.font-serif { letter-spacing: 0.01em; }

/* line-clamp-3 isn't core Tailwind in every CDN build. */
.line-clamp-3 {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ============================================================
   Theme tokens via CSS variables.

   The whole reason `text-parchment` etc. didn't swap in light mode was
   that those Tailwind utilities resolve to hardcoded hex colours at
   build (CDN) time. Templates had to manually opt-in to a `light:`
   counterpart for every utility. They drifted.

   Solution: redefine `text-parchment*`, `bg-slate*`, `border-border*`
   to read from CSS variables, and swap the variables when `html.light`
   is set. The nav is explicitly excluded (it stays dark in both themes).

   Tailwind utilities still work for sizing/spacing/layout — only the
   colour utilities are intercepted here.
   ============================================================ */

:root {
  /* Dark theme — the defaults. */
  --ink-rgb: 232 221 201;   /* parchment (text-on-dark) */
  --bg-rgb:  15 20 25;       /* slate (page bg) */
  --border-rgb: 42 51 64;   /* dark slate border */
  --brass-rgb: 200 169 92;  /* brass — gold accent, pops on slate */
}

html.light {
  --ink-rgb: 31 36 44;        /* ink (text-on-light) */
  --bg-rgb:  245 239 224;     /* bone (page bg) */
  --border-rgb: 31 36 44;     /* same as ink; used with low alpha for fine lines */
  --brass-rgb: 122 92 22;     /* darker gilt — meets WCAG AA on bone (~5:1) */
}

/* Containers that stay "dark" in both themes (dark backgrounds, light text).
   Local var overrides cascade to descendants, so any utility class inside
   resolves against the dark palette regardless of the global theme. */
nav,
[data-carousel] .absolute,     /* carousel caption overlay sits on a dark gradient */
.tri-stay-dark,
#sidebar {
  --ink-rgb: 232 221 201;
  --bg-rgb: 15 20 25;
  --border-rgb: 42 51 64;
}

/* --- Text colour overrides ---------------------------------------
   Selectors are prefixed with `html` so they beat Tailwind CDN's
   late-injected utilities (same single-class specificity otherwise).
   `html` + class = (0,1,1) > Tailwind's (0,1,0). */
html .text-parchment        { color: rgb(var(--ink-rgb)); }
html .text-parchment\/95    { color: rgb(var(--ink-rgb) / 0.95); }
html .text-parchment\/90    { color: rgb(var(--ink-rgb) / 0.90); }
html .text-parchment\/85    { color: rgb(var(--ink-rgb) / 0.85); }
html .text-parchment\/80    { color: rgb(var(--ink-rgb) / 0.80); }
html .text-parchment\/75    { color: rgb(var(--ink-rgb) / 0.75); }
html .text-parchment\/70    { color: rgb(var(--ink-rgb) / 0.70); }
html .text-parchment\/65    { color: rgb(var(--ink-rgb) / 0.65); }
html .text-parchment\/60    { color: rgb(var(--ink-rgb) / 0.60); }
html .text-parchment\/55    { color: rgb(var(--ink-rgb) / 0.55); }
html .text-parchment\/50    { color: rgb(var(--ink-rgb) / 0.50); }
html .text-parchment\/45    { color: rgb(var(--ink-rgb) / 0.45); }
html .text-parchment\/40    { color: rgb(var(--ink-rgb) / 0.40); }
html .text-parchment\/35    { color: rgb(var(--ink-rgb) / 0.35); }
html .text-parchment\/30    { color: rgb(var(--ink-rgb) / 0.30); }
html .text-parchment\/25    { color: rgb(var(--ink-rgb) / 0.25); }
html .text-parchment\/20    { color: rgb(var(--ink-rgb) / 0.20); }

html .hover\:text-parchment:hover { color: rgb(var(--ink-rgb)); }
html .group:hover .group-hover\:text-parchment { color: rgb(var(--ink-rgb)); }

/* --- Background overrides --------------------------------------- */
html .bg-slate            { background-color: rgb(var(--bg-rgb)); }
html .bg-slate\/95        { background-color: rgb(var(--bg-rgb) / 0.95); }
html .bg-slate\/90        { background-color: rgb(var(--bg-rgb) / 0.90); }
html .bg-slate\/70        { background-color: rgb(var(--bg-rgb) / 0.70); }
html .bg-slate\/60        { background-color: rgb(var(--bg-rgb) / 0.60); }
html .bg-slate\/50        { background-color: rgb(var(--bg-rgb) / 0.50); }
html .bg-slate\/40        { background-color: rgb(var(--bg-rgb) / 0.40); }
html .bg-slate\/30        { background-color: rgb(var(--bg-rgb) / 0.30); }
html .bg-slate\/20        { background-color: rgb(var(--bg-rgb) / 0.20); }
html .hover\:bg-slate:hover     { background-color: rgb(var(--bg-rgb)); }
html .hover\:bg-slate\/50:hover { background-color: rgb(var(--bg-rgb) / 0.50); }
html .hover\:bg-slate\/30:hover { background-color: rgb(var(--bg-rgb) / 0.30); }

/* --- Brass overrides ---------------------------------------------
   In dark mode brass is #C8A95C (gold). On bone that fails contrast,
   so light mode swaps to a deeper gilt (~5:1 against bone). Same
   variable-based pattern as ink/bg. */
html .text-brass            { color: rgb(var(--brass-rgb)); }
html .text-brass\/60        { color: rgb(var(--brass-rgb) / 0.60); }
html .text-brass\/50        { color: rgb(var(--brass-rgb) / 0.50); }
html .text-brass\/40        { color: rgb(var(--brass-rgb) / 0.40); }
html .hover\:text-brass:hover { color: rgb(var(--brass-rgb)); }
html .group:hover .group-hover\:text-brass { color: rgb(var(--brass-rgb)); }
html .border-brass          { border-color: rgb(var(--brass-rgb)); }
html .border-brass\/60      { border-color: rgb(var(--brass-rgb) / 0.60); }
html .border-brass\/50      { border-color: rgb(var(--brass-rgb) / 0.50); }
html .border-brass\/40      { border-color: rgb(var(--brass-rgb) / 0.40); }
html .hover\:border-brass:hover { border-color: rgb(var(--brass-rgb)); }
html .bg-brass              { background-color: rgb(var(--brass-rgb)); }
html .bg-brass\/10          { background-color: rgb(var(--brass-rgb) / 0.10); }
html .hover\:bg-brass:hover { background-color: rgb(var(--brass-rgb)); }
html .decoration-brass      { text-decoration-color: rgb(var(--brass-rgb)); }
html .decoration-brass\/40  { text-decoration-color: rgb(var(--brass-rgb) / 0.40); }

/* --- Border overrides ------------------------------------------- */
/* `border-border` is the subtle hairline used for cards, table rows, etc.
   We want it readable but not assertive in both themes — alpha 0.2 in
   light mode against bone reads as a soft pencil-line. */
html .border-border       { border-color: rgb(var(--border-rgb) / var(--border-alpha, 1)); }
html.light .border-border { --border-alpha: 0.20; }
html .hover\:border-border:hover { border-color: rgb(var(--border-rgb)); }
html .divide-border > * + * { border-color: rgb(var(--border-rgb) / var(--border-alpha, 1)); }
html.light .divide-border > * + * { --border-alpha: 0.20; }

/* ============================================================
   Theme-aware component helpers — one class per semantic role.

   The pattern across the app was: `class="w-full bg-slate/40
   light:bg-bone border border-border light:border-ink/25 px-3 py-2
   text-parchment light:text-ink focus:..."` — repeated everywhere.

   That's tedious to write and easy to drift on. These helpers collapse
   the dark/light pair into a single class so a Jinja template (or a JS
   modal builder) only writes `class="tri-input"` and the theme handles
   itself. New components should prefer these over piling on `light:` utils.
   ============================================================ */

/* Form fields — input, textarea, select. */
.tri-input,
.tri-input-mono,
.tri-textarea,
.tri-select {
  width: 100%;
  background-color: rgba(15, 20, 25, 0.4);   /* slate/40 */
  border: 1px solid #2A3340;                 /* border (dark) */
  color: #E8DDC9;                            /* parchment */
  padding: 0.5rem 0.75rem;                   /* py-2 px-3 */
  outline: none;
  transition: border-color 150ms ease;
}
.tri-input:focus,
.tri-input-mono:focus,
.tri-textarea:focus,
.tri-select:focus { border-color: #C8A95C; } /* brass */
.tri-input-mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; }
.tri-textarea { line-height: 1.5; resize: vertical; }

html.light .tri-input,
html.light .tri-input-mono,
html.light .tri-textarea,
html.light .tri-select {
  background-color: #F5EFE0;                 /* bone */
  border-color: rgba(31, 36, 44, 0.25);      /* ink/25 */
  color: #1F242C;                            /* ink */
}

/* Native <select> arrow styling — kill the OS chevron and draw our own
   inline SVG so dropdowns match the rest of the form. Applies to any
   <select> using either .tri-input or .tri-select (so existing markup
   that just used .tri-input picks this up app-wide). */
select.tri-input,
select.tri-input-mono,
.tri-select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path fill='none' stroke='%23C8A95C' stroke-width='1.5' d='M2 4l4 4 4-4'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 0.75rem 0.75rem;
  padding-right: 2.25rem;                    /* room for the chevron */
  cursor: pointer;
}
html.light select.tri-input,
html.light select.tri-input-mono,
html.light .tri-select {
  /* Same chevron, ink color for light mode. */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path fill='none' stroke='%231F242C' stroke-width='1.5' d='M2 4l4 4 4-4'/></svg>");
}
/* Open-state focus — keep the brass border consistent with text inputs. */
select.tri-input:focus,
select.tri-input-mono:focus,
.tri-select:focus { border-color: #C8A95C; }

/* Field label — used above .tri-input. */
.tri-label {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(232, 221, 201, 0.6);           /* parchment/60 */
  margin-bottom: 0.25rem;
}
html.light .tri-label { color: rgba(31, 36, 44, 0.6); }

/* Help-text under a field. */
.tri-help {
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: rgba(232, 221, 201, 0.4);
}
html.light .tri-help { color: rgba(31, 36, 44, 0.45); }

/* Modal panel — admin.js builds these. Background swaps in light mode. */
.tri-modal-panel {
  background-color: #0F1419;                 /* slate */
  color: #E8DDC9;
  border: 1px solid #2A3340;
}
html.light .tri-modal-panel {
  background-color: #F5EFE0;
  color: #1F242C;
  border-color: rgba(31, 36, 44, 0.2);
}
.tri-modal-divider { border-color: #2A3340; }
html.light .tri-modal-divider { border-color: rgba(31, 36, 44, 0.15); }

/* Toast — bottom-right notice. */
.tri-toast {
  background-color: #0F1419;
  color: #E8DDC9;
  border: 1px solid rgba(200, 169, 92, 0.6); /* brass/60 default */
}
html.light .tri-toast {
  background-color: #F5EFE0;
  color: #1F242C;
}

/* Secondary action button (cancel-style). */
.tri-btn-secondary {
  border: 1px solid #2A3340;
  color: rgba(232, 221, 201, 0.7);
  padding: 0.5rem 1rem;
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  transition: border-color 150ms ease, color 150ms ease;
}
.tri-btn-secondary:hover { border-color: #E8DDC9; color: #E8DDC9; }
html.light .tri-btn-secondary {
  border-color: rgba(31, 36, 44, 0.3);
  color: rgba(31, 36, 44, 0.7);
}
html.light .tri-btn-secondary:hover { border-color: #1F242C; color: #1F242C; }

/* ================================================================
   Sidebar navigation — unified collapsible left nav
   Replaces the top nav bar + dashboard tab strip.
   Width is driven by a CSS variable so body padding and sidebar
   width animate together when the collapse class toggles.
   ================================================================ */

:root { --sidebar-w: 220px; }
html.sidebar-collapsed { --sidebar-w: 54px; }

body {
  padding-left: var(--sidebar-w);
  transition: padding-left 0.2s ease;
}

#sidebar {
  width: var(--sidebar-w);
  transition: width 0.2s ease;
  overflow: hidden;
}

/* Collapse: hide text labels, chevrons, sub-nav lists, and the header logo.
   The logo anchor is ~28px wide; with padding + logo + gap + toggle button
   the header needs ~86px but the collapsed rail is only 54px. Hiding the
   logo lets the toggle button fit and remain clickable. */
html.sidebar-collapsed #sidebar .sidebar-label,
html.sidebar-collapsed #sidebar .sidebar-chevron,
html.sidebar-collapsed #sidebar [data-sidebar-subnav],
html.sidebar-collapsed #sidebar .sidebar-logo {
  display: none !important;
}

/* Collapsed: the framed-logo header still carries padding even with
   the logo hidden; collapse it to a thin divider row. */
html.sidebar-collapsed #sidebar > div:first-child {
  padding-top: 0.4rem;
  padding-bottom: 0.4rem;
  background: none;
  border-bottom-color: rgb(var(--border-rgb) / 0.4);
}
/* Collapsed footer: control buttons center inside the narrow rail.
   Theme + collapse stack vertically when the rail can't fit them
   side-by-side. */
html.sidebar-collapsed #sidebar > div:last-child {
  flex-direction: column;
  gap: 0.4rem;
}

/* Collapsed: centre icons in the narrower rail */
html.sidebar-collapsed #sidebar .sidebar-dept-btn,
html.sidebar-collapsed #sidebar .sidebar-page-link {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
}

/* Dept button — base, hover, active */
#sidebar .sidebar-dept-btn,
#sidebar .sidebar-page-link {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  padding: 0.6rem 0.75rem;
  text-align: left;
  transition: background 0.12s, color 0.12s;
}
#sidebar .sidebar-dept-btn:hover,
#sidebar .sidebar-page-link:hover {
  background: rgb(var(--brass-rgb) / 0.09);
}
#sidebar [data-sidebar-dept].is-active > .sidebar-dept-btn,
#sidebar [data-sidebar-page].is-active > .sidebar-page-link {
  background: rgb(var(--brass-rgb) / 0.12);
}
#sidebar [data-sidebar-dept].is-active > .sidebar-dept-btn .sidebar-dept-icon,
#sidebar [data-sidebar-dept].is-active > .sidebar-dept-btn .sidebar-dept-label,
#sidebar [data-sidebar-page].is-active > .sidebar-page-link .sidebar-dept-icon,
#sidebar [data-sidebar-page].is-active > .sidebar-page-link .sidebar-dept-label {
  color: rgb(var(--brass-rgb));
}

/* Dept icon — the character shown in both expanded and collapsed states.
   Bumped up in the 2026-05-26 polish pass so the four formerly-bleh
   glyphs (Operations / My Unit / My Profile / Admin) and the new
   State glyph have presence in the rail. */
#sidebar .sidebar-dept-icon {
  flex-shrink: 0;
  width: 1.25rem;
  text-align: center;
  font-size: 1rem;
  line-height: 1;
  color: rgb(var(--ink-rgb) / 0.6);
  transition: color 0.12s;
}
#sidebar .sidebar-dept-btn:hover .sidebar-dept-icon,
#sidebar .sidebar-page-link:hover .sidebar-dept-icon {
  color: rgb(var(--brass-rgb));
}

/* Dept label text */
#sidebar .sidebar-dept-label {
  flex: 1;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: rgb(var(--ink-rgb) / 0.72);
  white-space: nowrap;
  overflow: hidden;
  transition: color 0.12s;
}
#sidebar .sidebar-dept-btn:hover .sidebar-dept-label,
#sidebar .sidebar-page-link:hover .sidebar-dept-label {
  color: rgb(var(--brass-rgb));
}

/* Chevron — rotates when accordion is open */
#sidebar .sidebar-chevron {
  flex-shrink: 0;
  font-size: 0.55rem;
  color: rgb(var(--ink-rgb) / 0.35);
  transition: color 0.12s, transform 0.15s;
}
#sidebar .sidebar-dept-btn:hover .sidebar-chevron { color: rgb(var(--brass-rgb) / 0.6); }
#sidebar [data-sidebar-dept].is-open > .sidebar-dept-btn .sidebar-chevron {
  transform: rotate(0deg);
}
#sidebar [data-sidebar-dept]:not(.is-open) > .sidebar-dept-btn .sidebar-chevron {
  transform: rotate(-90deg);
}

/* Sub-nav panel */
#sidebar [data-sidebar-subnav] {
  overflow: hidden;
}
#sidebar .sidebar-subnav-link {
  display: flex;
  align-items: center;
  padding: 0.3rem 0.75rem 0.3rem 2.4rem;
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: rgb(var(--ink-rgb) / 0.45);
  border-left: 2px solid transparent;
  white-space: nowrap;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
#sidebar .sidebar-subnav-link:hover {
  color: rgb(var(--brass-rgb));
  border-left-color: rgb(var(--brass-rgb) / 0.45);
  background: rgb(var(--brass-rgb) / 0.06);
}
#sidebar .sidebar-subnav-link.is-active {
  color: rgb(var(--brass-rgb));
  border-left-color: rgb(var(--brass-rgb));
  background: rgb(var(--brass-rgb) / 0.1);
}

/* Sidebar dividers */
#sidebar .sidebar-divider {
  height: 1px;
  margin: 0.4rem 0.75rem;
  background: rgb(var(--border-rgb) / 0.5);
}

/* Mobile: sidebar slides off-screen, body has no left padding */
@media (max-width: 767px) {
  :root        { --sidebar-w: 0px; }
  html.sidebar-collapsed { --sidebar-w: 0px; }

  #sidebar {
    width: 220px !important;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
  }
  #sidebar.mobile-open {
    transform: translateX(0);
    box-shadow: 4px 0 24px rgb(0 0 0 / 0.45);
  }
  #sidebar-mobile-btn {
    display: flex;
  }
  #sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgb(0 0 0 / 0.5);
    z-index: 39;
    cursor: pointer;
  }
  #sidebar-backdrop.visible { display: block; }
}
@media (min-width: 768px) {
  #sidebar-mobile-btn { display: none !important; }
  #sidebar-backdrop   { display: none !important; }
}
