/* ==========================================================================
   ITAMFY: APPLICATION SHELL & COMPOSITE COMPONENTS

   app.css owns the design tokens and the single-element overrides (button, input,
   card, table, badge). This file owns the layer above that: the page skeleton and
   the composite components every screen is assembled from.

   Why it exists at all. The pieces below used to live as copy-pasted blocks inside
   individual pages' scoped CSS:

     - `.page-header`      duplicated byte-identically in 28 .razor.css files
     - the page container  duplicated in 27 files under 27 different names
                           (.assets-container, .admin-container, .licenses-container...)
                           every one of them setting max-width: 1400px
     - `.header-actions`   4 variants that had drifted apart (space-2 vs space-3 gap)
     - `.data-table`       2 cell paddings and 2 font sizes across its copies
     - `.empty-state`      defined in 8 files
     - `.loading-spinner`  the same keyframe written out 9 times

   That is consistent only until the next page is written, and it turns a change to
   the page rhythm into a 28-file edit. Owning these here means a new page inherits
   the layout by using the markup: consistency becomes the default rather than
   something each page has to remember.

   Page structure, top to bottom (see Components/Shared/PageHeader.razor):

     .page                       content column: max width + gutters
       .page-header              title block + primary actions, rule underneath
         .page-heading
           .page-title           h1: what this screen is
           .page-description     one quiet line of context, optional
         .page-actions           primary action right-most
       .toolbar                  search + filters, optional
       ...content
   ========================================================================== */


/* ==========================================================================
   Page shell
   ========================================================================== */

.page {
    max-width: 1400px;
    margin: 0 auto;
    padding: 0;
    transition: max-width var(--transition-base);
}

/* The full-width toggle: same page, gutters only. */
.page.full-width {
    max-width: 100%;
}

@media (max-width: 768px) {
    .page {
        padding: 0;
    }
}

/* --------------------------------------------------------------------------
   Page header
   -------------------------------------------------------------------------- */

.page-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--space-4);
    margin-bottom: var(--space-6);
    padding-bottom: 0;
}

.page-heading {
    min-width: 0;
    max-width: 100%;
    flex: 1;
}

.page-title {
    overflow-wrap: anywhere;
    min-width: 0;
    margin: 0;
    font-family: var(--font-ui);
    font-size: var(--text-4xl);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -0.02em;
    color: var(--text-primary);
}

.page-description {
    margin: var(--space-1) 0 0 0;
    max-width: 68ch;
    font-size: var(--text-base);
    line-height: 1.5;
    color: var(--text-secondary);
}

.page-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
}

/* Below the sidebar breakpoint the header stacks and the actions take a full row,
   so the primary button stays a comfortable target instead of being squeezed
   against the title. */
@media (max-width: 768px) {
    .page-header {
        flex-direction: column;
        gap: var(--space-3);
    }

    .page-actions {
        width: 100%;
        flex-wrap: wrap;
    }
}

/* A back-link above the title, for detail pages. */
.page-back {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.page-back:hover {
    color: var(--itamfy-primary);
}

/* --------------------------------------------------------------------------
   Section heading. A block of content inside a page
   -------------------------------------------------------------------------- */

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}

.section-heading {
    margin: 0;
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--text-primary);
}

.section-description {
    margin: var(--space-1) 0 0 0;
    font-size: var(--text-sm);
    color: var(--text-secondary);
}


/* ==========================================================================
   Toolbar: search + filters above a table
   ========================================================================== */

/* No panel of its own. Wrapping the filters in a bordered card put a second box around
   controls that are already boxes, directly above the table's box - three nested frames
   for one row of inputs. The controls sit on the page and the table below them is the
   only framed surface, which is what makes the table read as the subject of the screen. */
.toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-bottom: var(--space-4);
}

.toolbar-search {
    flex: 1 1 240px;
    min-width: 0;
}

.toolbar-filters {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

@media (max-width: 768px) {
    .toolbar {
        flex-direction: column;
        align-items: stretch;
    }

    /* The search box's `flex: 1 1 240px` sizes the MAIN axis, which is vertical once the
       toolbar stacks - left as-is it grew to a 240px-tall empty box under the input. */
    .toolbar-search {
        flex: 0 0 auto;
    }

    .toolbar-filters > * {
        flex: 0 1 auto;
        min-width: 0;
        max-width: 100%;
    }

    .toolbar-filters .dropdown-toggle { max-width: 100%; white-space: normal; text-align: left; }
}


/* ==========================================================================
   Stat row

   A compact figure-and-label strip, not a row of hero tiles. Cards are bordered
   and flat; the number is the only element allowed to be large.
   ========================================================================== */

.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 0;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    overflow: hidden;
    margin-bottom: var(--space-5);
}

.stat-card {
    padding: var(--space-4);
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: none;
}

.stat-value {
    display: block;
    font-size: var(--text-3xl);
    font-weight: 600;
    line-height: 1.15;
    color: var(--text-primary);
    /* Lining figures so a column of numbers stays aligned as values change. */
    font-variant-numeric: tabular-nums;
}

.stat-label {
    display: block;
    margin-top: var(--space-1);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.stat-card-clickable {
    cursor: pointer;
    transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.stat-card-clickable:hover {
    border-color: var(--gray-400);
    background-color: var(--bg-hover);
}

@media (max-width: 576px) {
    .stats-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}


/* ==========================================================================
   Detail grid: label/value pairs on detail pages
   ========================================================================== */

.detail-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 24px;
    align-items: start;
}

.detail-field {
    margin-bottom: var(--space-4);
}

.detail-field:last-child {
    margin-bottom: 0;
}

.detail-label {
    display: block;
    margin-bottom: var(--space-1);
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.detail-value {
    font-size: var(--text-base);
    color: var(--text-primary);
    overflow-wrap: anywhere;
}

@media (max-width: 992px) {
    .detail-grid {
        grid-template-columns: 1fr;
    }
}


/* ==========================================================================
   Pagination bar
   ========================================================================== */

.pagination-controls {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    margin-top: var(--space-6);
    padding-top: var(--space-4);
    border-top: 1px solid var(--border-color);
}

.page-size-selector {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.page-size-label {
    color: var(--text-secondary);
    font-size: var(--text-sm);
    white-space: nowrap;
}

.page-size-selector .form-select {
    width: auto;
    min-width: 4.5rem;
    padding-top: 0.375rem;
    padding-bottom: 0.375rem;
}

.pagination-info {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-left: auto;
}

.pagination-buttons {
    display: flex;
    gap: var(--space-1);
}

@media (max-width: 768px) {
    .pagination-controls {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-3);
    }

    .pagination-info {
        text-align: center;
    }

    .pagination-buttons {
        justify-content: center;
        flex-wrap: wrap;
    }

    .page-size-selector {
        justify-content: space-between;
        width: 100%;
    }

    .page-size-selector .form-select {
        flex: 0 0 auto;
    }
}


/* ==========================================================================
   Empty / loading states

   The two things every list-shaped screen has to say when it has nothing to show
   yet. These were previously improvised per page: `.empty-state` was defined in 8
   scoped files, and loading was drawn five different ways. A bespoke
   `.loading-spinner` keyframe duplicated 9 times, `fa-spinner fa-3x` 22 times,
   `fa-spinner fa-2x`, Bootstrap's `.spinner-border`, and bare `text-center p-5`.
   See Components/Shared/EmptyState.razor and Components/Shared/LoadingState.razor.
   ========================================================================== */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-10) var(--space-4);
    text-align: center;
}

/* Restrained on purpose: an empty state is a sentence with an action under it,
   not an illustration. The glyph is a quiet marker near body scale: well short
   of the fa-3x icons this replaces. */
.empty-state-icon {
    font-size: var(--text-2xl);
    line-height: 1;
    color: var(--text-muted);
    opacity: 0.65;
}

.empty-state-title {
    margin: var(--space-1) 0 0 0;
    font-size: var(--text-md);
    font-weight: 600;
    color: var(--text-primary);
}

.empty-state-description {
    margin: 0;
    max-width: 46ch;
    font-size: var(--text-base);
    line-height: 1.5;
    color: var(--text-secondary);
}

.empty-state-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
}

/* --------------------------------------------------------------------------
   Loading
   -------------------------------------------------------------------------- */

.loading-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    padding: var(--space-10) var(--space-4);
    color: var(--text-secondary);
    font-size: var(--text-base);
}

.loading-spinner {
    width: 20px;
    height: 20px;
    border: 2px solid var(--border-color);
    border-top-color: var(--itamfy-primary);
    border-radius: var(--radius-full);
    animation: itamfy-spin 0.7s linear infinite;
}

.loading-spinner-lg {
    width: 28px;
    height: 28px;
    border-width: 3px;
}

@keyframes itamfy-spin {
    to { transform: rotate(360deg); }
}

/* --------------------------------------------------------------------------
   Skeletons

   Preferred over a spinner wherever the shape of the result is already known: the
   page keeps its layout while loading instead of collapsing to a centred spinner
   and then jumping back to full height when the data lands.
   -------------------------------------------------------------------------- */

.skeleton {
    background-color: var(--gray-200);
    border-radius: var(--radius-sm);
    animation: itamfy-pulse 1.4s ease-in-out infinite;
}

body[data-theme="dark"] .skeleton {
    background-color: var(--gray-700);
}

@keyframes itamfy-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.45; }
}

.skeleton-text {
    height: 0.7rem;
    border-radius: var(--radius-sm);
}

/* Respect an OS preference for reduced motion. The loop is the whole point of
   these two, so it is stilled rather than merely slowed. The spinner keeps its
   ring so the "busy" affordance survives. */
@media (prefers-reduced-motion: reduce) {
    .skeleton,
    .loading-spinner {
        animation: none;
    }

    .skeleton {
        opacity: 0.7;
    }
}


/* ==========================================================================
   Data tables

   Scanning density first. The scoped copies of `.data-table` had drifted to two
   different cell paddings (space-3 and space-4) and two different font sizes, so
   the same table read differently depending on the page it was on.
   ========================================================================== */

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-base);
}

.data-table th {
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    text-align: left;
    white-space: nowrap;
    background: var(--bg-body);
    border-bottom: 1px solid var(--border-color);
}

.data-table td {
    height: 52px;
    padding: var(--space-3);
    color: var(--text-primary);
    border-bottom: 1px solid var(--border-color);
    vertical-align: middle;
    /* One line per cell. Without this a row grows to whatever the longest value needs and
       a list mixes one-, two- and three-line rows depending on how long an asset name
       happens to be, which reads as a broken grid rather than a table. The full value is
       on the detail page, and title="" keeps it reachable on hover. */
    max-width: 22ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Columns that must stay legible in full. */
.data-table td.cell-wide {
    max-width: 34ch;
}

.data-table td.cell-auto {
    max-width: none;
    white-space: normal;
}

.data-table tbody tr {
    transition: background-color var(--transition-fast);
}

/* Hover highlight only where hovering does something: highlight plus pointer
   means clickable, no highlight means static. */
.data-table tbody tr.clickable-row:hover {
    background-color: var(--bg-row-hover);
}

.data-table tbody tr:last-child td {
    border-bottom: none;
}

/* Numeric columns align right on lining figures, so they can be compared down
   the column rather than read one at a time. */
.data-table .cell-numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* The trailing actions column: fixed, tight, never the widest thing in the row. */
.data-table .cell-actions {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}

.table-container {
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    /* Scrolls rather than clips. `overflow: hidden` here (used to clip the corner radius)
       cut off the right-hand columns of any table wider than the viewport, which on mobile
       meant status and actions were unreachable rather than merely off-screen. */
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}


/* ==========================================================================
   Accessibility

   A visible, consistent focus ring on everything reachable by keyboard. Several
   components were clearing `outline` to tidy up their mouse styling, which leaves
   a keyboard user with no idea where they are. `:focus-visible` keeps the ring off
   for pointer users, so there is nothing to trade away by having it.
   ========================================================================== */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--itamfy-primary);
    outline-offset: 2px;
}

.stat-card-clickable:focus-visible,
tr.clickable-row:focus-visible {
    outline: 2px solid var(--itamfy-primary);
    outline-offset: -2px;
}

/* Skip link. The first tab stop on every page, jumping past the sidebar to the
   main content. Off-screen until focused. */
.skip-link {
    position: absolute;
    top: var(--space-2);
    left: var(--space-2);
    z-index: var(--z-tooltip);
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--text-primary);
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    transform: translateY(-250%);
    transition: transform var(--transition-fast);
}

.skip-link:focus {
    transform: translateY(0);
}

/* --------------------------------------------------------------------------
   Step indicator in a dialog header: for multi-step destructive flows, where
   knowing how far through you are is part of understanding what the button will
   do. Sits beside the title rather than inside the body's warning, so the
   warning can say one thing only.
   -------------------------------------------------------------------------- */

.modal-step {
    margin-left: auto;
    padding-right: var(--space-3);
    font-size: var(--text-xs);
    font-weight: 500;
    color: var(--text-muted);
    white-space: nowrap;
}

/* A list inside a notice: keep the bullets close to the text they belong to and
   drop the browser's default block margins, which otherwise open a gap between
   the notice's title and its own first bullet. */
.notice-list {
    margin: var(--space-1) 0 0 0;
    padding-left: var(--space-4);
}

.notice-list > li + li {
    margin-top: var(--space-1);
}

/* Title plus an inline status badge: kept on one baseline so the badge reads as an
   attribute of the title rather than as a separate line of content. */
.page-title-row {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   Sortable column headers (Components/Shared/SortableHeader.razor)

   The control is a real <button> filling the cell, so the whole header stays a
   comfortable click target while also being tabbable. Only headers that actually
   sort get the pointer and hover treatment. The previous per-page table styles
   put `cursor: pointer` on every th, which advertised sorting on columns that
   had none.
   -------------------------------------------------------------------------- */

.data-table th.sortable {
    padding: 0;
}

.th-sort {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2) var(--space-3);
    font: inherit;
    color: inherit;
    text-align: left;
    text-transform: inherit;
    letter-spacing: inherit;
    background: none;
    border: none;
    cursor: pointer;
    transition: color var(--transition-fast), background-color var(--transition-fast);
}

.th-sort:hover {
    color: var(--text-primary);
    background-color: var(--bg-hover);
}

.th-sort-icon {
    font-size: 0.85em;
    opacity: 0.35;
    transition: opacity var(--transition-fast);
}

.th-sort:hover .th-sort-icon {
    opacity: 0.7;
}

/* The column the table is actually sorted by reads at full strength, so the
   current sort is legible at a glance rather than only on inspection. */
.th-sort-icon.is-active {
    opacity: 1;
    color: var(--itamfy-primary);
}

.data-table th[aria-sort]:not([aria-sort="none"]) {
    color: var(--text-primary);
}

/* A stat card that navigates is an <a>; it must not pick up link colour or underline. */
a.stat-card,
a.stat-card:hover {
    color: inherit;
    text-decoration: none;
}

/* Sized to the figure it stands in for, so the row keeps its height while loading
   instead of growing when the numbers land. */
.stat-value-skeleton {
    display: inline-block;
    width: 2.5ch;
    height: 0.75em;
    vertical-align: middle;
}

/* --------------------------------------------------------------------------
   Label/value pairs and card titles shared by the detail pages.

   `::deep .field-label` was written out in 7 scoped stylesheets and `.info-grid` in 3
   the same rule, the same values, seven places to change.

   `::deep .card-title { margin-bottom: 0 }` was in those 7 files too and is deliberately
   NOT hoisted: it clamped a section title inside a card body flush against the first
   field below it. app.css already gives .card-title a space-3 gap, which is what the
   other twenty pages use, so dropping the override is what makes all of them agree.
   -------------------------------------------------------------------------- */

.field-label {
    margin-bottom: var(--space-1);
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.info-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
}

@media (max-width: 992px) {
    .info-grid {
        grid-template-columns: 1fr;
    }
}

/* --------------------------------------------------------------------------
   A table cell whose value is prefixed by a small type glyph (the template icon
   in the asset list). The icon is a scanning aid, not the content: it sits at
   the muted text colour and near body size, and it is aria-hidden because the
   adjacent text already names the thing.
   -------------------------------------------------------------------------- */

.cell-with-icon {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
}

.cell-with-icon > span {
    overflow: hidden;
    text-overflow: ellipsis;
}

.cell-icon {
    flex-shrink: 0;
    width: 1em;
    font-size: var(--text-base);
    color: var(--text-muted);
    text-align: center;
}

/* ==========================================================================
   Setup checklist (Components/Shared/SetupChecklist.razor)

   Deliberately not a row of cards. It is one panel with a numbered sequence, because
   the whole point is that these three steps happen in order: cards side by side would
   invite the customer to start with the wrong one.
   ========================================================================== */

.setup {
    margin-bottom: var(--space-5);
    padding: var(--space-5);
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
}

.setup-intro {
    margin-bottom: var(--space-4);
}

.setup-title {
    margin: 0;
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--text-primary);
}

.setup-lead {
    margin: var(--space-1) 0 0 0;
    max-width: 60ch;
    font-size: var(--text-base);
    color: var(--text-secondary);
}

.setup-steps {
    margin: 0;
    padding: 0;
    list-style: none;
}

.setup-step {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-3) 0;
    border-top: 1px solid var(--border-color);
}

/* The numbered disc. Finished steps go quiet, the current one carries the brand colour,
   and steps not yet reachable are dimmed - so the eye lands on the one thing to do now. */
.setup-marker {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 1.75rem;
    height: 1.75rem;
    font-size: var(--text-sm);
    font-weight: 600;
    border-radius: var(--radius-full);
    border: 1px solid var(--border-color);
    background: var(--bg-body);
    color: var(--text-muted);
}

.setup-step.is-current .setup-marker {
    background: var(--itamfy-primary);
    border-color: var(--itamfy-primary);
    color: #ffffff;
}

.setup-step.is-done .setup-marker {
    background: var(--tone-success-bg);
    border-color: var(--tone-success-border);
    color: var(--tone-success-accent);
}

.setup-step-body {
    min-width: 0;
}

.setup-step-title {
    margin: 0;
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.75rem;
}

/* A completed step keeps its title but drops its explanation - the definition has served
   its purpose and would otherwise crowd out the step that still needs doing. */
.setup-step.is-done .setup-step-title {
    color: var(--text-secondary);
    font-weight: 500;
}

.setup-step.is-waiting .setup-step-title {
    color: var(--text-secondary);
}

.setup-step-text {
    margin: var(--space-1) 0 0 0;
    max-width: 66ch;
    font-size: var(--text-base);
    line-height: 1.55;
    color: var(--text-secondary);
}

.setup-step-action {
    margin-top: var(--space-3);
}

/* The current step's actions: the fast route as a button, the manual route as a quiet
   link beside it, so there is one obvious thing to press and one way out of it. */
.setup-step-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-3);
    flex-wrap: wrap;
}

/* ==========================================================================
   Maps

   Leaflet ships its own styling for the tiles and controls; everything here is
   the frame around it, so it sits in the page like any other panel.
   ========================================================================== */

.map-picker-canvas,
.asset-map-canvas {
    height: 320px;
    width: 100%;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    /* Leaflet paints tiles right to the element edge, so without this the corners
       square off over the radius. */
    overflow: hidden;
    z-index: 0;
}

.asset-map-canvas {
    height: 340px;
}

.map-picker-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-3);
    margin-bottom: var(--space-2);
}

.map-picker-coords {
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
}

.map-picker-hint {
    font-size: var(--text-sm);
    color: var(--text-muted);
}

.asset-map-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

/* A site with no position is invisible on the map, so the count doubles as the way
   to go and fix it. */
.asset-map-unmapped {
    color: var(--tone-warning-accent);
    white-space: nowrap;
}

/* Leaflet's popups and controls are white by default, which reads as a hole punched
   in a dark page. */
body[data-theme="dark"] .leaflet-popup-content-wrapper,
body[data-theme="dark"] .leaflet-popup-tip,
body[data-theme="dark"] .leaflet-control-zoom a,
body[data-theme="dark"] .leaflet-control-attribution {
    background: var(--bg-card);
    color: var(--text-primary);
}

body[data-theme="dark"] .leaflet-control-attribution a {
    color: var(--itamfy-primary-light);
}

/* The tile imagery itself is a light-mode photograph. Damping it keeps the markers
   and the heat layer legible instead of glowing off a bright ground. */
body[data-theme="dark"] .leaflet-tile-pane {
    filter: brightness(0.75) saturate(0.85);
}

/* Metric groups read as one summary rather than a row of competing tiles. */
.stats-grid > .stat-card { border: 0; border-radius: 0; border-right: 1px solid var(--border-color); padding: 20px 24px; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.stats-grid > .stat-card:last-child { border-right: 0; }
.stat-label { order: -1; margin: 0; display: flex; align-items: center; gap: 8px; font-weight: 500; }
.stat-icon { color: var(--text-muted); font-size: 13px; }
.stat-value { font-size: 28px; letter-spacing: -0.035em; }
.stat-card-clickable:hover { background: var(--surface-subtle); }
.stat-note { color: var(--text-secondary); font-size: var(--text-xs); }
.stat-note-warning { color: var(--tone-warning-accent); }
.workspace-tabs { display: flex; gap: 24px; border-bottom: 1px solid var(--border-color); margin-bottom: 24px; overflow-x: auto; }
.workspace-tab { padding: 0 0 12px; border: 0; border-bottom: 2px solid transparent; background: transparent; color: var(--text-secondary); font-size: var(--text-base); font-weight: 500; white-space: nowrap; }
.workspace-tab:hover { color: var(--text-primary); }
.workspace-tab.active { color: var(--itamfy-primary); border-bottom-color: var(--itamfy-primary); }
body[data-theme="dark"] .workspace-tab.active { color: #9ac2ff; border-bottom-color: #9ac2ff; }
.panel-heading { display: flex; justify-content: space-between; align-items: center; gap: 12px; width: 100%; }
.panel-heading h2 { font-size: var(--text-lg); font-weight: 600; margin: 0; letter-spacing: -0.02em; }
.panel-description { color: var(--text-secondary); font-size: var(--text-sm); margin: 5px 0 0; font-weight: 400; }
.page-eyebrow { margin: 0 0 8px; color: var(--text-muted); font-size: var(--text-xs); font-weight: 500; }
.chart-wrapper > div { height: 100%; }
.panel-link { color: var(--link-color); font-size: var(--text-sm); font-weight: 500; white-space: nowrap; }
.section-header { margin-top: 24px; }
.section-heading { font-size: var(--text-base); }
.data-table thead th { background: var(--surface-subtle); color: var(--text-secondary); font-size: var(--text-xs); font-weight: 600; }
.data-table tbody td { border-bottom-color: var(--border-color); }
.data-table tbody tr:last-child td { border-bottom: 0; }
.detail-label { text-transform: none; letter-spacing: 0; font-size: var(--text-sm); font-weight: 500; }
.toolbar { gap: 8px; }
.toolbar-search { max-width: 420px; }
.page-actions .fullwidth-toggle { color: var(--text-muted); border-color: transparent; }
@media (max-width: 768px) {
    .stats-grid > .stat-card { padding: 16px; }
    .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .stats-grid > .stat-card:nth-child(2n) { border-right: 0; }
    .stats-grid > .stat-card:nth-child(n+3) { border-top: 1px solid var(--border-color); }
    .toolbar-search { max-width: none; }
    .workspace-tabs { gap: 20px; }
}
/* The organization is a persistent workspace context, above the navigation groups. */
.workspace-switcher { min-width: 0; }
.workspace-switcher-button { display: flex; align-items: center; gap: 10px; width: 100%; padding: 10px; border: 1px solid var(--border-color); border-radius: var(--radius-lg); background: var(--bg-card); color: var(--text-primary); text-align: left; }
.workspace-switcher-button:hover { border-color: var(--control-border); }
.workspace-switcher-button > i { font-size: 11px; color: var(--text-muted); margin-left: auto; }
.workspace-monogram { display: flex; align-items: center; justify-content: center; flex-shrink: 0; width: 32px; height: 32px; border-radius: var(--radius-md); background: var(--tone-info-bg); border: 1px solid var(--tone-info-border); color: var(--tone-info-fg); font-size: 14px; font-weight: 600; }
.workspace-switcher-copy { display: flex; flex-direction: column; min-width: 0; gap: 3px; }
.workspace-switcher-copy strong { font-size: var(--text-sm); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.workspace-switcher-copy > span { color: var(--text-secondary); font-size: 11px; }
.workspace-switcher .dropdown-menu { width: 280px; max-width: calc(100vw - 32px); max-height: 360px; overflow-y: auto; }
.workspace-switcher .dropdown-item { display: flex; align-items: center; gap: 12px; white-space: normal; }
.workspace-option-name { flex: 1; overflow-wrap: anywhere; }
.sidebar-workspace { margin: 20px 14px 4px; }
.mobile-workspace { display: none; }
.sidebar.collapsed:not(.mobile-open) .sidebar-workspace { margin: 16px 8px 4px; }
.sidebar.collapsed:not(.mobile-open) .workspace-switcher-button { padding: 7px; border-color: transparent; background: transparent; }
.sidebar.collapsed:not(.mobile-open) .workspace-switcher-copy, .sidebar.collapsed:not(.mobile-open) .workspace-switcher-button > i { display: none; }
.sidebar.collapsed:not(.mobile-open) .workspace-switcher .dropdown-menu { margin-left: 50px !important; }
@media (max-width: 768px) {
    .sidebar-workspace { display: none; }
    .mobile-workspace { display: block; flex: 1; }
    .mobile-workspace .workspace-switcher-button { border: 0; padding: 4px; background: transparent; gap: 6px; }
    .mobile-workspace .workspace-monogram { display: none; }
    .mobile-workspace .workspace-switcher-copy { max-width: 170px; }
    .mobile-workspace .workspace-switcher-copy > span { display: none; }
    .mobile-workspace .dropdown-menu { right: 0; left: auto; }
}
/* A record keeps its name and identifying number together for quick scanning. */
.record-identity { display: flex; align-items: center; gap: 10px; color: var(--text-primary); min-width: 0; }
.record-identity:hover { color: var(--link-color); }
.record-icon { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; flex-shrink: 0; background: var(--surface-subtle); border: 1px solid var(--border-color); border-radius: var(--radius-md); color: var(--text-secondary); }
.record-copy { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.record-copy strong { font-size: var(--text-sm); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.record-copy > span { font-size: 11px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.data-table td.cell-identity { padding-top: 8px; padding-bottom: 8px; min-width: 200px; max-width: 30ch; }
.data-table thead th { text-transform: none; letter-spacing: 0; }
.data-table .th-sort { text-transform: none; letter-spacing: 0; }
.settings-layout {
    display: grid;
    grid-template-columns: 192px minmax(0, 1fr);
    gap: 32px;
    align-items: start;
    container-type: inline-size;
}
.settings-sidebar { position: sticky; top: 80px; min-width: 0; }
.settings-nav { display: flex; flex-direction: column; gap: 4px; padding-right: 16px; border-right: 1px solid var(--border-color); }
.settings-nav-label { padding: 8px 12px 16px; font-size: 12px; font-weight: 600; color: var(--text-secondary); }
.settings-nav-item {
    display: flex; align-items: center; gap: 8px; width: 100%; min-height: 36px;
    padding: 8px 12px; text-align: left; border: 0; border-radius: 4px;
    background: transparent; color: var(--text-secondary); font-size: 14px; line-height: 20px;
    text-decoration: none; transition: color 120ms ease, background-color 120ms ease;
}
.settings-nav-item i { width: 20px; text-align: center; flex-shrink: 0; margin: 0 !important; }
.settings-nav-item:hover { background: var(--bg-hover); color: var(--text-primary); }
.settings-nav-item.active { background: color-mix(in srgb, var(--itamfy-primary) 12%, transparent); color: var(--link-color); font-weight: 600; }
.settings-content { min-width: 0; container-type: inline-size; }
.settings-content > .card { margin-bottom: 24px !important; }
.settings-content .card-body { padding: 24px; }
.settings-content .card-header { padding: 16px 24px; }
.settings-content .detail-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
.settings-content .form-control, .settings-content .form-select { max-width: 560px; }
.settings-content .card-body > .row { row-gap: 16px; margin-bottom: 24px; }
.settings-content .card-body > .row:last-child { margin-bottom: 0; }
.settings-content .form-text { max-width: 64ch; line-height: 20px; }
@container (max-width: 700px) {
    .settings-content .detail-grid, .settings-content .settings-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 1000px) {
    .settings-layout { grid-template-columns: minmax(0, 1fr); gap: 24px; }
    .settings-sidebar { position: static; }
    .settings-nav { flex-direction: row; flex-wrap: wrap; padding: 0 0 16px; border-right: 0; border-bottom: 1px solid var(--border-color); }
    .settings-nav-label { width: 100%; padding: 0 8px 8px; }
    .settings-nav-item { width: auto; }
}
@media (max-width: 600px) {
    .settings-content .card-body { padding: 16px; }
    .settings-content .card-header { padding: 16px; }
}

.global-search { position: relative; width: min(480px, 42vw); min-width: 160px; }
.global-search-input { display: flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 12px; border: 1px solid var(--control-border); border-radius: 6px; background: var(--surface-subtle); color: var(--text-secondary); }
.global-search-input:focus-within { outline: 2px solid var(--itamfy-primary); outline-offset: 1px; background: var(--bg-card); }
.global-search-input input { width: 100%; min-width: 0; border: 0; outline: none !important; box-shadow: none !important; padding: 7px 0; background: transparent; color: var(--text-primary); font: inherit; font-size: 14px; }
.global-search-input kbd { background: transparent; color: var(--text-secondary); border: 1px solid var(--border-color); font: 12px var(--font-ui); padding: 0 4px; }
.global-search-results { position: absolute; top: calc(100% + 8px); left: 0; width: max(100%, 360px); max-width: calc(100vw - 32px); max-height: min(560px, 75dvh); overflow-y: auto; padding: 8px; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: 8px; box-shadow: var(--shadow-lg); z-index: 1050; }
.search-context { display: flex; align-items: center; gap: 8px; padding: 8px; color: var(--text-secondary); font-size: 12px; border-bottom: 1px solid var(--border-color); }
.search-context span { overflow-wrap: anywhere; }
.search-feedback { display: flex; align-items: center; gap: 8px; padding: 12px 8px; font-size: 12px; color: var(--text-secondary); }
.search-result { display: flex; align-items: center; gap: 12px; border-radius: 4px; padding: 10px 8px; color: var(--text-primary); text-decoration: none; }
.search-result:hover, .search-result:focus-visible { background: var(--bg-hover); color: var(--text-primary); text-decoration: none; }
.search-result-copy { display: grid; gap: 2px; min-width: 0; flex: 1; }
.search-result-copy strong { font-size: 14px; font-weight: 500; overflow-wrap: anywhere; }
.search-result-copy small { font-size: 12px; color: var(--text-secondary); overflow-wrap: anywhere; }
.search-result > .fa-arrow-right { color: var(--text-secondary); font-size: 12px; }
@media (max-width: 767px) {
    .global-search { width: 100%; min-width: 0; }
    .global-search-input input { font-size: 16px; }
    .global-search-input kbd { display: none; }
    .global-search-results { position: fixed; top: 60px; left: 16px; width: calc(100vw - 32px); }
}
.page-context-icon { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; margin-top: 2px; flex: 0 0 40px; border-radius: var(--radius-md); background: var(--tone-info-bg); color: var(--link-color); font-size: 20px; }
.page .card-header { display: flex; align-items: center; gap: 6px 12px; flex-wrap: wrap; min-height: 56px; background: var(--bg-card); border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
.page .card-header .card-title { font-size: 16px; line-height: 24px; margin: 0; }
.page .card-title > i { width: 20px; font-size: 16px; color: var(--text-secondary); margin-right: 8px; text-align: center; }
.page .card-body { border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
.page .detail-grid .card-body > .row { margin-bottom: 24px; row-gap: 16px; }
.page .detail-grid .card-body > .row:last-child { margin-bottom: 0; }
.page .detail-grid .card-body p, .page .detail-grid .detail-value { overflow-wrap: anywhere; }
.page .detail-grid > .card { min-width: 0; }
.page .detail-grid .form-label, .page .detail-label { text-transform: none; letter-spacing: 0; font-size: 12px; font-weight: 600; line-height: 20px; }
.page .toolbar { padding: 16px; margin-bottom: 24px; background: var(--bg-card); border: 1px solid var(--border-color); border-radius: var(--radius-lg); }
.page .toolbar .input-group { min-width: min(240px, 100%); }
.page .toolbar .dropdown-menu { max-width: calc(100vw - 32px); }
.page .table-responsive { border-radius: 0 0 var(--radius-lg) var(--radius-lg); overflow: hidden; }
.page .card:has(> .card-body > .table-responsive) { overflow: hidden; }
.page .data-table thead th:first-child { border-top-left-radius: var(--radius-lg); }
.page .data-table thead th:last-child { border-top-right-radius: var(--radius-lg); }
.page .card > .card-body:first-child { border-top-left-radius: var(--radius-lg); border-top-right-radius: var(--radius-lg); }
.settings-content .stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 0; }
.settings-content .stats-grid > .stat-card:nth-child(2n) { border-right: 0; }
.settings-content .stats-grid > .stat-card:nth-child(n+3) { border-top: 1px solid var(--border-color); }
.settings-content .card-header > .d-flex { flex-wrap: wrap; gap: 12px; }
.page .card:focus-within { border-color: var(--control-border); }
@media (max-width: 600px) {
    .page-header { flex-direction: row; flex-wrap: wrap; }
    .page-heading { flex-basis: calc(100% - 64px); }
    .page-actions { width: 100%; justify-content: flex-end; }
    .page .toolbar { padding: 12px; }
}
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* Bounded paging stays inside narrow panels, even with large inventories. */
.pagination-controls { flex-wrap: wrap; gap: 12px; min-width: 0; }
.pagination-buttons { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; min-width: 0; }
.pagination-buttons .btn { margin-left: 0 !important; min-width: 30px; padding-inline: 8px; }
.page-ellipsis { padding-inline: 2px; color: var(--text-muted); }
.viewport-page-marker { height: 0; }

/* Keep the workspace restriction visible above the independently scrolling page. */
.readonly-banner-container { position: static; margin-bottom: 24px; }
.readonly-workspace-notice { max-width: 1400px; margin: 0 auto; border-radius: var(--radius-lg); }
.readonly-workspace-notice .alert-actions:empty { display: none; }
.readonly-workspace-notice .alert-content { overflow-wrap: anywhere; }
.readonly-workspace-notice .btn { max-width: 100%; white-space: normal; }
.global-search-input { border-color: transparent; border-radius: var(--radius-md); }
.workspace-tabs { gap: 6px; width: fit-content; max-width: 100%; padding: 4px; border: 1px solid var(--border-color); border-radius: var(--radius-md); background: var(--surface-subtle); }
.workspace-tab { padding: 7px 16px; border: 0; border-radius: var(--radius-sm); }
.workspace-tab.active { background: var(--bg-card); color: var(--link-color); }
@media (max-width: 768px) {
    .readonly-banner-container { margin-bottom: 16px; }
}

/* Record content and supporting facts flow independently, without stretched cards. */
.record-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.8fr) minmax(280px, 1fr);
    gap: var(--space-6);
    align-items: start;
}
.content-stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
    min-width: 0;
}
.content-stack > .card { margin-bottom: 0 !important; }
.record-layout .card-body > .row { row-gap: 16px; margin-bottom: 20px; }
.record-layout .card-body > .row:last-child { margin-bottom: 0; }
.record-layout .card-body { min-width: 0; }
.record-layout p, .record-layout a, .record-layout .detail-value { overflow-wrap: anywhere; }
.record-sidebar .row > [class*="col-md-"] { width: 100%; }
.record-sidebar .usage-stats .row > [class*="col-md-"] { width: 50%; }
.record-layout .card-header > .d-flex { flex-wrap: wrap; gap: 12px; }
/* Shared paired panels have one spacing owner and fill the row when only one remains. */
.detail-grid:has(> .card) { margin-bottom: var(--space-6); }
.detail-grid > .card { margin-bottom: 0 !important; }
.detail-grid > .card:only-child { grid-column: 1 / -1; }
.page > .card + .card { margin-top: var(--space-6); }
.card > .pagination-controls { margin: 0; padding: var(--space-4) var(--space-5); }
.card-body.p-0 > .pagination-controls { margin: 0; padding: var(--space-4) var(--space-5); }
/* Tables scroll horizontally on small screens rather than losing trailing actions. */
.page .table-responsive { overflow-x: auto; }
@media (max-width: 1000px) {
    .record-layout { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 768px) {
    .pagination-info { margin-left: 0; }
    .record-layout .d-flex.justify-content-between { flex-wrap: wrap; gap: 12px; }
}

.record-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 1px solid var(--border-color); border-radius: var(--radius-lg); background: var(--bg-card); margin-bottom: var(--space-6); }
.record-summary-item { min-width: 0; padding: var(--space-4) var(--space-5); border-right: 1px solid var(--border-color); overflow-wrap: anywhere; }
.record-summary-item:last-child { border-right: 0; }
@media (max-width: 1000px) {
    .record-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .record-summary-item:nth-child(2n) { border-right: 0; }
    .record-summary-item:nth-child(n+3) { border-top: 1px solid var(--border-color); }
}
@media (max-width: 480px) {
    .record-summary { grid-template-columns: minmax(0, 1fr); }
    .record-summary-item { border-right: 0; }
    .record-summary-item + .record-summary-item { border-top: 1px solid var(--border-color); }
}
