/* MeshTender app-specific styles layered on top of Tabler.
   Everything generic (cards, forms, buttons, tables, badges, dropdowns) comes
   from Tabler; this file only covers things Tabler has no component for: the
   live console/event log, the Leaflet map, and the public-key code block. */

/* ---------- Text selection ----------
   The dark theme's default selection highlight is nearly invisible inside form
   controls; force a high-contrast highlight everywhere, inputs included. */
::selection {
  background-color: var(--tblr-primary);
  color: #fff;
}
input::selection,
textarea::selection {
  background-color: var(--tblr-primary);
  color: #fff;
}

/* ---------- Back links (icon + text, plain link — not a button) ----------
   These are navigational "← All organizations" links. Styling them as a plain
   link (rather than .btn .btn-link) avoids the button's inline-flex box being
   icon-height tall but text-width wide, which made the focus/hover state show
   asymmetric padding (flush left/right, padded top/bottom). */
.back-link {
  display: inline-flex;
  align-items: center;
  color: var(--tblr-link-color);
  text-decoration: none;
}
/* a.back-link beats Tabler's `a:hover:has(.icon){text-decoration:none}`. */
a.back-link:hover {
  color: var(--tblr-link-hover-color);
  text-decoration: underline;
}
.back-link .icon {
  width: 1.25rem;
  height: 1.25rem;
}

/* ---------- Public-key / monospace code blocks ---------- */
code.pk,
code.pubkey {
  display: block;
  word-break: break-all;
  background: var(--tblr-bg-surface-secondary);
  border: 1px solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius);
  padding: 0.5rem 0.625rem;
  font-size: 0.8125rem;
  /* gray-400, not --tblr-secondary (#6b7280): the latter is only 3.67:1 on the
     near-black panel bg and fails WCAG AA for this key/data text. */
  color: var(--tblr-gray-400);
}

/* ---------- Collapse toggle label (Show/Hide) ---------- */
.collapse-hide {
  display: none;
}
[aria-expanded="true"] .collapse-show {
  display: none;
}
[aria-expanded="true"] .collapse-hide {
  display: inline;
}

/* A row's expanded panel (account page credential rows) lines up with the row's
   heading rather than with the icon gutter to its left: one .icon (1.25rem) plus
   one g-3 grid gutter (1rem). Hardcoded rather than read from --tblr-icon-size,
   which Tabler redefines per component context. */
.row-panel {
  padding-left: 2.25rem;
}

/* A chevron on a collapse toggle: points down when the panel is closed, up when
   it's open. Bootstrap maintains aria-expanded on the toggle itself, so the same
   attribute the Show/Hide labels key off drives this too — no JS of our own. */
.collapse-chevron {
  transition: transform 0.2s ease;
}
[aria-expanded="true"] .collapse-chevron {
  transform: rotate(180deg);
}

/* ---------- Live event / console log ---------- */
.evlog {
  list-style: none;
  margin: 0;
  padding: 0.75rem;
  background: var(--tblr-bg-surface-secondary);
  border: 1px solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius);
  max-height: 240px;
  overflow-y: auto;
  font-family: var(--tblr-font-monospace);
  font-size: 0.8125rem;
}
.evlog:empty { display: none; }
.evlog.console { max-height: 320px; }
.ev { padding: 0.15rem 0; border-bottom: 1px solid var(--tblr-border-color-translucent); }
.ev:last-child { border-bottom: none; }
/* Colors chosen for WCAG AA (≥4.5:1) on the near-black log background:
   --tblr-secondary (#6b7280) and --tblr-danger (#d63939) only reach ~3.7:1,
   so info uses the lighter gray-400 and errors the lighter danger emphasis. */
.ev-info { color: var(--tblr-gray-400); }
.ev-confirmed { color: var(--tblr-success); font-weight: 600; }
.ev-error, .ev-timeout { color: var(--tblr-danger-text-emphasis); }
.ev-warning, .ev-denied, .ev-noreply { color: var(--tblr-warning); }
.ev-debug { color: var(--tblr-info); word-break: break-all; }
.ev-sent { color: var(--tblr-azure); }
.ev-reply { color: var(--tblr-body-color); white-space: pre-wrap; }

/* ---------- Badge contrast (dark) ----------
   Tabler's light "-lt" badges set their text to the full-strength brand color
   over a 10%-opacity tint, which is too dark for this small status text on the dark
   theme. The list below is now maintained by TestContrastMeetsWCAGAA rather than by
   eye — an earlier by-hand pass asserted "azure/success/warning/yellow already pass",
   and azure (4.15:1) and teal (4.13:1) in fact did not.

   Where Tabler defines a dark-theme *-text-emphasis value, use it; the rest are mixed
   toward white against their own palette variable, so they stay tied to the palette
   instead of becoming hand-picked hexes. */
.badge.bg-purple-lt { color: #d98fe6 !important; }
.badge.bg-secondary-lt { color: var(--tblr-secondary-text-emphasis) !important; }
.badge.bg-blue-lt { color: var(--tblr-primary-text-emphasis) !important; }
.badge.bg-azure-lt { color: color-mix(in srgb, var(--tblr-azure) 80%, #fff) !important; }
.badge.bg-teal-lt { color: color-mix(in srgb, var(--tblr-teal) 80%, #fff) !important; }

/* Tabler's danger button pairs its off-white foreground (#f9fafb) with the danger red,
   which measures 4.46:1 — just under the 4.5:1 floor. Pure white reaches 4.66:1 without
   touching the button's color. */
.btn-danger {
  color: #fff;
}

/* ---------- Contrast corrections (WCAG AA on the dark theme) ----------
   Found by internal/e2e TestContrastMeetsWCAGAA, which measures rendered pixels. All
   three point at Tabler's own dark-theme *-text-emphasis values rather than
   hand-picked colors, so they stay tied to the palette.

   Tabler's dark theme lightens --tblr-link-hover-color but NOT --tblr-link-color, which
   leaves every link at 3.55:1 on the page background and 2.94:1 on a card — below the
   4.5:1 AA floor for body text. Emphasis blue measures 7.07:1 and 5.85:1. .back-link
   already reads --tblr-link-color, so it's fixed by this too. */
:root {
  --tblr-link-color: var(--tblr-primary-text-emphasis);
}

/* Inactive tab labels use --tblr-muted (#6b7280 → 3.67:1). Emphasis gray is 7.65:1 and
   still clearly dimmer than the active tab, which uses the full body color. */
.nav-tabs .nav-link {
  color: var(--tblr-secondary-text-emphasis);
}

/* ---------- Members list filter (org members page) ----------
   The members page filters rows by role + search in JS (text search can't be
   pure CSS). Rows carry `.d-flex` (display:flex !important), so the JS toggles
   this `!important` hide class rather than an inline style, which `.d-flex`
   would otherwise win over. */
#member-list .member-hidden {
  display: none !important;
}

/* ---------- Step indicator (.steps) ----------
   Tabler ships two unrelated components under the same `.steps` class: the
   horizontal step indicator (ul.steps > li.step-item) we use on the add/added
   wizards, and a numbered documentation list (div.steps > h3). The latter's
   rule sets border-left + a left margin/padding, which also lands on the step
   indicator — drawing a stray vertical line and an empty gap before the first
   step. Undo those just for the indicator usage. */
.steps:has(> .step-item) {
  margin-left: 0;
  padding-left: 0;
  border-left: 0;
}

/* ---------- MapLibre map (dark) ---------- */
#map {
  height: 360px;
  border-radius: var(--tblr-border-radius);
  border: 1px solid var(--tblr-border-color);
}
/* Painted behind the WebGL canvas, so it shows while tiles are still in flight
   rather than a white flash on a dark page. */
.maplibregl-map { background: #14171c; }
/* Scoped under .maplibregl-popup so these beat MapLibre's own defaults, which load
   after app.css (maplibre-gl.css is pulled in per-page in the map card body). */
.maplibregl-popup .maplibregl-popup-content {
  background: var(--tblr-bg-surface);
  color: var(--tblr-body-color);
  box-shadow: var(--tblr-box-shadow, 0 1px 2px rgba(0, 0, 0, 0.4));
}
.maplibregl-popup-anchor-top .maplibregl-popup-tip { border-bottom-color: var(--tblr-bg-surface); }
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip { border-top-color: var(--tblr-bg-surface); }
.maplibregl-popup-anchor-left .maplibregl-popup-tip { border-right-color: var(--tblr-bg-surface); }
.maplibregl-popup-anchor-right .maplibregl-popup-tip { border-left-color: var(--tblr-bg-surface); }
.maplibregl-popup-close-button { color: var(--tblr-body-color); }

/* Controls: the zoom buttons, plus our own two button groups (the Dark/Light
   basemap switch and the region-editor draw tools, both built in JS — see
   basemap.js and regionmap.js). MapLibre's default control is a white box, which
   is wrong on every page we render.

   Everything here is scoped under .maplibregl-map purely to win the cascade:
   maplibre-gl.css is pulled in per-page in the map card body, so it loads *after*
   app.css and an equally specific rule of ours loses to it. The tell when this is
   missing is subtle — the buttons we style by state still look right, and only the
   unpressed ones stay white. */
.maplibregl-map .maplibregl-ctrl-group {
  background: var(--tblr-bg-surface);
  box-shadow: var(--tblr-box-shadow, 0 1px 2px rgba(0, 0, 0, 0.4));
}
.maplibregl-map .maplibregl-ctrl-group button { color: var(--tblr-body-color); }
/* The zoom glyphs are background-image SVGs with a hard-coded #333 fill — fine on
   MapLibre's white control, invisible on our dark one, and not restyleable because
   the color lives inside the data: URI. Inverting the icon is the way to reach it. */
.maplibregl-map .maplibregl-ctrl-group button .maplibregl-ctrl-icon { filter: invert(1); }
.maplibregl-map .maplibregl-ctrl-group button + button { border-top-color: var(--tblr-border-color); }
.maplibregl-map .maplibregl-ctrl-group button:not(:disabled):hover { background: var(--tblr-bg-surface-secondary); }
/* MapLibre's icon buttons are square and unlabeled; ours carry text, so they need
   width and horizontal padding or the label is clipped to a 29px box. */
.maplibregl-map .mesh-basemap-ctrl button,
.maplibregl-map .mesh-draw-ctrl button {
  width: auto;
  min-width: 4.5rem;
  padding: 0 0.5rem;
  font-size: 0.75rem;
  line-height: 1.75rem;
}
/* aria-pressed is the state, so it is also what styles the active button — there
   is no second class to keep in sync. */
.maplibregl-map .mesh-basemap-ctrl button[aria-pressed="true"],
.maplibregl-map .mesh-draw-ctrl button[aria-pressed="true"] {
  background: var(--tblr-primary);
  color: #fff;
}
.maplibregl-map .mesh-draw-ctrl button:disabled { opacity: 0.45; }
/* The attribution CARTO require stays visible; only its chrome is themed. It sits
   over the map, not the page, so it is deliberately NOT painted in theme tokens:
   the same strip has to stay legible over both the near-black Dark Matter basemap
   and the near-white Voyager one, which a token that only knows the page theme
   cannot do. A dark scrim with near-white text reads on both. */
.maplibregl-map .maplibregl-ctrl.maplibregl-ctrl-attrib {
  /* Both class names, because upstream's own rule is .maplibregl-ctrl.maplibregl-
     ctrl-attrib — matching only one of them ties on specificity and loses, which
     shows up as white-on-white text rather than as nothing happening. */
  background: rgba(0, 0, 0, 0.7);
  color: #f4f6fa;
}
.maplibregl-map .maplibregl-ctrl-attrib a,
.maplibregl-map .maplibregl-ctrl-attrib a:hover { color: #f4f6fa; }

/* Profile list on the org config page: a long list scrolls inside its card
   instead of pushing the location-preview map off the page. Rows are compact —
   Tabler's default list-group padding plus a full-size icon button makes a ~4.5rem
   row, so only a couple fit before scrolling. Both are driven by CSS variables, so
   turn those down here rather than overriding the padding itself. */
.profile-list {
  max-height: 22rem;
  overflow-y: auto;
}
.profile-list .list-group-item {
  --tblr-list-group-item-padding-y: 0.375rem;
}
.profile-list .btn-icon {
  --tblr-btn-padding-y: 0.25rem;
  --tblr-btn-icon-size: 1.25rem;
}

/* Active region block in the config editor: highlight the block currently being
   drawn on the shared region map. */
.region-block.region-active {
  border-color: var(--tblr-primary) !important;
  box-shadow: 0 0 0 1px var(--tblr-primary);
}

/* Footer on the centered auth layout (authbase). footerbody right-packs its two
   columns, which suits a full-width page but reads as misaligned under a narrow
   centered card, so center them here instead. */
.footer-centered .row {
  justify-content: center;
}

/* Undo Tabler's scrollbar compensation, which shifts the whole page sideways.
   @media (min-width:992px) it sets `:root { margin-left: calc(100vw - 100%) }` —
   100vw includes the scrollbar, 100% doesn't, so a page long enough to scroll gets a
   left margin the width of the scrollbar. The intent is to stop layout shifting when
   a scrollbar appears, but the result is that every scrollable page sits ~15px right
   of the window with an unpainted strip down the left edge, navbar included (it was
   visible on the org Repeaters and Configuration tabs, and absent on the shorter Home
   and Members tabs, which is what made it look page-specific).

   scrollbar-gutter reserves the space on the correct side instead: no shift when the
   scrollbar appears, no gutter on the left. Where it isn't supported the declaration
   is ignored, which lands on the plain browser behavior rather than back on the
   sideways shift. Overlay scrollbars (macOS, mobile) take no space at all, so the
   gutter is a no-op there.

   Overriding here rather than editing tabler.min.css keeps that file byte-identical
   to the audited upstream artifact (internal/licenses pins its hash). */
:root {
  scrollbar-gutter: stable;
}
@media (min-width: 992px) {
  :root {
    margin-left: 0;
  }
}
