.bg-img {
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

.spin {
    display: inline-block;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/*
 * Tabler ships a scrollbar "anti-jump" hack: at >=992px it sets
 * `:root { margin-left: calc(100vw - 100%) }`, i.e. it reserves the vertical
 * scrollbar width as a left margin on <html>. The intent is to keep a *centered*
 * .container from shifting horizontally when you move between a page that has a
 * scrollbar and one that doesn't. This app is full-width (.container-fluid
 * everywhere), so that margin has no centering to protect and instead pushes the
 * whole layout — navbar included — right by the scrollbar width on pages that
 * scroll (e.g. the Cruscotto), leaving it misaligned against the non-scrolling
 * admin pages (which are locked to 100vh, see .admin-section-header below).
 * Neutralize it so every page stays flush-left and the navbar lines up.
 */
@media (min-width: 992px) {
    :root {
        margin-left: 0;
    }
}

.ts-dropdown {
    --bs-body-bg: var(--tblr-body-bg);
    opacity: 1;
}

.ts-dropdown .option {
    background: white;
    opacity: 1;
}

.ts-control {
    min-height: 38px;
}

/*
 * A single-select TomSelect built over a text input (e.g. the city/municipality autocomplete)
 * renders as a Bootstrap .form-control wrapper. The bootstrap5 theme reserves the caret space
 * for every .single wrapper but only paints the chevron SVG for non-.form-control/.form-select
 * wrappers — and .form-control (unlike .form-select) has no arrow of its own. The result is
 * reserved-but-empty space. Paint the same chevron the country (.form-select) field uses.
 */
.ts-wrapper.form-control.single {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 16px 12px;
}

/*
 * Page shell (templates/base.html.twig): the section sidebar on the left, the page
 * content on the right. Both scroll with the page except on the full-height admin
 * list pages, handled further down.
 */
.app-shell {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.app-main {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    /* Without this a wide table/grid would stretch the flex item past the viewport. */
    min-width: 0;
}

.app-sidebar {
    flex: 0 0 15rem;
    width: 15rem;
    margin-bottom: 0;
    position: sticky;
    top: 0.5rem;
    transition: flex-basis 0.15s ease, width 0.15s ease;
}

.app-sidebar > .card-body {
    padding: 0.75rem;
}

.app-sidebar .app-sidebar-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
    padding-bottom: 0.5rem;
    min-height: 2rem;
    border-bottom: 1px solid var(--tblr-border-color);
}

/* The section is the sidebar's heading, so it reads as a title rather than as
   another sub-heading like the groups below it. Same look as the Cruscotto cards. */
.app-sidebar .app-sidebar-title {
    display: flex;
    align-items: center;
    min-width: 0;
}

.app-sidebar .app-sidebar-title .avatar {
    flex: 0 0 auto;
}

.app-sidebar .app-sidebar-title .card-title {
    font-size: 0.8125rem;
    line-height: 1.25;
}

.app-sidebar .subheader {
    margin-bottom: 0.25rem;
    padding-left: 0.5rem;
}

/*
 * Tabler pulls .list-group-transparent items out to the card edges with a
 * -1.25rem side margin, which assumes the default .card-body padding. This
 * sidebar is tighter, so the items would spill past the rounded border: keep them
 * inside and give them their own padding instead.
 */
.app-sidebar .list-group-transparent {
    margin-left: 0;
    margin-right: 0;
}

.app-sidebar .list-group-item {
    padding: 0.5rem;
    border-radius: var(--tblr-border-radius);
}

.app-sidebar .app-sidebar-icon {
    flex: 0 0 auto;
    margin-right: 0.5rem;
}

/* The active entry is a rounded pill inside the card, so the gold accent belongs
   inside it too (theme.css squares off the left corner for the full-bleed variant). */
.app-sidebar .list-group-transparent .list-group-item.active {
    border-radius: var(--tblr-border-radius);
}

/*
 * The toggle is the twin of the section chip at the other end of the row: same
 * 2rem tinted square, same rounding. The glyph is 1.25rem, not the .75rem Tabler
 * gives the avatar letter: a line-art icon needs the extra size to read, while the
 * filled chip carries the avatar on its own. The min-* are needed because
 * .btn-icon pins its own 40px square.
 */
.app-sidebar .app-sidebar-toggle {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    min-width: 2rem;
    min-height: 2rem;
    padding: 0;
    border: 0;
    border-radius: var(--tblr-border-radius);
    color: var(--tblr-primary);
    background-color: rgba(var(--tblr-primary-rgb), 0.1);
}

.app-sidebar .app-sidebar-toggle:hover {
    color: var(--tblr-primary);
    background-color: rgba(var(--tblr-primary-rgb), 0.2);
}

.app-sidebar .app-sidebar-toggle i {
    font-size: 1.25rem;
    line-height: 1;
}

/* Collapsed: an icon-only rail. The labels go, the icons centre, and the native
   `title` of each entry acts as the tooltip. */
.app-sidebar .app-sidebar-icon-collapsed,
:root.sidebar-collapsed .app-sidebar .app-sidebar-icon-expanded {
    display: none;
}

:root.sidebar-collapsed .app-sidebar .app-sidebar-icon-collapsed {
    display: inline-block;
}

:root.sidebar-collapsed .app-sidebar {
    flex-basis: 3.75rem;
    width: 3.75rem;
}

:root.sidebar-collapsed .app-sidebar .app-sidebar-label {
    display: none;
}

:root.sidebar-collapsed .app-sidebar .app-sidebar-head {
    justify-content: center;
}

:root.sidebar-collapsed .app-sidebar > .card-body {
    padding: 0.75rem 0.5rem;
}

:root.sidebar-collapsed .app-sidebar .list-group-item {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}

:root.sidebar-collapsed .app-sidebar .app-sidebar-icon {
    margin-right: 0;
}

/* The breadcrumb row is now a single line (the page title lives in the card header
   below it), so Tabler's page-header spacing is oversized. */
.app-page-header {
    margin-top: 0;
    margin-bottom: 0.5rem;
}

/* Below lg the sidebar would eat the whole width: hide it, the top navbar carries
   the same entries. */
@media (max-width: 991.98px) {
    .app-sidebar {
        display: none;
    }
}

/*
 * Admin list pages (templates/admin/_index_layout.html.twig). The section card
 * stretches to fill the viewport, the header keeps a fixed, uniform height across
 * every section, and the table fills the remaining space with its own scroll while
 * the toolbar/pagination stay pinned.
 */
body:has(.admin-section-header) {
    height: 100vh;
}

body:has(.admin-section-header) > .app-shell {
    flex: 1 1 auto;
    min-height: 0;
    /* The shell aligns its items to the top on scrolling pages; here both columns
       must reach the bottom of the viewport instead. */
    align-items: stretch;
}

body:has(.admin-section-header) .app-sidebar {
    align-self: stretch;
    overflow-y: auto;
    /* The labels are clipped rather than scrolled while the sidebar collapses. */
    overflow-x: hidden;
}

body:has(.admin-section-header) .app-main {
    min-height: 0;
}

.card:has(.admin-section-header) {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-height: 0;
    margin-bottom: 0;
}

.card:has(.admin-section-header) > .row {
    flex: 1 1 auto;
    min-height: 0;
}

/* Fixed, compact header — same height on every admin page. Only the list variant
   (.admin-section-header) locks the card to the viewport. */
.admin-section-header,
.admin-page-header {
    flex: 0 0 auto;
    min-height: 4.5rem;
    padding-top: 0.875rem;
    padding-bottom: 0.875rem;
}

/*
 * Form and detail pages nest white .card panels inside the layout's outer white card, which
 * left them indistinguishable. Tint this content panel with the page background so the inner
 * cards read as raised surfaces. List pages override admin_body_class (.admin-section-body),
 * so they keep the plain card-body and are unaffected.
 */
.admin-content-surface {
    background: var(--tblr-body-bg);
}

/* The list/table fills the space below the header. */
.admin-section-body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-height: 0;
}

.admin-section-body > * {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-height: 0;
}

/*
 * The search/filter toolbar is a .card-body, which Bootstrap gives `flex: 1 1 auto`.
 * Inside the flex column that would let it grow and split the height with the table,
 * pushing a short table toward the middle. Pin it to its natural height so only the
 * table fills the remaining space — matching the toolbar-less sections.
 */
.admin-section-body .card-body:not(.admin-section-fill) {
    flex: 0 0 auto;
}

.admin-section-body .table-responsive {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
}

/* A card wrapped in a controller div (the ag-grid lists, the plants map) still has
   to reach the bottom of the section body. */
.admin-section-body > * > .card {
    flex: 1 1 auto;
    min-height: 0;
    margin-bottom: 0;
}

/*
 * Marks the card body that holds a widget sized by the layout rather than by a
 * hand-computed viewport height: the ag-grid lists and the Leaflet map fill
 * whatever the toolbar and the footer leave.
 */
.admin-section-fill {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-height: 0;
}

.admin-section-fill > * {
    flex: 1 1 auto;
    min-height: 0;
}

/* Keep the table header visible while the body scrolls. */
.admin-section-body thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--tblr-bg-surface, #fff);
}

/*
 * Plants map (templates/admin/plant/map.html.twig + plant_map_controller.js).
 * The Leaflet divIcon pins carry their own inline color; here we only style the
 * hover tooltip (as a floating card) and the status legend overlay.
 */
.plant-map-pin {
    background: none;
    border: 0;
}

/* Strip Leaflet's default tooltip chrome — the inner card provides the styling. */
.leaflet-tooltip.plant-map-tooltip {
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    white-space: normal;
}

.leaflet-tooltip.plant-map-tooltip::before,
.leaflet-tooltip.plant-map-tooltip::after {
    display: none;
}

.plant-map-tooltip-card {
    min-width: 200px;
    max-width: 260px;
    padding: 10px 12px;
    font-size: 12.5px;
    line-height: 1.35;
    color: var(--tblr-body-color, #1a2234);
    background: var(--tblr-bg-surface, #fff);
    border: 1px solid var(--tblr-border-color, rgba(0, 0, 0, 0.1));
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}

.plant-map-tooltip-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
}

.plant-map-tooltip-code {
    font-weight: 600;
    font-size: 13px;
}

.plant-map-tooltip-row {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin-top: 3px;
    color: var(--tblr-secondary, #667382);
}

.plant-map-tooltip-row i {
    flex: 0 0 auto;
    margin-top: 1px;
    opacity: 0.8;
}

.plant-map-tooltip-hint {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    padding-top: 6px;
    font-size: 11.5px;
    color: var(--tblr-primary, #206bc4);
    border-top: 1px dashed var(--tblr-border-color, rgba(0, 0, 0, 0.1));
}

.plant-map-legend {
    position: absolute;
    left: 12px;
    bottom: 12px;
    z-index: 1001;
    padding: 8px 10px;
    font-size: 12px;
    color: var(--tblr-body-color, #1a2234);
    background: var(--tblr-bg-surface, #fff);
    border: 1px solid var(--tblr-border-color, rgba(0, 0, 0, 0.1));
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}

.plant-map-legend-dot {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

/*
 * Marker cluster bubbles (leaflet.markercluster iconCreateFunction). The plugin's
 * default .marker-cluster look is replaced by our own .plant-cluster class; the
 * bubble size is set inline per child count.
 */
.plant-cluster {
    background: none;
    border: 0;
}

.plant-cluster-bubble {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 600;
    color: #fff;
    background: rgba(32, 107, 196, 0.9); /* --tblr-primary */
    border: 3px solid rgba(32, 107, 196, 0.35);
    border-radius: 50%;
    background-clip: padding-box;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
