/* ==========================================================================
 * Project overrides of the admin theme.
 *
 * Loaded after `css/app.min.css` and before `styles/theme.css`, so the location
 * palette still has the last word (see `theme.css` for why that order matters).
 *
 * This file is for defects in the theme that affect every screen. Anything that
 * belongs to ONE page belongs in that page's own sheet — `checkinout.css` is the
 * worked example — and anything that is the location palette belongs in
 * `theme.css`. A rule here is a claim that every screen wants it.
 * ========================================================================== */

/* --------------------------------------------------------------------------
 * A multi-select has to look like a select.
 *
 * INSPINIA paints `.choices[data-type*=select-one]` with a caret and a pointer
 * cursor, and leaves `select-multiple` as a bare box with `cursor: text`. The two
 * then read as different KINDS of control rather than as one control that takes
 * one value and one that takes several: a multi-select looks like a text field
 * until you click it and a list appears. Seven form types are affected — the
 * check-in conditions, permissions, notification recipients, the profile.
 *
 * The caret is the theme's own — same SVG, same offsets, same rotation on open —
 * because the point is for the two to match, not for this one to be nicer.
 * -------------------------------------------------------------------------- */

.choices[data-type*="select-multiple"] .choices__inner {
    cursor: pointer;
    /* `!important` because the declaration it is answering is: the theme sets
       `padding: … !important` on this element, so a longhand without it loses
       however late this sheet is read. The room is for the caret. */
    padding-right: 2rem !important;
}

/* A search-enabled multi-select is still typed into, so the box that IS typed into
   keeps saying so. */
.choices[data-type*="select-multiple"] .choices__input {
    cursor: text;
}

.choices[data-type*="select-multiple"]::after {
    content: "";
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='%239ba6b7'  xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 16a1 1 0 0 1-.64-.23l-6-5a1 1 0 1 1 1.28-1.54L12 13.71l5.36-4.32a1 1 0 0 1 1.41.15a1 1 0 0 1-.14 1.46l-6 4.83A1 1 0 0 1 12 16'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    position: absolute;
    border: 0;
    /* Pinned near the top line rather than to the middle: a multi-select grows
       downwards as items are picked, and an arrow that tracks the centre of a
       four-row box has wandered away from the control it belongs to. */
    top: 18px;
    right: 12px;
    left: auto;
    height: 20px;
    width: 20px;
    margin-top: 0;
    transform: translateY(-50%);
    transition: transform 0.2s ease-in-out;
    pointer-events: none;
}

.choices[data-type*="select-multiple"].is-open::after {
    transform: translateY(-50%) rotate(-180deg);
}

/* The theme's dark caret, for the same reason. */
[data-bs-theme="dark"] .choices[data-type*="select-multiple"]::after {
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='%238391a2'  xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 16a1 1 0 0 1-.64-.23l-6-5a1 1 0 1 1 1.28-1.54L12 13.71l5.36-4.32a1 1 0 0 1 1.41.15a1 1 0 0 1-.14 1.46l-6 4.83A1 1 0 0 1 12 16'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
 * A menu label wraps; it is never cut off.
 *
 * The theme sets `white-space: nowrap` on `.side-nav-link` and ellipsis on
 * `.menu-text`, which suits its demo's one-word entries. Legacy's labels are
 * longer — "List of upcoming installments (Budgeting)" — and the rows ran out
 * past the right edge of the sidebar, under the page body. They break onto
 * two or three lines instead, the icon and the arrow keeping their place.
 *
 * The condensed sidebar is left alone: its labels only appear in the hover
 * flyout, which is sized from the text and relies on `nowrap` to do it.
 * -------------------------------------------------------------------------- */

html:not([data-sidenav-size="condensed"]) .side-nav .side-nav-item .side-nav-link {
    white-space: normal;
    overflow-wrap: anywhere;
}

/* Past three lines the label is cut with an ellipsis, and `lbapp.js` titles the
   link with the full text — only then, so a label that fits carries no tooltip. */
html:not([data-sidenav-size="condensed"]) .side-nav .side-nav-item .side-nav-link .menu-text,
html:not([data-sidenav-size="condensed"]) .side-nav .side-nav-item .side-nav-link .menu-label {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    overflow: hidden;
    min-width: 0;
}

.side-nav .side-nav-link .menu-icon,
.side-nav .side-nav-link .menu-arrow {
    flex-shrink: 0;
}

/* --------------------------------------------------------------------------
 * DataTables · the Columns menu
 *
 * `lbapp.js` adds it above every responsive table. A listing with fourteen
 * columns makes a long menu, so it scrolls inside itself rather than running
 * off the bottom of a short card.
 * -------------------------------------------------------------------------- */

.dt-columns .dt-columns-list {
    max-height: 18rem;
    overflow-y: auto;
    min-width: 12rem;
}

/* Columns ticked in the menu are never hidden to make room, so once they
 * outgrow the card the table scrolls sideways rather than spilling out of it. */
.dt-columns-scroll {
    overflow-x: auto;
}

/* --------------------------------------------------------------------------
 * DataTables · the rows-per-page control
 *
 * `lbapp.js` makes it a Choices.js control on `init.dt`, so that every select in
 * the application is one (conventions §3). Choices replaces the `<select>` with a
 * block-level `div.choices`, which in the table's top row would stretch across the
 * cell — the native control it replaced was as wide as "100".
 *
 * So: sized to its content and kept on one line with the "entries per page" label
 * beside it. `margin-bottom: 0` because Choices ships `24px` for a control sitting
 * in a form, and this one sits in a toolbar. The `0.5em` gap to the label is the
 * one DataTables' Bootstrap 5 sheet puts on `div.dt-length select` — the select is
 * hidden inside Choices now, so its margin no longer spaces anything.
 * -------------------------------------------------------------------------- */

.dt-length .choices {
    display: inline-block;
    margin-bottom: 0;
    margin-right: 0.5em;
    min-width: 5.5rem;
    vertical-align: middle;
}

.dt-length .choices__inner {
    padding: 0.28rem 0.5rem;
    min-height: auto;
}

/* --------------------------------------------------------------------------
 * A checkbox sharing a half/half row sits in the middle of the fields beside it.
 *
 * `form_row` on a `CheckboxType` renders no label above the control — the label
 * IS the text beside the tick — so in a `col-*-6` next to an ordinary field the
 * checkbox lands at the top of its column, up level with that field's LABEL
 * rather than anywhere near the box the operator is looking at. "Amount" and
 * "Is Paid" then read as two unrelated lines instead of as one row of two
 * fields (`lostcard__form`, `receipt__form`, `invoice_pay_form`).
 *
 * So: a half-width column holding nothing but a checkbox is centred down the
 * row, which puts the tick level with the control beside it.
 *
 * Two things the rule deliberately does NOT touch. A row of nothing but
 * checkboxes is already level with itself, and its `mb-3` is what spaces it
 * from the row below — the `:has()` on the row, "some visible column here has a
 * real label in it", is what tells the two apart. And a column holding more
 * than one field is left alone, because the margins between them are the layout.
 * -------------------------------------------------------------------------- */

.lb-form .row:has(> [class*="col-"]:not(.hidden):not(.d-none) > .mb-3 > label:not(.form-check-label))
    > :is([class~="col-6"], [class~="col-sm-6"], [class~="col-md-6"], [class~="col-lg-6"], [class~="col-xl-6"]):has(> .mb-3:only-child > .form-check) {
    display: flex;
    align-items: center;
}

/* Centring measures the MARGIN box, so the row's own bottom margin would push
   the tick half a margin above the middle. `!important` because the declaration
   it is answering is: `mb-3` is a Bootstrap spacing utility and carries one.
   Dropping it costs nothing — the field beside it sets the height of the row. */
.lb-form .row:has(> [class*="col-"]:not(.hidden):not(.d-none) > .mb-3 > label:not(.form-check-label))
    > :is([class~="col-6"], [class~="col-sm-6"], [class~="col-md-6"], [class~="col-lg-6"], [class~="col-xl-6"]):has(> .mb-3:only-child > .form-check) > .mb-3 {
    margin-bottom: 0 !important;
}

/* --------------------------------------------------------------------------
 * The year picker (`data-year-picker`, built by `buildYearGrid()` in lbapp.js).
 * Its cells are `.flatpickr-day`s so they take the theme's hover, today and
 * selected colours; only their size changes, from a seventh of a week to a
 * quarter of a four-by-three grid of years.
 * -------------------------------------------------------------------------- */

.lb-yearpicker .lb-yearpicker-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 4px;
    padding: 8px;
}

.lb-yearpicker .lb-yearpicker-grid .flatpickr-day {
    max-width: none;
    width: auto;
    height: 48px;
    line-height: 46px;
    border-radius: 4px;
}

.lb-yearpicker .lb-yearpicker-title {
    font-weight: 600;
}
