/* ============================================================
   Conjunto layout — fixed topbar / fixed sidebar(s) / fixed statusbar
   ============================================================
   Required CSS variables (set on <body>):
     --cj-navbar-height
     --cj-statusbar-height
     --cj-sidebar-left-width        (free-drag, "full" mode only)
     --cj-sidebar-left-mini-width
     --cj-sidebar-right-width       (free-drag, "full" mode only)
     --cj-sidebar-right-mini-width
   Body classes (exactly one per side):
     .cj-sidebar-{left,right}-mode-full       → text + icons, free-drag width
     .cj-sidebar-{left,right}-mode-mini       → icons only; flyout submenus
     .cj-sidebar-{left,right}-mode-collapsed  → sidebar fully out of layout
   Additional (mobile only):
     .cj-sidebar-{left,right}-open            → overlay visible (< 992px)
*/

:root {
    --cj-navbar-height: 3.5rem;
    --cj-statusbar-height: 2.5rem;
    --cj-sidebar-left-width: 15rem;
    --cj-sidebar-left-mini-width: 3.5rem;
    --cj-sidebar-right-width: 20rem;
    --cj-sidebar-right-mini-width: 3.5rem;
    --cj-sidebar-bg: var(--tblr-bg-surface, #fff);
    --cj-sidebar-border: var(--tblr-border-color, rgba(0, 0, 0, 0.08));
    /* Stacking order, foreground → background:
       sidebar (1050) > backdrop (1045) > topbar/statusbar (1030).
       Sidebar must stay above the topbar so dropdowns/avatar/bell
       opened from the topbar do not punch through the mobile
       overlay. The backdrop sits below the sidebar but still above
       the topbar so the dimming covers the chrome too. */
    --cj-z-topbar: 1030;
    --cj-z-statusbar: 1030;
    --cj-z-backdrop: 1045;
    --cj-z-sidebar: 1050;
}

/* ── Topbar ───────────────────────────────────────────────── */
#cj-topbar {
    z-index: var(--cj-z-topbar);
    border-bottom: 1px solid var(--cj-sidebar-border);
    background: var(--tblr-bg-surface, #fff);
}

/* ── Sidebars (always position:fixed) ─────────────────────── */
.cj-sidebar-left,
.cj-sidebar-right {
    position: fixed;
    top: var(--cj-navbar-height);
    bottom: var(--cj-statusbar-height);
    z-index: var(--cj-z-sidebar);
    background: var(--cj-sidebar-bg);
    overflow-y: auto;
    overflow-x: hidden;
    transition: transform 0.25s ease, width 0.25s ease;
    transform: translateX(0);
    /* Thin, unobtrusive scrollbar — the thumb only materialises on hover so
       a tall menu (especially in the narrow mini mode) doesn't show Chrome's
       chunky default bar. */
    scrollbar-width: thin;
    scrollbar-color: transparent transparent;
}

.cj-sidebar-left:hover,
.cj-sidebar-right:hover {
    scrollbar-color: var(--tblr-border-color, rgba(0, 0, 0, 0.2)) transparent;
}

.cj-sidebar-left::-webkit-scrollbar,
.cj-sidebar-right::-webkit-scrollbar {
    width: 6px;
}

.cj-sidebar-left::-webkit-scrollbar-thumb,
.cj-sidebar-right::-webkit-scrollbar-thumb {
    background: transparent;
    border-radius: 3px;
}

.cj-sidebar-left:hover::-webkit-scrollbar-thumb,
.cj-sidebar-right:hover::-webkit-scrollbar-thumb {
    background: var(--tblr-border-color, rgba(0, 0, 0, 0.2));
}

.cj-sidebar-left {
    left: 0;
    width: var(--cj-sidebar-left-width);
    border-right: 1px solid var(--cj-sidebar-border);
}

.cj-sidebar-right {
    right: 0;
    width: var(--cj-sidebar-right-width);
    border-left: 1px solid var(--cj-sidebar-border);
}

/* ── Sidebar resize handle (desktop only) ────────────────── */
.cj-sidebar-resize {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 6px;
    cursor: col-resize;
    z-index: 1;
    background: transparent;
    transition: background 0.15s ease;
}

.cj-sidebar-left-resize { right: 0; }
.cj-sidebar-right-resize { left: 0; }

.cj-sidebar-resize:hover,
body.cj-sidebar-resizing .cj-sidebar-resize {
    background: rgba(var(--tblr-primary-rgb, 32, 107, 196), 0.3);
}

body.cj-sidebar-resizing .cj-sidebar-left,
body.cj-sidebar-resizing .cj-sidebar-right,
body.cj-sidebar-resizing .cj-page-content {
    transition: none;
}

body.cj-sidebar-resizing {
    user-select: none;
    -webkit-user-select: none;
    cursor: col-resize;
}

.cj-sidebar-nav {
    list-style: none;
    margin: 0;
    padding: 0.5rem 0;
    display: flex;
    flex-direction: column;
}

.cj-sidebar-nav .nav-item {
    width: 100%;
}

.cj-sidebar-nav .nav-link {
    display: flex;
    align-items: center;
    padding: 0.5rem 1rem;
    color: var(--tblr-body-color);
    text-decoration: none;
    border-radius: 0;
}

.cj-sidebar-nav .nav-link-icon {
    display: inline-flex;
    align-items: center;
    margin-right: 0.5rem;
    font-size: 1.1rem;
    width: 1.25rem;
}

.cj-sidebar-nav .nav-link-title {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cj-sidebar-nav .nav-link.active,
.cj-sidebar-nav .nav-item.active > .cj-sidebar-row > .nav-link {
    color: var(--tblr-primary);
    background: rgba(var(--tblr-primary-rgb, 32, 107, 196), 0.08);
}

.cj-sidebar-nav .nav-link:hover {
    background: rgba(var(--tblr-primary-rgb, 32, 107, 196), 0.05);
}

.cj-sidebar-nav .nav-link.disabled,
.cj-sidebar-nav .nav-link.disabled:hover {
    color: var(--tblr-nav-link-disabled-color, var(--tblr-disabled-color));
    background: transparent;
    opacity: 0.55;
    pointer-events: none;
    cursor: default;
}

/* Submenu (level 2) — indented, no nested children */
.cj-sidebar-nav .nav-submenu {
    list-style: none;
    margin: 0;
    padding: 0;
    background: rgba(0, 0, 0, 0.02);
}

.cj-sidebar-nav .nav-submenu .nav-link {
    padding-left: 2.75rem;
    font-size: 0.875rem;
}

/* Right-sidebar widget stack — same vertical rhythm as the nav above. */
.cj-sidebar-right-stack {
    padding: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Inline action button: half-opacity until row hover */
.cj-sidebar-action {
    flex: 0 0 auto;
    opacity: 0.35;
    transition: opacity 0.15s ease;
}

.cj-sidebar-row:hover .cj-sidebar-action {
    opacity: 1;
}

/* Collapse arrow rotation */
.cj-sidebar-arrow {
    transition: transform 0.2s ease;
    flex: 0 0 auto;
}

.cj-sidebar-nav [aria-expanded="true"] .cj-sidebar-arrow {
    transform: rotate(90deg);
}

/* Chevron toggle button sits next to the nav-link — keep it visually flush */
.cj-sidebar-nav .cj-sidebar-toggle {
    background: transparent;
    color: inherit;
}

.cj-sidebar-nav .cj-sidebar-toggle:hover {
    background: rgba(var(--tblr-primary-rgb, 32, 107, 196), 0.05);
}

.cj-sidebar-divider {
    list-style: none;
    height: 1px;
    background: var(--cj-sidebar-border);
    margin: 0.5rem 0;
}

/* ── Page title icon ──────────────────────────────────────── */
.page-title-icon:empty {
    display: none;
}
.page-title-icon:not(:empty) {
    margin-right: 0.5rem;
}

/* ── Page content (canvas) ────────────────────────────────── */
.cj-page-content {
    margin-left: var(--cj-sidebar-left-width);
    margin-right: var(--cj-sidebar-right-width);
    padding-top: var(--cj-navbar-height);
    padding-bottom: var(--cj-statusbar-height);
    min-height: 100vh;
    transition: margin 0.25s ease;
    box-sizing: border-box;
}

/* ── Left sidebar mode: mini ──────────────────────────────── */
body.cj-sidebar-left-mode-mini .cj-sidebar-left {
    width: var(--cj-sidebar-left-mini-width);
}
body.cj-sidebar-left-mode-mini .cj-page-content {
    margin-left: var(--cj-sidebar-left-mini-width);
}
body.cj-sidebar-left-mode-mini .cj-sidebar-left .nav-link-title,
body.cj-sidebar-left-mode-mini .cj-sidebar-left .badge,
body.cj-sidebar-left-mode-mini .cj-sidebar-left .cj-sidebar-arrow,
body.cj-sidebar-left-mode-mini .cj-sidebar-left .cj-sidebar-toggle,
body.cj-sidebar-left-mode-mini .cj-sidebar-left .cj-sidebar-action,
body.cj-sidebar-left-mode-mini .cj-sidebar-left .nav-submenu {
    display: none;
}
body.cj-sidebar-left-mode-mini .cj-sidebar-left .cj-sidebar-row {
    justify-content: center;
    min-height: 2.5rem;
}
body.cj-sidebar-left-mode-mini .cj-sidebar-left .cj-sidebar-link {
    justify-content: center;
    align-items: center;
    padding: 0;
    line-height: 1;
    align-self: stretch;
}
body.cj-sidebar-left-mode-mini .cj-sidebar-left .nav-link-icon {
    margin-right: 0;
    font-size: 1.5rem;  /* fs-2 */
    width: auto;
    justify-content: center;
    line-height: 1;
}
body.cj-sidebar-left-mode-mini .cj-sidebar-left .nav-link-icon > i {
    line-height: 1;
}
body.cj-sidebar-left-mode-mini .cj-sidebar-left .nav-item.active > .cj-sidebar-row,
body.cj-sidebar-left-mode-mini .cj-sidebar-left .nav-item:has(> .cj-sidebar-row > .nav-link.active) > .cj-sidebar-row {
    box-shadow: inset 3px 0 0 var(--tblr-primary);
}

/* ── Left sidebar mode: collapsed ─────────────────────────── */
body.cj-sidebar-left-mode-collapsed .cj-sidebar-left {
    transform: translateX(-100%);
}
/* Preserve the previous expanded width while collapsed so the slide-in
   animation starts from the correct off-screen offset. */
body.cj-sidebar-left-mode-collapsed[data-sidebar-left-last-expanded-mode="mini"] .cj-sidebar-left {
    width: var(--cj-sidebar-left-mini-width);
}
body.cj-sidebar-left-mode-collapsed .cj-page-content {
    margin-left: 0;
}
body.cj-sidebar-left-mode-collapsed .cj-sidebar-left-resize {
    display: none;
}

/* ── Right sidebar mode: mini ─────────────────────────────── */
body.cj-sidebar-right-mode-mini .cj-sidebar-right {
    width: var(--cj-sidebar-right-mini-width);
}
body.cj-sidebar-right-mode-mini .cj-page-content {
    margin-right: var(--cj-sidebar-right-mini-width);
}
body.cj-sidebar-right-mode-mini .cj-sidebar-right .cj-sidebar-right-stack > * > :not(.cj-sidebar-mini-marker) {
    /* Plugins can opt-in to mini-mode visibility by marking their icon
       with .cj-sidebar-mini-marker; everything else collapses. */
    display: none;
}

/* ── Right sidebar mode: collapsed ────────────────────────── */
body.cj-sidebar-right-mode-collapsed .cj-sidebar-right {
    transform: translateX(100%);
}
body.cj-sidebar-right-mode-collapsed[data-sidebar-right-last-expanded-mode="mini"] .cj-sidebar-right {
    width: var(--cj-sidebar-right-mini-width);
}
body.cj-sidebar-right-mode-collapsed .cj-page-content {
    margin-right: 0;
}
body.cj-sidebar-right-mode-collapsed .cj-sidebar-right-resize {
    display: none;
}

/* ── Topbar toggle icon swap ──────────────────────────────── */
/* Both icons render inside the same button — CSS picks the matching one
   per sidebar mode so the swap survives reloads and HTMX swaps without
   any JS coordination. Default: show the "expanded" icon, hide the
   "collapsed" one. When the body carries the collapsed-mode class for
   THIS side, flip the pair. */
#cj-sidebar-left-toggle .cj-icon-when-collapsed,
#cj-sidebar-right-toggle .cj-icon-when-collapsed {
    display: none;
}
body.cj-sidebar-left-mode-collapsed #cj-sidebar-left-toggle .cj-icon-when-expanded {
    display: none;
}
body.cj-sidebar-left-mode-collapsed #cj-sidebar-left-toggle .cj-icon-when-collapsed {
    display: inline-block;
}
body.cj-sidebar-right-mode-collapsed #cj-sidebar-right-toggle .cj-icon-when-expanded {
    display: none;
}
body.cj-sidebar-right-mode-collapsed #cj-sidebar-right-toggle .cj-icon-when-collapsed {
    display: inline-block;
}

/* ── Lock indicators ──────────────────────────────────────── */
body[data-sidebar-left-mode-locked] #cj-sidebar-left-toggle {
    pointer-events: none;
    opacity: 0.4;
}
body[data-sidebar-left-mode-locked] .cj-sidebar-left-resize {
    display: none;
}
body[data-sidebar-right-mode-locked] #cj-sidebar-right-toggle {
    pointer-events: none;
    opacity: 0.4;
}
body[data-sidebar-right-mode-locked] .cj-sidebar-right-resize {
    display: none;
}

/* ── Mini-mode flyout (legacy markup, always hidden) ──────── */
/* Mini mode no longer opens submenu flyouts — only level-1 icons are
   visible and a click follows the link's own href. The .cj-sidebar-flyout
   <ul> is still emitted by sidebar_item.html for backward compatibility
   but never displayed. Drop the markup once no plugin references it. */
.cj-sidebar-left .cj-sidebar-flyout {
    display: none !important;
}

/* ── Statusbar (always fixed bottom) ──────────────────────── */
.cj-statusbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--cj-statusbar-height);
    z-index: var(--cj-z-statusbar);
    background: var(--tblr-bg-surface, #fff);
    border-top: 1px solid var(--cj-sidebar-border);
}

/* ── Mobile (< lg = 992px): sidebars as overlay ───────────── */
@media (max-width: 991.98px) {
    /* Mobile ignores sidebar mode entirely — both sidebars are
       full-width overlays opened via the topbar toggle buttons. The
       cj-sidebar-{left,right}-mode-* classes still ride on body (they
       persist server state) but their layout effects are overridden. */
    .cj-sidebar-left,
    body.cj-sidebar-left-mode-mini .cj-sidebar-left,
    body.cj-sidebar-left-mode-collapsed .cj-sidebar-left {
        width: var(--cj-sidebar-left-width);
        transform: translateX(-100%);
        box-shadow: 0 0 1rem rgba(0, 0, 0, 0.15);
    }
    .cj-sidebar-right,
    body.cj-sidebar-right-mode-mini .cj-sidebar-right,
    body.cj-sidebar-right-mode-collapsed .cj-sidebar-right {
        width: var(--cj-sidebar-right-width);
        transform: translateX(100%);
        box-shadow: 0 0 1rem rgba(0, 0, 0, 0.15);
    }

    body.cj-sidebar-left-open .cj-sidebar-left {
        transform: translateX(0);
    }
    body.cj-sidebar-right-open .cj-sidebar-right {
        transform: translateX(0);
    }

    .cj-sidebar-resize {
        display: none;
    }

    /* No push on mobile — sidebar overlays content */
    .cj-page-content,
    body.cj-sidebar-left-mode-mini .cj-page-content,
    body.cj-sidebar-left-mode-collapsed .cj-page-content,
    body.cj-sidebar-right-mode-mini .cj-page-content,
    body.cj-sidebar-right-mode-collapsed .cj-page-content {
        margin-left: 0;
        margin-right: 0;
    }

    /* Restore mini-hidden elements so overlays behave like full mode. */
    body.cj-sidebar-left-mode-mini .cj-sidebar-left .nav-link-title,
    body.cj-sidebar-left-mode-mini .cj-sidebar-left .badge,
    body.cj-sidebar-left-mode-mini .cj-sidebar-left .cj-sidebar-arrow,
    body.cj-sidebar-left-mode-mini .cj-sidebar-left .cj-sidebar-toggle,
    body.cj-sidebar-left-mode-mini .cj-sidebar-left .cj-sidebar-action,
    body.cj-sidebar-left-mode-mini .cj-sidebar-left .nav-submenu {
        display: revert;
    }
    body.cj-sidebar-right-mode-mini .cj-sidebar-right .cj-sidebar-right-stack > * > :not(.cj-sidebar-mini-marker) {
        display: revert;
    }

    /* Backdrop — shared between both sidebars */
    body.cj-sidebar-left-open::before,
    body.cj-sidebar-right-open::before {
        content: "";
        position: fixed;
        top: var(--cj-navbar-height);
        left: 0;
        right: 0;
        bottom: var(--cj-statusbar-height);
        background: rgba(0, 0, 0, 0.4);
        z-index: var(--cj-z-backdrop);
    }
}

/* ── Misc preserved utilities ─────────────────────────────── */
a.list-group-item-actions:hover {
    text-decoration: none;
}

.spinner-border {
    display: none;
}

.tetra-request + .spinner-border,
.tetra-request.spinner-border {
    display: inline-block;
}

/* ── Sectioned-page action buttons & row-actions ─────────────────────── */
/* Two slots get the standard btn-sm + fs-2-icon + me-1-spacing centrally  */
/* so per-template repetition is unnecessary:                              */
/*                                                                         */
/*   1. .cj-sectioned-page .card-header .card-actions .btn                 */
/*      Wrapping card carries `cj-sectioned-page` (settings page +         */
/*      medux administration page).                                        */
/*   2. td.cj-row-actions .btn                                             */
/*      django-tables2 row-action column (ActionsColumn from               */
/*      conjunto.tables).                                                  */
/*                                                                         */
/* Templates write a bare ``<button class="btn btn-…"><i class="ti ti-…">``*/
/* — sizing/spacing arrives via these rules. */

.cj-sectioned-page .card-header .card-actions .btn,
td.cj-row-actions .btn {
    padding: .25rem .5rem;
    font-size: .75rem;
    line-height: 1.5;
    border-radius: var(--tblr-border-radius-sm, .375rem);
}

.cj-sectioned-page .card-header .card-actions .btn i.ti,
td.cj-row-actions .btn i.ti {
    font-size: 1.25rem;        /* tabler/Bootstrap fs-2 equivalent */
    margin-inline-end: .25rem;  /* me-1 equivalent */
}

.cj-sectioned-page .card-header .card-actions .btn.btn-icon i.ti,
td.cj-row-actions .btn.btn-icon i.ti {
    margin-inline-end: 0;
}

/* ── Button icon spacing (global) ────────────────────────────────────── */
/* Any icon+label button keeps a minimal gap between its leading icon and the
 * text, so templates never need a per-button `me-1`. Icon-only buttons must
 * carry `.btn-icon` (Tabler convention) and are excluded — a text node next to
 * the icon is not an element sibling, so CSS cannot detect it; the marker class
 * is the reliable signal. */
.btn:not(.btn-icon) > i.ti:first-child {
    margin-inline-end: .25rem;
}

/* Bootstrap utility extension. Bootstrap's spacer scale jumps from
 * `ps-4` (1.5rem) to `ps-5` (3rem); a third-level rail item needs
 * 2rem to keep the "1rem per nesting level" rhythm without using a
 * margin (which would shrink the clickable item width). */
.ps-6 { padding-inline-start: 2rem !important; }

/* {% help_hint %} icon — small blue info dot next to a section
 * title. Sized as a body-text glyph so it doesn't crowd the title;
 * cursor:help broadcasts the tooltip affordance. Visibility itself
 * is gated by the ``conjunto.show_help_hints`` scoped setting. */
.cj-help-hint {
    cursor: help;
    margin-inline-start: .25rem;
    font-size: 1rem;
    line-height: 1;
    vertical-align: -1px;
    opacity: .75;
    transition: opacity 100ms ease;
}
.cj-help-hint:hover,
.cj-help-hint:focus-visible { opacity: 1; }

/* IconSelect (form-selectgroup): suppress per-tile border, show only on
 * the checked tile. Scoped via .cj-icon-select so the rule cannot bleed
 * into other form-selectgroup uses. */
.form-selectgroup.cj-icon-select .form-selectgroup-label {
  border-color: transparent;
}
.form-selectgroup.cj-icon-select
  .form-selectgroup-input:checked
  + .form-selectgroup-label {
  border-color: var(--tblr-primary);
}

/* ButtonGroupSelect field-error feedback. Bootstrap's ``.is-invalid``
 * only styles ``<input>``/``<select>``/``.form-control`` natively, so a
 * button-radio group never lit up red. Use a red ring (matches
 * Bootstrap's danger focus shadow) instead of redrawing borders. */
.btn-group.is-invalid,
.btn-group-vertical.is-invalid {
  box-shadow: 0 0 0 .125rem var(--tblr-danger);
  border-radius: var(--tblr-border-radius, .375rem);
}

/* ButtonGroupSelect keyboard-focus visibility. ``.btn-check`` is visually
 * hidden, so a per-button focus ring would land on an invisible element
 * and Tabler's per-label focus shadow gets drowned out by the constant
 * ``--tblr-shadow-input`` on the ``.btn-group`` container. Instead, paint
 * the same halo used by ``.form-control:focus`` (tabler.css:2618) around
 * the **whole group** via ``:focus-within`` — consistent with normal
 * inputs, and the currently focused option is already visible via Tabler's
 * ``:checked`` button styling (arrow keys move focus + selection together
 * within a radio group). Scoped with ``:has(.btn-check)`` so plain toolbar
 * btn-groups are unaffected. */
.btn-group:has(.btn-check):focus-within,
.btn-group-vertical:has(.btn-check):focus-within {
  border-radius: var(--tblr-border-radius, .375rem);
  box-shadow: var(--tblr-shadow-input),
              0 0 0 0.25rem rgba(var(--tblr-primary-rgb), 0.25);
}

/* SelectGroup(as_btn_group=True) responsiveness. Tabler buttons are
 * ``white-space: nowrap``, so long choice labels overflow a phone
 * viewport and force the whole page to scroll horizontally. Like any
 * form control, the group spans the full field width; the buttons share
 * it equally and their labels may wrap. Below the md breakpoint the
 * group stacks vertically instead, mirroring Bootstrap's
 * ``.btn-group-vertical`` corner/border handling. */
.cj-btn-group {
  width: 100%;
}
.cj-btn-group > .btn {
  white-space: normal;
  flex: 1 1 0;
}

@media (max-width: 767.98px) {
  .cj-btn-group {
    flex-direction: column;
    align-items: stretch;
  }
  .cj-btn-group > .btn {
    width: 100%;
    margin-left: 0;
  }
  /* Every button after the first: collapse the shared border and square
   * the touching corners (bottom of the upper / top of the lower). The
   * ``label`` selectors skip the visually-hidden ``.btn-check`` inputs. */
  .cj-btn-group > label.btn ~ label.btn {
    margin-top: calc(var(--tblr-border-width, 1px) * -1);
    border-top-left-radius: 0;
    border-top-right-radius: 0;
  }
  .cj-btn-group > label.btn:not(:last-of-type) {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
  }
}

/* Bulk-action selection bar. Fixed to the viewport bottom while a
 * selection is active. ``x-cloak`` keeps it hidden during the
 * brief window before Alpine flips ``count > 0`` to false on first
 * render. The z-index sits above Tabler's footer (1030) but below
 * Bootstrap modal backdrops (1050+), so it disappears behind a
 * confirmation dialog rather than peeking through it. */
.cj-bulk-actions-bar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 1040;
  background: var(--tblr-bg-surface, #fff);
  border-top: 1px solid var(--tblr-border-color, rgba(0, 0, 0, .08));
  box-shadow: 0 -2px 12px rgba(0, 0, 0, .08);
  padding: .5rem 1rem;
}

.cj-bulk-actions-bar-inner {
  display: flex;
  align-items: center;
  gap: .75rem;
  max-width: 100%;
}

.cj-bulk-actions-count {
  font-weight: 500;
  white-space: nowrap;
}

.cj-bulk-select-cell {
  width: 1%;
  white-space: nowrap;
  vertical-align: middle;
}

/* TenantRole permissions — live filter (Alpine) + bounded scroll.
 * The widget toggles ``d-none`` on each ``.permission-widget__item``
 * based on the search input. Hide empty model + app groups so the
 * layout collapses while the user types.
 *
 * Modern :has() (Chrome 105+, Safari 15.4+, Firefox 121+) — fine for
 * the medux-2026 baseline; older browsers fall back to showing the
 * empty headers, which is ugly but not broken.
 *
 * The inner ``__scroll`` wrapper caps the permission list so the role
 * modal stays compact: filter input + clear stay above the fold, the
 * (potentially hundreds of) permission rows scroll inside the box.
 */
.permission-widget__model:not(:has(.permission-widget__item:not(.d-none))) {
  display: none;
}
.permission-widget__app:not(:has(.permission-widget__item:not(.d-none))) {
  display: none;
}
.permission-widget__scroll {
  max-height: min(50vh, 28rem);
  overflow-y: auto;
  border: 1px solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius);
  padding: 0.75rem;
}

/* Filter input with overlaid icons: search glyph on the left,
 * clear-X + assigned-filter funnel on the right — all clickable,
 * no separate buttons next to the input. */
.permission-widget__filter-input {
  padding-left: 2.25rem;
  padding-right: 3.5rem;
}
.permission-widget__filter-icon {
  position: absolute;
  top: 50%;
  left: 0.75rem;
  transform: translateY(-50%);
  pointer-events: none;
}
.permission-widget__filter-actions {
  position: absolute;
  top: 50%;
  right: 0.75rem;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.permission-widget__filter-actions a {
  cursor: pointer;
}

/* Sectioned-page rail live filter (settings / administration).
 * The rail rows toggle ``d-none`` from the Alpine search box; collapse
 * a whole group once all of its rows are filtered out so the rail does
 * not leave dangling group headers. Same modern :has() baseline as the
 * permission widget above; older browsers just keep the empty header. */
.cj-rail-group:not(:has(.list-group-item-action:not(.d-none))) {
  display: none;
}

/* Filter input with a left search glyph and a right clear (✕) button
 * that appears once something is typed. */
.cj-rail-filter {
  position: relative;
}
.cj-rail-filter__icon {
  position: absolute;
  top: 50%;
  left: 0.75rem;
  transform: translateY(-50%);
  pointer-events: none;
}
.cj-rail-filter__input {
  padding-left: 2.25rem;
  padding-right: 2rem;
}
.cj-rail-filter__clear {
  position: absolute;
  top: 50%;
  right: 0.6rem;
  transform: translateY(-50%);
  display: inline-flex;
  line-height: 1;
  cursor: pointer;
  text-decoration: none;
}

/* Alpine ``x-cloak`` — hide elements until Alpine has initialised, so
 * an ``x-show``/``x-if`` element does not flash on first paint. */
[x-cloak] {
  display: none !important;
}

/* ── Alerts ───────────────────────────────────────────────── */
/* .alert is a flexbox, so plain text wrapped in <p> (the correct markup)
   would inherit Bootstrap's bottom margin and render with an unwanted gap.
   Drop the trailing margin so single- or multi-paragraph alerts stay tight. */
.alert > p {
  margin-bottom: 0;
}

/* ── Dense interface ──────────────────────────────────────── */
/* The ``conjunto.dense`` scoped setting puts ``cj-dense`` on <html>. In
   dense mode every table inside page content gets Tabler's ``.table-sm``
   spacing (same cell-padding vars) so more rows fit on screen — without
   each template hard-coding the class. Scoped to ``.page-body`` so modals
   and other surfaces keep their normal spacing. */
.cj-dense .page-body .table {
  --tblr-table-cell-padding-y: 0.25rem;
  --tblr-table-cell-padding-x: 0.5rem;
}

/* ── Breadcrumb in the page-pretitle area ──────────────────────────────────
   The dashboard breadcrumb (BreadcrumbMixin) renders inside ``.page-pretitle``
   so it adopts that small, muted, uppercase label style instead of Tabler's
   default breadcrumb look. */
.page-pretitle .breadcrumb {
  margin-bottom: 0;
  font-size: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
}
.page-pretitle .breadcrumb-item,
.page-pretitle .breadcrumb-item a,
.page-pretitle .breadcrumb-item.active {
  color: inherit;
}
.page-pretitle .breadcrumb-item a:hover {
  text-decoration: underline;
}

/* ── Disclosure (<details>) ───────────────────────────────── */
/* Indent the body of every <details> so its content sits visually under,
   not flush with, the summary. The summary itself stays at the margin. */
details > :not(summary) {
  margin-inline-start: 1rem;
}

/* ── Cookie-consent banner ────────────────────────────────── */
/* Wide bar pinned to the bottom of the viewport (#cj-cookie-banner). Ships
   ``hidden``; cookie_consent.js drops the attribute and adds ``is-visible``
   on the next frame for the slide-up. Below Bootstrap modals (z 1055). */
.cj-cookie-banner {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 1040;
  padding: 1rem;
  pointer-events: none;
}

.cj-cookie-banner__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.25rem;
  pointer-events: auto;
  background-color: var(--tblr-bg-surface, #fff);
  border: 1px solid var(--tblr-border-color, rgba(0, 0, 0, .1));
  border-radius: var(--tblr-border-radius, .5rem);
  box-shadow: 0 -2px 24px rgba(0, 0, 0, .18);
  padding: 1.25rem 1.5rem;

  transform: translateY(calc(100% + 2rem));
  opacity: 0;
  transition: transform .35s ease, opacity .35s ease;
}

.cj-cookie-banner.is-visible .cj-cookie-banner__inner {
  transform: translateY(0);
  opacity: 1;
}

.cj-cookie-banner__body {
  flex: 1 1 22rem;
  min-width: 0;
}

.cj-cookie-banner__title {
  font-size: 1.125rem;
  font-weight: 700;
  margin: 0 0 .35rem;
}

.cj-cookie-banner__intro {
  font-size: .9375rem;
  color: var(--tblr-secondary-color, #6c757d);
}

.cj-cookie-banner__intro p:last-child {
  margin-bottom: 0;
}

.cj-cookie-banner__categories {
  display: grid;
  gap: .5rem;
  margin-top: 1rem;
}

.cj-cookie-cat {
  display: flex;
  gap: .6rem;
  align-items: flex-start;
  padding: .6rem .75rem;
  border: 1px solid var(--tblr-border-color, rgba(0, 0, 0, .1));
  border-radius: var(--tblr-border-radius, .5rem);
  cursor: pointer;
}

.cj-cookie-cat__input {
  margin-top: .2rem;
  flex: 0 0 auto;
}

.cj-cookie-cat__text {
  display: flex;
  flex-direction: column;
  gap: .15rem;
}

.cj-cookie-cat__label {
  font-weight: 600;
  font-size: .9375rem;
}

.cj-cookie-cat__always {
  font-weight: 400;
  color: var(--tblr-secondary-color, #6c757d);
}

.cj-cookie-cat__desc {
  font-size: .8125rem;
  color: var(--tblr-secondary-color, #6c757d);
}

/* Actions stack on the right; "Reject all" and "Accept all" share the same
   weight (no dark patterns). */
.cj-cookie-banner__actions {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
}

@media (max-width: 575.98px) {
  .cj-cookie-banner__actions {
    flex: 1 1 100%;
  }

  .cj-cookie-banner__btn {
    flex: 1 1 auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cj-cookie-banner__inner {
    transition: none;
  }
}

/* ============================================================
   Toasts — solid backgrounds that honour `conjunto.toast_opacity`
   ============================================================
   Tabler's soft `bg-*-lt` colours are only ~10% opaque BY DESIGN
   (`--tblr-*-lt: color-mix(in oklab, var(--tblr-*) 10%, transparent)`).
   A toast painted with them therefore stays ~90% see-through even at
   `toast_opacity = 100%`, and the `--tblr-bg-opacity` knob can never make
   it solid — it only scales an already-transparent base.

   Fix: re-blend the SAME 10% accent tint over the OPAQUE body surface
   instead of over `transparent`, then let `--tblr-bg-opacity` dial the
   whole result. Identical look, but genuinely solid at 100% and
   translucent only when the user lowers the setting. Scoped to the toast
   container so other `bg-*-lt` usages stay untouched. */
#cj-toasts .toast { --cj-toast-accent: transparent; }
#cj-toasts .toast.bg-secondary-lt { --cj-toast-accent: var(--tblr-secondary); }
#cj-toasts .toast.bg-info-lt      { --cj-toast-accent: var(--tblr-info); }
#cj-toasts .toast.bg-success-lt   { --cj-toast-accent: var(--tblr-success); }
#cj-toasts .toast.bg-warning-lt   { --cj-toast-accent: var(--tblr-warning); }
#cj-toasts .toast.bg-danger-lt    { --cj-toast-accent: var(--tblr-danger); }
#cj-toasts .toast {
  background-color: color-mix(
    in srgb,
    color-mix(in srgb, var(--cj-toast-accent) 10%, var(--tblr-body-bg))
      calc(var(--tblr-bg-opacity, 1) * 100%),
    transparent
  ) !important;
}

/* ============================================================
   Drag & drop — "you can drop here" affordance
   ============================================================
   One ecosystem-wide look shared by every drag mechanism (SortableJS,
   GridStack, native HTML5 DnD, the calendar). While a drag is in
   progress EVERY valid drop target carries ``.cj-drop-target`` — an
   unobtrusive grey dashed border running all the way around, so it is
   clear at a glance where (possibly several places) a drop will land.
   The target currently under the pointer additionally carries
   ``.cj-drop-target--over`` (a touch stronger + faint tint). A drop
   position *between* two list items is drawn as a running dashed line
   with ``.cj-drop-line``.

   The colour is a single custom property, ``--cj-drop-target-color``,
   so a specific target can recolour its border/line without new rules —
   e.g. a calendar zone that rejects an appointment type. Ready-made
   modifiers (``--danger`` / ``--success`` / ``--warning``) just set it. */
:root {
  --cj-drop-target-color:      var(--tblr-gray-400, #ced4da);
  --cj-drop-target-color-over: var(--tblr-gray-500, #adb5bd);
}
.cj-drop-target {
  outline: 2px dashed var(--cj-drop-target-color);
  outline-offset: -2px;
  border-radius: 4px;
  transition: outline-color .12s ease, background-color .12s ease;
}
.cj-drop-target.cj-drop-target--over {
  outline-color: var(--cj-drop-target-color-over);
  background-color: color-mix(in srgb, var(--cj-drop-target-color) 8%, transparent);
}
/* Colour overrides — set the property, border AND line follow. */
.cj-drop-target--danger {
  --cj-drop-target-color:      var(--tblr-danger, #d63939);
  --cj-drop-target-color-over: var(--tblr-danger, #d63939);
}
.cj-drop-target--success {
  --cj-drop-target-color:      var(--tblr-success, #2fb344);
  --cj-drop-target-color-over: var(--tblr-success, #2fb344);
}
.cj-drop-target--warning {
  --cj-drop-target-color:      var(--tblr-warning, #f76707);
  --cj-drop-target-color-over: var(--tblr-warning, #f76707);
}

/* Between-items insertion line — sits in the normal flow between two
   items, or as the sole child of an empty list. Inherits the target
   colour so an overridden zone tints its line to match. */
.cj-drop-line {
  height: 0;
  margin: 2px 0;
  border: 0;
  border-top: 2px dashed var(--cj-drop-target-color-over, #adb5bd);
  border-radius: 2px;
  pointer-events: none;
}
