/* ============================================================
   Material interaction layer
   ------------------------------------------------------------
   Adds the M3 *feel* (state layers, ripple, motion, hover
   elevation) on top of the M3 design tokens defined in app.css.
   Loaded AFTER app.css so it layers cleanly without touching it.
   ============================================================ */

:root {
    /* M3 motion */
    --md-ease-standard:   cubic-bezier(0.2, 0, 0, 1);
    --md-ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
    --md-dur-short:  150ms;
    --md-dur-medium: 250ms;
    --md-dur-ripple: 380ms;
}

/* ---------- State layers ----------
   An interactive element gets a translucent overlay in its own
   text/icon colour (currentColor): hover 8 %, focus 10 %, pressed 12 %.
   Because the overlay colour matches the content colour it tints the
   surface but barely touches the label. Painted at z-index:-1 (between
   the element background and its text) via ::before, so it never covers
   content and never clobbers the dropdown caret (which uses ::after). */
.btn,
.dropdown-item,
.list-group-item-action,
.page-link {
    position: relative;
    overflow: hidden;          /* contain state layer + ripple to the shape */
    isolation: isolate;        /* keep the -1 layer above the bg, below text */
}

.btn::before,
.dropdown-item::before,
.list-group-item-action::before,
.page-link::before {
    content: "";
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: -1;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}

.btn:hover::before,
.dropdown-item:hover::before,
.list-group-item-action:hover::before,
.page-link:hover::before                 { opacity: .08; }

.btn:focus-visible::before,
.dropdown-item:focus::before,
.list-group-item-action:focus::before    { opacity: .10; }

.btn:active::before,
.dropdown-item:active::before,
.list-group-item-action:active::before   { opacity: .12; }

/* Material expresses interaction through state layers, not brightness —
   neutralise the brightness:hover from app.css so the two don't stack. */
.btn-primary:hover,
.btn-secondary:hover,
.btn-danger:hover,
.btn-success:hover { filter: none; }

/* Keyboard focus indicator (a11y) */
.btn:focus-visible {
    outline: 2px solid var(--md-sys-color-primary);
    outline-offset: 2px;
}

/* ---------- Ripple ----------
   <span class="md-ripple"> injected by material.js on pointerdown. */
.md-ripple {
    position: absolute;
    border-radius: 50%;
    background: currentColor;
    opacity: .12;
    transform: scale(0);
    pointer-events: none;
    z-index: -1;
    animation: md-ripple var(--md-dur-ripple) var(--md-ease-standard) forwards;
}
@keyframes md-ripple {
    to { transform: scale(2.5); opacity: 0; }
}

/* ---------- Motion + hover elevation ----------
   Standardise easing on the common transitions and let filled buttons
   rise on hover (M3 elevates interactive filled buttons). */
.btn {
    transition: box-shadow var(--md-dur-short) var(--md-ease-standard),
                background-color var(--md-dur-short) var(--md-ease-standard);
}
.btn-primary:hover,
.btn-danger:hover,
.btn-success:hover { box-shadow: var(--md-elevation-2); }

.card { transition: box-shadow var(--md-dur-medium) var(--md-ease-standard); }

/* ---------- Navbar links: ripple host ----------
   (they already carry a hover background that reads as a state layer). */
.navbar-nav .nav-link { position: relative; overflow: hidden; isolation: isolate; }

/* ---------- Clickable cards: hover elevation ----------
   Interactive M3 cards rise on hover. The dashboard stat tiles open
   popovers, so they are clickable. */
.stat-card {
    transition: box-shadow var(--md-dur-medium) var(--md-ease-standard);
    cursor: pointer;
}
.stat-card:hover { box-shadow: var(--md-elevation-3); }

/* ---------- FAB (extended) ----------
   Primary "create" action, floating bottom-right. */
.md-fab {
    position: fixed;
    right: 1.75rem;
    bottom: 1.75rem;
    z-index: 1030;
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    height: 56px;
    padding: 0 1.35rem;
    border-radius: 16px;
    background: var(--md-sys-color-primary-container);
    color: var(--md-sys-color-on-primary-container);
    box-shadow: var(--md-elevation-3);
    font-weight: 500;
    text-decoration: none;
    overflow: hidden;
    isolation: isolate;
    transition: box-shadow var(--md-dur-short) var(--md-ease-standard);
}
.md-fab:hover,
.md-fab:focus {
    color: var(--md-sys-color-on-primary-container);
    box-shadow: var(--md-elevation-3), 0 6px 14px rgba(0,0,0,.22);
}
.md-fab::before {
    content: "";
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    border-radius: inherit;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-fab:hover::before         { opacity: .08; }
.md-fab:focus-visible::before { opacity: .10; }
.md-fab:active::before        { opacity: .12; }
.md-fab .material-symbols-outlined { font-size: 22px; }

/* ---------- Page entrance motion ----------
   Opacity-only fade (no transform, so position:fixed children like the FAB
   keep their viewport anchoring). */
@media (prefers-reduced-motion: no-preference) {
    main > .container-fluid { animation: md-page-enter var(--md-dur-medium) var(--md-ease-emphasized) both; }
}
@keyframes md-page-enter {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ---------- Filter chips (M3) ---------- */
.md-chip {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    height: 32px;
    padding: 0 .9rem;
    border-radius: 8px;
    border: 1px solid var(--md-sys-color-outline);
    background: transparent;
    color: var(--md-sys-color-on-surface-variant);
    font-size: .85rem;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: background-color var(--md-dur-short) var(--md-ease-standard),
                border-color var(--md-dur-short) var(--md-ease-standard);
}
.md-chip:hover { color: var(--md-sys-color-on-surface); text-decoration: none; }
.md-chip::before {
    content: ""; position: absolute; inset: 0; background: currentColor; opacity: 0;
    pointer-events: none; z-index: -1; border-radius: inherit;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-chip:hover::before  { opacity: .06; }
.md-chip:active::before { opacity: .12; }
.md-chip-selected,
.md-chip-selected:hover {
    background: var(--md-sys-color-secondary-container);
    color: var(--md-sys-color-on-secondary-container);
    border-color: transparent;
}
.md-chip-check { font-size: 16px; }

/* ---------- Selected / active table row (M3) ---------- */
.table > tbody > tr.table-active > *,
.table > tbody > tr.is-selected > * {
    background: var(--md-sys-color-secondary-container);
    color: var(--md-sys-color-on-secondary-container);
}

/* ---------- Gantt rich tooltip (M3 surface) ---------- */
.gantt-tooltip {
    background: var(--md-sys-color-surface-container, #fff);
    border: 1px solid var(--md-sys-color-outline-variant, #c1c7ce);
    border-radius: var(--md-shape-md, 12px);
    box-shadow: var(--md-elevation-2, 0 2px 6px rgba(0,0,0,.2));
    color: var(--md-sys-color-on-surface);
}

/* ---------- Snackbar action button (M3) ---------- */
.gantt-toast { display: inline-flex; align-items: center; gap: .75rem; pointer-events: auto; }
.gantt-toast-action {
    flex: none;
    background: transparent;
    border: none;
    padding: .3rem .55rem;
    margin: -.3rem -.35rem -.3rem 0;
    border-radius: 4px;
    color: var(--md-sys-color-inverse-primary, #6fd2ff);
    font-weight: 600;
    font-size: .85rem;
    cursor: pointer;
}
.gantt-toast-action:hover { background: rgba(255,255,255,.12); }
.gantt-toast-error .gantt-toast-action { color: var(--md-sys-color-error, #ba1a1a); }

/* ---------- Data-table pages: constrain width + row rhythm ----------
   Lists are sparse, so the full 1600px content width over-stretches them.
   Constrain list pages to a comfortable column; the Gantt/dashboard keep
   the full width (they don't use .md-list).

   M3 Lists spec: 16dp leading/trailing cell padding; row height 48–56dp
   achieved via generous vertical padding (~12px top+bottom → ~48px total
   with body line-height, ~56px for content-dense rows). */
.md-list { max-width: 1140px; }
.md-list .table > thead > tr > th,
.md-list .table > tbody > tr > td {
    padding-top:    .75rem;    /* ~12px — gives ~48px row height with 1.5 line-height */
    padding-bottom: .75rem;
    padding-left:   1rem;      /* 16px leading per M3 Lists spec */
    padding-right:  1rem;      /* 16px trailing per M3 Lists spec */
}
/* Primary cell (first non-icon column) uses body/on-surface style */
.md-list .table > tbody > tr > td:first-child { font-size: 1rem; }
/* Secondary cells use on-surface-variant at body-small */
.md-list .table > tbody > tr > td:not(:first-child) {
    font-size: .875rem;
    color: var(--md-sys-color-on-surface-variant);
}
/* Header cells: on-surface-variant, weight 500 (already so via app.css) */
.md-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.md-row-link { cursor: pointer; }
/* First-column entries shouldn't look like links — the whole row is clickable. */
.md-list .table td:first-child a,
.md-list .table td:first-child a:hover {
    color: var(--md-sys-color-on-surface);
    text-decoration: none;
    font-weight: 500;
}

/* ---------- Icon button (M3) ---------- */
.md-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--md-sys-color-on-surface-variant);
    text-decoration: none;
    cursor: pointer;
    vertical-align: middle;
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: color var(--md-dur-short) var(--md-ease-standard);
}
.md-icon-btn::before {
    content: ""; position: absolute; inset: 0; background: currentColor; opacity: 0;
    border-radius: inherit; pointer-events: none; z-index: -1;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-icon-btn:hover { color: var(--md-sys-color-on-surface); }
.md-icon-btn:hover::before          { opacity: .08; }
.md-icon-btn:focus-visible::before  { opacity: .10; }
.md-icon-btn:active::before         { opacity: .12; }
.md-icon-btn:focus-visible { outline: 2px solid var(--md-sys-color-primary); outline-offset: 2px; }
.md-icon-btn .material-symbols-outlined { font-size: 20px; }

/* ---------- M3 Modal Side Sheet ----------
   Right-anchored detail panel. Build once (singleton), reuse for all rows.
   Open state toggled by adding .md-side-sheet--open to the element. */

.md-side-sheet-scrim {
    position: fixed;
    inset: 0;
    z-index: 1040;
    background: rgba(0, 0, 0, .32);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--md-dur-medium) var(--md-ease-standard);
}
.md-side-sheet-scrim.md-side-sheet--open {
    opacity: 1;
    pointer-events: auto;
}

.md-side-sheet {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 1050;
    width: min(420px, 100vw);
    display: flex;
    flex-direction: column;
    background: var(--md-sys-color-surface);
    box-shadow: var(--md-elevation-3);
    border-radius: var(--md-shape-lg, 16px) 0 0 var(--md-shape-lg, 16px);
    transform: translateX(100%);
    transition: transform var(--md-dur-medium) var(--md-ease-standard);
    overflow: hidden;
}
.md-side-sheet.md-side-sheet--open {
    transform: translateX(0);
}

@media (max-width: 599px) {
    .md-side-sheet {
        width: 100vw;
        border-radius: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .md-side-sheet,
    .md-side-sheet-scrim {
        transition: none;
    }
}

/* Sheet internal layout */
.md-sheet-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: 1rem 1rem 1rem 1.5rem;
    border-bottom: 1px solid var(--md-sys-color-outline-variant, #cac4d0);
    flex-shrink: 0;
}
.md-sheet-title {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--md-sys-color-on-surface);
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.md-sheet-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1.25rem 1.5rem;
}
.md-sheet-footer {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .875rem 1.5rem;
    border-top: 1px solid var(--md-sys-color-outline-variant, #cac4d0);
    flex-shrink: 0;
}

/* Loading/error states inside the sheet body */
.md-sheet-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3rem 1rem;
    color: var(--md-sys-color-on-surface-variant);
    gap: .6rem;
    font-size: .9rem;
}
.md-sheet-error {
    padding: 1.5rem;
    color: var(--md-sys-color-error, #ba1a1a);
    font-size: .9rem;
}

/* Sheet fragment internals */
.md-sheet-dl {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: .35rem 1rem;
    margin: 0;
}
.md-sheet-dl dt {
    color: var(--md-sys-color-on-surface-variant);
    font-size: .8rem;
    font-weight: 500;
    padding-top: .15rem;
    white-space: nowrap;
}
.md-sheet-dl dd {
    color: var(--md-sys-color-on-surface);
    font-size: .9rem;
    margin: 0;
    word-break: break-word;
}
.md-sheet-section {
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--md-sys-color-outline-variant, #cac4d0);
}
.md-sheet-section-title {
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--md-sys-color-on-surface-variant);
    margin-bottom: .75rem;
}
.md-sheet-table {
    width: 100%;
    font-size: .85rem;
    border-collapse: collapse;
}
.md-sheet-table th,
.md-sheet-table td {
    padding: .35rem .5rem;
    text-align: left;
    border-bottom: 1px solid var(--md-sys-color-outline-variant, #cac4d0);
}
.md-sheet-table th {
    color: var(--md-sys-color-on-surface-variant);
    font-weight: 600;
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .03em;
}

/* ============================================================
   M3 Navigation Drawer
   ============================================================

   Desktop (≥768px): permanent fixed left drawer, 300px wide.
   Mobile  (<768px): modal drawer, hidden by default, slides in
                     from left over a scrim when hamburger is tapped.

   The CSS custom property --md-rail-width is inherited by app.css:
     body.has-rail main { margin-left: var(--md-rail-width, 80px) }
   We redefine it here to 300px on desktop and 0 on mobile so the
   content offset works without touching app.css.
   ============================================================ */

:root {
    --md-rail-width:   0px;   /* mobile default: no offset */
    --md-top-bar-h:    0px;   /* mobile top bar height, 0 on desktop */
}

@media (min-width: 768px) {
    :root {
        --md-rail-width: 300px;  /* drawer pushes content right */
    }
}

@media (max-width: 767.98px) {
    :root {
        --md-top-bar-h: 56px;
    }
}

/* Push main + footer below the mobile top app bar */
body.has-rail main,
body.has-rail > .footer {
    padding-top: var(--md-top-bar-h, 0);
}

/* Neutralise the old app.css mobile bottom-nav padding
   (was: padding-bottom:80px for the fixed bottom bar) */
@media (max-width: 767.98px) {
    body.has-rail main {
        padding-bottom: 0;
    }
}

/* ── M3 Number Badge ───────────────────────────────────────── */

.md-badge {
    position: absolute;
    top: -6px;
    right: -8px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--md-sys-color-error);
    color: var(--md-sys-color-on-error);
    font-size: .65rem;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    white-space: nowrap;
    /* Hidden by default; shown by JS when count > 0 */
    display: none;
}
.md-badge[data-count]:not([data-count="0"]) { display: block; }

/* ── Mobile top app bar ────────────────────────────────────── */

.md-top-bar {
    display: none; /* hidden on desktop */
}

@media (max-width: 767.98px) {
    .md-top-bar {
        display: flex;
        align-items: center;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        height: 56px;
        z-index: 210;
        background: var(--md-sys-color-surface);
        box-shadow: 0 1px 3px rgba(0, 0, 0, .12);
        padding: 0 4px;
    }
}

.md-top-bar-title {
    flex: 1;
    text-align: center;
    font-size: 1rem;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--md-sys-color-on-surface);
    padding: 0 .5rem;
}

/* ── Navigation Drawer (permanent on desktop) ──────────────── */

.md-drawer {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 300px;
    z-index: 200;
    display: flex;
    flex-direction: column;
    background: var(--md-sys-color-surface-container-low);
    border-right: 1px solid var(--md-sys-color-outline-variant);
    padding: .75rem 12px .5rem;
    overflow-y: auto;
    overflow-x: hidden;
}

/* ── Drawer brand / logo header ────────────────────────────── */

.md-drawer-brand {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: 1rem 1rem 1rem 1.25rem;
    color: var(--md-sys-color-primary);
    text-decoration: none;
    flex-shrink: 0;
}
.md-drawer-brand:hover { color: var(--md-sys-color-primary); text-decoration: none; }

.md-drawer-brand-name {
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.2;
    color: var(--md-sys-color-on-surface);
    /* Wrap up to 2 lines, then truncate with an ellipsis */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    min-width: 0;
}

/* ── Drawer sections ───────────────────────────────────────── */

.md-drawer-section {
    display: flex;
    flex-direction: column;
}

/* Spacer pushes bottom section down */
.md-drawer-spacer { flex: 1 1 auto; }

/* Divider between main items and bottom items */
.md-drawer-divider {
    margin: .25rem 0;
    border: 0;
    border-top: 1px solid var(--md-sys-color-outline-variant);
}

/* Bottom section needs position:relative so account menu can be absolute */
.md-drawer-section--bottom {
    position: relative;
    flex-shrink: 0;
}

/* ── Drawer item ───────────────────────────────────────────── */

.md-drawer-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 56px;
    padding: 0 16px;
    color: var(--md-sys-color-on-surface-variant);
    text-decoration: none;
    font-size: .875rem;
    font-weight: 500;
    letter-spacing: .006em;
    cursor: pointer;
    border: none;
    background: transparent;
    width: 100%;
    box-sizing: border-box;
    overflow: hidden;
    isolation: isolate;
    transition: color var(--md-dur-short) var(--md-ease-standard);
    -webkit-user-select: none;
    user-select: none;
    text-align: left;
}
.md-drawer-item:hover  { color: var(--md-sys-color-on-surface); text-decoration: none; }
.md-drawer-item--active { color: var(--md-sys-color-on-secondary-container); }
.md-drawer-item:focus-visible {
    outline: 2px solid var(--md-sys-color-primary);
    outline-offset: -2px;
    border-radius: 28px;
}

/* Full-width rounded pill indicator (active background) */
.md-drawer-indicator {
    position: absolute;
    inset: 4px 0;
    border-radius: 28px;
    background: transparent;
    transition: background var(--md-dur-medium) var(--md-ease-standard);
    z-index: -1;
    pointer-events: none;
}
.md-drawer-item--active .md-drawer-indicator {
    background: var(--md-sys-color-secondary-container);
}

/* State layer */
.md-drawer-item::before {
    content: "";
    position: absolute;
    inset: 4px 0;
    border-radius: 28px;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-drawer-item:hover::before         { opacity: .08; }
.md-drawer-item:focus-visible::before { opacity: .10; }
.md-drawer-item:active::before        { opacity: .12; }

/* Icon wrapper — positions the badge relative to the icon */
.md-drawer-icon-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
}
.md-drawer-icon-wrap .material-symbols-outlined { font-size: 24px; }

/* Label — must not overflow at 300px drawer width */
.md-drawer-label {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1 1 0;
    min-width: 0;
}

/* ── Account dropdown menu ─────────────────────────────────── */

.md-drawer-account-menu {
    position: absolute;
    bottom: 100%;
    left: 0;
    right: 0;
    z-index: 1060;
    background: var(--md-sys-color-surface-container-high);
    border-radius: var(--md-shape-md);
    box-shadow: var(--md-elevation-3);
    padding: .35rem;
    display: none;
}
.md-drawer-account-menu.is-open { display: block; }

/* ── Mobile modal drawer ───────────────────────────────────── */

@media (max-width: 767.98px) {
    .md-drawer {
        width: min(300px, calc(100vw - 56px));
        box-shadow: none;
        border-right: none;
        border-radius: 0 16px 16px 0;
        transform: translateX(-100%);
        transition: transform var(--md-dur-medium) var(--md-ease-standard);
    }
    .md-drawer.md-drawer--open {
        transform: translateX(0);
        box-shadow: var(--md-elevation-3);
    }
}

/* ── Modal scrim ───────────────────────────────────────────── */

.md-drawer-scrim {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 199;
    background: rgba(0, 0, 0, .40);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--md-dur-medium) var(--md-ease-standard);
}
@media (max-width: 767.98px) {
    .md-drawer-scrim {
        display: block;
    }
    .md-drawer-scrim.md-drawer-scrim--open {
        opacity: 1;
        pointer-events: auto;
    }
}

/* ── Drawer group: parent link + chevron toggle side-by-side (generic) ── */

.md-drawer-group {
    display: flex;
    align-items: stretch;
}
/* Parent link takes all available width minus the chevron */
.md-drawer-group .md-drawer-item {
    flex: 1 1 0;
    min-width: 0;
    /* override the width:100% from .md-drawer-item so flex sizing works */
    width: auto;
}

/* Chevron toggle button */
.md-drawer-sub-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 40px;
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--md-sys-color-on-surface-variant);
    border-radius: 20px;
    margin: 4px 2px 4px 0;
    padding: 0;
    transition: color var(--md-dur-short) var(--md-ease-standard);
    position: relative;
    overflow: hidden;
    isolation: isolate;
}
.md-drawer-sub-toggle:hover { color: var(--md-sys-color-on-surface); }
.md-drawer-sub-toggle:focus-visible {
    outline: 2px solid var(--md-sys-color-primary);
    outline-offset: -2px;
}
/* State layer */
.md-drawer-sub-toggle::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-drawer-sub-toggle:hover::before         { opacity: .08; }
.md-drawer-sub-toggle:focus-visible::before { opacity: .10; }
.md-drawer-sub-toggle:active::before        { opacity: .12; }

/* Chevron icon rotation */
.md-drawer-sub-toggle .material-symbols-outlined {
    font-size: 20px;
    transition: transform var(--md-dur-short) var(--md-ease-standard);
}
.md-drawer-sub-toggle[aria-expanded="true"] .material-symbols-outlined {
    transform: rotate(180deg);
}

/* ── Inline submenu (all viewports) ───────────────────────── */

.md-drawer-sub-inline {
    overflow: hidden;
    max-height: 0;
    transition: max-height var(--md-dur-medium) var(--md-ease-standard);
}
.md-drawer-sub-inline.is-open {
    /* Generous fallback so the submenu never clips its last item before JS
       runs or without JS. JS sets the exact scrollHeight on open for a
       smooth, content-matched animation (each item is min-height:56px, and
       there can be up to 4 items = 224px). */
    max-height: 600px;
}
.md-drawer-sub-item {
    padding-left: 52px; /* icon width (24) + gap (12) + base padding (16) = 52 */
}

/* ── Reduced motion ────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .md-drawer,
    .md-drawer-indicator,
    .md-drawer-item,
    .md-drawer-item::before,
    .md-drawer-scrim,
    .md-drawer-account-menu,
    .md-drawer-sub-inline,
    .md-drawer-sub-toggle,
    .md-drawer-sub-toggle::before,
    .md-drawer-sub-toggle .material-symbols-outlined {
        transition: none;
    }
}

/* ============================================================
   M3 Date Picker
   A docked popover calendar anchored below each input[type=date].
   Tokens: --md-sys-color-*, --md-shape-*, --md-elevation-*
   ============================================================ */

/* Hide the native browser calendar icon so our picker takes over */
input[type="date"]::-webkit-calendar-picker-indicator {
    opacity: 0;
    pointer-events: none;
    width: 0;
    position: absolute;
}

/* The popover container */
.md-datepicker {
    position: fixed;
    z-index: 2000;
    width: 296px;
    background: var(--md-sys-color-surface-container-high);
    border-radius: var(--md-shape-lg);
    box-shadow: var(--md-elevation-3);
    padding: 0;
    outline: none;
    overflow: hidden;
    opacity: 0;
    transform: scaleY(0.9);
    transform-origin: top center;
    transition: opacity var(--md-dur-short) var(--md-ease-standard),
                transform var(--md-dur-short) var(--md-ease-standard);
    pointer-events: none;
    -webkit-user-select: none;
    user-select: none;
}
.md-datepicker.md-datepicker--open {
    opacity: 1;
    transform: scaleY(1);
    pointer-events: auto;
}

/* Header row: prev icon | month+year label | next icon */
.md-datepicker-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 8px 4px;
    gap: 4px;
}

/* Month/year button that opens the year grid */
.md-datepicker-label {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 6px 8px;
    border: none;
    background: transparent;
    border-radius: var(--md-shape-sm);
    color: var(--md-sys-color-on-surface);
    font-size: .9rem;
    font-weight: 600;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: background var(--md-dur-short) var(--md-ease-standard);
}
.md-datepicker-label::before {
    content: "";
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    border-radius: inherit;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-datepicker-label:hover::before  { opacity: .08; }
.md-datepicker-label:active::before { opacity: .12; }
.md-datepicker-label .material-symbols-outlined { font-size: 18px; }

/* Prev / Next month icon buttons */
.md-datepicker-nav {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--md-sys-color-on-surface-variant);
    cursor: pointer;
    position: relative;
    overflow: hidden;
    isolation: isolate;
    flex-shrink: 0;
    transition: color var(--md-dur-short) var(--md-ease-standard);
}
.md-datepicker-nav::before {
    content: "";
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    border-radius: inherit;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-datepicker-nav:hover  { color: var(--md-sys-color-on-surface); }
.md-datepicker-nav:hover::before  { opacity: .08; }
.md-datepicker-nav:active::before { opacity: .12; }
.md-datepicker-nav:focus-visible {
    outline: 2px solid var(--md-sys-color-primary);
    outline-offset: 2px;
}
.md-datepicker-nav .material-symbols-outlined { font-size: 20px; pointer-events: none; }
.md-datepicker-nav[disabled],
.md-datepicker-nav[aria-disabled="true"] {
    opacity: .38;
    cursor: default;
    pointer-events: none;
}

/* Weekday header row */
.md-datepicker-weekdays {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    padding: 4px 12px 0;
    gap: 0;
}
.md-datepicker-weekday {
    text-align: center;
    font-size: .72rem;
    font-weight: 600;
    color: var(--md-sys-color-on-surface-variant);
    padding: 4px 0 6px;
    line-height: 1;
}

/* Day grid */
.md-datepicker-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px 0;
    padding: 4px 12px 12px;
}

/* Individual day cell */
.md-datepicker-day {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    margin: 0 auto;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--md-sys-color-on-surface);
    font-size: .875rem;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: background var(--md-dur-short) var(--md-ease-standard),
                color var(--md-dur-short) var(--md-ease-standard);
    outline: none;
}
.md-datepicker-day::before {
    content: "";
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    border-radius: inherit;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-datepicker-day:hover:not([disabled]):not([aria-disabled="true"])::before  { opacity: .08; }
.md-datepicker-day:active:not([disabled]):not([aria-disabled="true"])::before { opacity: .12; }
.md-datepicker-day:focus-visible {
    outline: 2px solid var(--md-sys-color-primary);
    outline-offset: 2px;
}

/* Out-of-current-month days */
.md-datepicker-day--other-month {
    color: var(--md-sys-color-on-surface-variant);
    opacity: .5;
}

/* Today's date: outlined circle */
.md-datepicker-day--today {
    box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
    color: var(--md-sys-color-primary);
    font-weight: 600;
}

/* Selected day: filled primary circle */
.md-datepicker-day--selected {
    background: var(--md-sys-color-primary) !important;
    color: var(--md-sys-color-on-primary) !important;
    font-weight: 700;
    box-shadow: none;
}
.md-datepicker-day--selected::before { background: var(--md-sys-color-on-primary); }

/* Disabled / out-of-min-max days */
.md-datepicker-day[disabled],
.md-datepicker-day[aria-disabled="true"] {
    color: var(--md-sys-color-on-surface-variant);
    opacity: .38;
    cursor: default;
    pointer-events: none;
}

/* Focused day during keyboard nav (not yet selected) */
.md-datepicker-day--focus {
    outline: 2px solid var(--md-sys-color-primary);
    outline-offset: 2px;
}

/* Year selection grid */
.md-datepicker-year-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4px 4px;
    padding: 8px 12px 12px;
    max-height: 220px;
    overflow-y: auto;
}
.md-datepicker-year-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 36px;
    border: none;
    border-radius: 18px;
    background: transparent;
    color: var(--md-sys-color-on-surface);
    font-size: .875rem;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    isolation: isolate;
    transition: background var(--md-dur-short) var(--md-ease-standard);
}
.md-datepicker-year-btn::before {
    content: "";
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    border-radius: inherit;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-datepicker-year-btn:hover::before  { opacity: .08; }
.md-datepicker-year-btn:active::before { opacity: .12; }
.md-datepicker-year-btn--selected {
    background: var(--md-sys-color-primary);
    color: var(--md-sys-color-on-primary);
    font-weight: 700;
}
.md-datepicker-year-btn--selected::before { background: var(--md-sys-color-on-primary); }
.md-datepicker-year-btn:focus-visible {
    outline: 2px solid var(--md-sys-color-primary);
    outline-offset: 2px;
}

/* Divider between header and grid */
.md-datepicker-divider {
    height: 1px;
    background: var(--md-sys-color-outline-variant);
    margin: 0 12px 4px;
}

/* ============================================================
   M3 Search bar (.md-search)
   Pill-shaped search field with a leading search icon.
   Use inside a <form method="get"> with class md-search-form.
   ============================================================ */
.md-search-form {
    max-width: 480px;
}

.md-search {
    display: flex;
    align-items: center;
    background: var(--md-sys-color-surface-container-high);
    border-radius: var(--md-shape-xl);
    padding: 0 16px;
    height: 48px;
    gap: 8px;
    transition: box-shadow var(--md-dur-short) var(--md-ease-standard);
}

.md-search:focus-within {
    box-shadow: 0 0 0 3px var(--md-sys-color-primary-container);
    outline: 2px solid var(--md-sys-color-primary);
    outline-offset: 0;
}

.md-search-icon {
    color: var(--md-sys-color-on-surface-variant);
    font-size: 20px;
    flex-shrink: 0;
    pointer-events: none;
    user-select: none;
}

.md-search-input {
    flex: 1;
    border: none;
    background: transparent;
    font-size: 1rem;
    color: var(--md-sys-color-on-surface);
    outline: none;
    min-width: 0;
}

.md-search-input::placeholder {
    color: var(--md-sys-color-on-surface-variant);
}

.md-search-clear {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--md-sys-color-on-surface-variant);
    flex-shrink: 0;
    border-radius: 50%;
    width: 28px;
    height: 28px;
    text-decoration: none;
    transition: background var(--md-dur-short) var(--md-ease-standard);
}

.md-search-clear:hover {
    background: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 12%, transparent);
}

.md-search-clear .material-symbols-outlined {
    font-size: 18px;
}

@media (prefers-reduced-motion: reduce) {
    .md-datepicker {
        transition: none;
    }
}

/* Live-search clear (×) is hidden while the field is empty (placeholder shown) */
.md-search .md-search-input:placeholder-shown ~ .md-search-clear { display: none; }

/* ============================================================
   M3 Select — custom <select> replacement
   The native <select> stays in the DOM (value holder).
   A .md-select-trigger overlay replaces the visible widget.
   The singleton .md-select-menu popover is appended to <body>.
   ============================================================ */

/* Hide the native browser arrow on select elements managed by MdSelect.
   We can't target these with a static rule without touching HTML, so the
   JS sets opacity:0 / pointer-events:none inline instead. */

/* ── Trigger (closed state) ──────────────────────────────────────────────── */

.md-select-trigger {
    /* Inherits parent position:relative context set by JS or form-floating */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .35rem;

    /* Match M3 outlined field look exactly (same as .form-control / .form-select) */
    height: calc(3.5rem + 2px);
    padding: 1.625rem 0.75rem 0.625rem;
    border: 1px solid var(--md-sys-color-outline);
    border-radius: var(--md-shape-sm);
    background: var(--md-sys-color-surface);
    color: var(--md-sys-color-on-surface);
    font-size: 1rem;
    line-height: 1.25;
    cursor: pointer;
    outline: none;
    user-select: none;
    -webkit-user-select: none;
    box-sizing: border-box;

    /* State layer */
    position: absolute;
    isolation: isolate;
    overflow: hidden;
    transition:
        border-color var(--md-dur-short) var(--md-ease-standard),
        box-shadow   var(--md-dur-short) var(--md-ease-standard);
}

.md-select-trigger::before {
    content: "";
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    border-radius: inherit;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}

.md-select-trigger:hover::before           { opacity: .06; }
.md-select-trigger:focus-visible::before   { opacity: .10; }
.md-select-trigger:active::before          { opacity: .12; }

.md-select-trigger:focus-visible,
.md-select-trigger[aria-expanded="true"] {
    border-color: var(--md-sys-color-primary);
    box-shadow: 0 0 0 1px var(--md-sys-color-primary);
    outline: none;
}

.md-select-trigger-label {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Placeholder option: muted colour */
.md-select-trigger--placeholder .md-select-trigger-label {
    color: var(--md-sys-color-on-surface-variant);
}

/* Compact trigger for bare selects (e.g. small filter selects that have a
   separate label above, not a floating label) — no floating-label height/
   padding; the height comes from the JS matching the native <select>. */
.md-select-trigger--bare {
    padding: .25rem .6rem;
    font-size: .875rem;
    line-height: 1.4;
}

.md-select-trigger-icon {
    flex-shrink: 0;
    font-size: 20px;
    color: var(--md-sys-color-on-surface-variant);
    transition: transform var(--md-dur-short) var(--md-ease-standard);
    pointer-events: none;
}

/* Rotate chevron when open */
.md-select-trigger[aria-expanded="true"] .md-select-trigger-icon {
    transform: rotate(180deg);
}

/* ── Disabled trigger ────────────────────────────────────────────────────── */

select[disabled] ~ .md-select-trigger,
.md-select-trigger[aria-disabled="true"] {
    opacity: .38;
    cursor: default;
    pointer-events: none;
}

/* ── Popover menu ────────────────────────────────────────────────────────── */

.md-select-menu {
    position: fixed;
    z-index: 2100;
    background: var(--md-sys-color-surface-container-high);
    border-radius: var(--md-shape-sm);
    box-shadow: var(--md-elevation-2);
    padding: .3rem 0;
    max-height: 320px;
    overflow-y: auto;
    overflow-x: hidden;
    outline: none;

    /* Hidden by default */
    opacity: 0;
    transform: scaleY(0.92);
    transform-origin: top center;
    pointer-events: none;
    transition:
        opacity  var(--md-dur-short) var(--md-ease-standard),
        transform var(--md-dur-short) var(--md-ease-standard);
}

.md-select-menu--open {
    opacity: 1;
    transform: scaleY(1);
    pointer-events: auto;
}

/* Reset list styling */
.md-select-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* ── Option item ─────────────────────────────────────────────────────────── */

.md-select-option {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .625rem 1rem .625rem .75rem;
    min-height: 48px;
    cursor: pointer;
    color: var(--md-sys-color-on-surface);
    font-size: .95rem;
    position: relative;
    isolation: isolate;
    overflow: hidden;
    user-select: none;
    -webkit-user-select: none;
    transition: background var(--md-dur-short) var(--md-ease-standard);
}

/* State layer */
.md-select-option::before {
    content: "";
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    pointer-events: none;
    z-index: -1;
    transition: opacity var(--md-dur-short) var(--md-ease-standard);
}
.md-select-option:hover::before    { opacity: .08; }

/* Active item (keyboard focus) */
.md-select-option--active {
    background: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
}
.md-select-option--active::before  { opacity: .08; }

/* Selected item: secondary-container highlight + full row */
.md-select-option--selected {
    background: var(--md-sys-color-secondary-container);
    color: var(--md-sys-color-on-secondary-container);
    font-weight: 500;
}
.md-select-option--selected::before { background: var(--md-sys-color-on-secondary-container); }
.md-select-option--selected.md-select-option--active { opacity: .95; }

/* Leading check icon: hidden unless selected */
.md-select-option-check {
    font-size: 18px;
    flex-shrink: 0;
    visibility: hidden;
    color: var(--md-sys-color-primary);
    width: 18px;
}
.md-select-option--selected .md-select-option-check {
    visibility: visible;
}

.md-select-option-text {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Disabled option */
.md-select-option--disabled {
    opacity: .38;
    cursor: default;
    pointer-events: none;
}

/* Placeholder option (empty value): muted */
.md-select-option--placeholder {
    color: var(--md-sys-color-on-surface-variant);
    font-style: italic;
}

/* ── Group header ────────────────────────────────────────────────────────── */

.md-select-group-label {
    padding: .5rem 1rem .25rem;
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--md-sys-color-on-surface-variant);
    pointer-events: none;
    user-select: none;
    -webkit-user-select: none;
}

/* Separator line above a group label (except the first) */
.md-select-group-label:not(:first-child) {
    border-top: 1px solid var(--md-sys-color-outline-variant);
    margin-top: .2rem;
    padding-top: .6rem;
}

/* ── Reduced motion ──────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    .md-select-menu,
    .md-select-trigger,
    .md-select-trigger-icon,
    .md-select-option,
    .md-select-trigger::before,
    .md-select-option::before {
        transition: none;
    }
}

/* ============================================================
   M3 Dialog (Bootstrap .modal → Material 3 dialog)
   https://m3.material.io/components/dialogs
   The .modal-content / header / body / footer rules in app.css
   give the basic shape; this block completes the M3 spec.
   ============================================================ */

/* Container shape, surface, elevation — overrides app.css values
   with the full M3 spec: xl radius (28px), surface-container-high,
   elevation level 3. */
.modal-content {
    border-radius: var(--md-shape-xl, 28px);
    background: var(--md-sys-color-surface-container-high);
    border: none;
    box-shadow: var(--md-elevation-3);
}

/* Header: 24px padding, no divider (M3 dialogs have no header line),
   headline-small typography for the title. */
.modal-header {
    padding: 1.5rem 1.5rem 0;
    border-bottom: none;
    align-items: flex-start;
}

.modal-title {
    font-size: 1.5rem;
    font-weight: 400;
    line-height: 2rem;
    color: var(--md-sys-color-on-surface);
}

/* Body: M3 body-medium, 24px horizontal + vertical rhythm */
.modal-body {
    padding: 1rem 1.5rem;
    color: var(--md-sys-color-on-surface-variant);
    font-size: .875rem;
    line-height: 1.43;
}

/* Footer: no top divider (M3), 24px padding, actions right-aligned
   (Bootstrap already uses justify-content:flex-end on .modal-footer). */
.modal-footer {
    padding: .75rem 1.5rem 1.5rem;
    border-top: none;
    gap: .5rem;
}

/* M3 scrim: 32% opacity over the M3 scrim colour (#000 approximation)
   Bootstrap sets .modal-backdrop.show to opacity .5 — we lower it to M3 spec. */
.modal-backdrop.show {
    opacity: .32;
    background-color: #000;
}

@media (prefers-reduced-motion: reduce) {
    .modal.fade .modal-dialog { transition: none; }
}

/* ============================================================
   M3 Plain Tooltip (Bootstrap .tooltip → Material 3)
   https://m3.material.io/components/tooltips
   Plain tooltip: inverse-surface fill, inverse-on-surface text,
   extra-small radius (4px), body-small font, no arrow.
   ============================================================ */

.tooltip-inner {
    background: var(--md-sys-color-inverse-surface, #2f3133);
    color: var(--md-sys-color-inverse-on-surface, #f0f1f4);
    border-radius: var(--md-shape-xs, 4px);
    font-size: .75rem;
    line-height: 1.33;
    padding: .25rem .5rem;
    max-width: 200px;
    word-wrap: break-word;
}

/* Hide Bootstrap tooltip arrow — M3 plain tooltips have no caret */
.tooltip .tooltip-arrow,
.tooltip .arrow {
    display: none !important;
}

/* ============================================================
   M3 Checkbox (Bootstrap .form-check-input[type=checkbox])
   https://m3.material.io/components/checkbox
   The basic colour tint already exists in app.css; this adds the
   full M3 visual spec: proper size, rounded-square outline shape,
   smooth transitions, and a correct focus ring.
   ============================================================ */

.form-check-input[type="checkbox"] {
    width: 1.125rem;
    height: 1.125rem;
    border: 2px solid var(--md-sys-color-outline);
    border-radius: 2px;
    background-color: transparent;
    background-image: none;
    appearance: none;
    -webkit-appearance: none;
    vertical-align: -2px;
    cursor: pointer;
    flex-shrink: 0;
    transition:
        background-color var(--md-dur-short) var(--md-ease-standard),
        border-color     var(--md-dur-short) var(--md-ease-standard),
        box-shadow       var(--md-dur-short) var(--md-ease-standard);
    position: relative;
}

/* Checked state: filled primary with a white check mark drawn via clip-path */
.form-check-input[type="checkbox"]:checked {
    background-color: var(--md-sys-color-primary);
    border-color: var(--md-sys-color-primary);
    /* M3 check mark as SVG data URI */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Cpath fill='%23ffffff' d='M7 14.17 2.83 10l-1.41 1.41L7 17 19 5l-1.41-1.42z' transform='scale(0.72) translate(1,1)'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: .75rem;
}

/* Indeterminate state: filled primary with dash */
.form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--md-sys-color-primary);
    border-color: var(--md-sys-color-primary);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Crect fill='%23ffffff' x='3' y='8' width='12' height='2' rx='1'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: .75rem;
}

/* Focus ring: M3 uses a 3dp ring in primary colour */
.form-check-input[type="checkbox"]:focus {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent);
    border-color: var(--md-sys-color-primary);
}

/* Disabled state */
.form-check-input[type="checkbox"]:disabled {
    opacity: .38;
    cursor: default;
}

/* ============================================================
   M3 Switch (Bootstrap .form-switch .form-check-input)
   https://m3.material.io/components/switch
   Pill-shaped track + circular thumb. Off: outline track, small
   thumb at left. On: primary track, white thumb shifted right.
   ============================================================ */

.form-switch .form-check-input {
    width: 3.25rem;
    height: 2rem;
    border-radius: 1rem;
    border: 2px solid var(--md-sys-color-outline);
    background-color: var(--md-sys-color-surface-variant);
    background-image: none;
    appearance: none;
    -webkit-appearance: none;
    position: relative;
    cursor: pointer;
    transition:
        background-color var(--md-dur-medium) var(--md-ease-standard),
        border-color     var(--md-dur-medium) var(--md-ease-standard);
    margin-top: 0;
    vertical-align: middle;
    flex-shrink: 0;
}

/* Thumb via ::before pseudo-element */
.form-switch .form-check-input::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 2px;
    transform: translateY(-50%);
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    background: var(--md-sys-color-outline);
    transition:
        left   var(--md-dur-medium) var(--md-ease-standard),
        width  var(--md-dur-short)  var(--md-ease-standard),
        height var(--md-dur-short)  var(--md-ease-standard),
        background var(--md-dur-medium) var(--md-ease-standard);
}

/* Pressed state: thumb grows slightly (M3 tactile feedback) */
.form-switch .form-check-input:active::before {
    width: 1.75rem;
    height: 1.75rem;
    left: 1px;
}

/* Checked (on) state */
.form-switch .form-check-input:checked {
    background-color: var(--md-sys-color-primary);
    border-color: var(--md-sys-color-primary);
    background-image: none;
}

.form-switch .form-check-input:checked::before {
    left: calc(100% - 1.25rem);
    width: 1.5rem;
    height: 1.5rem;
    top: 50%;
    background: var(--md-sys-color-on-primary);
}

.form-switch .form-check-input:checked:active::before {
    left: calc(100% - 1.85rem);
    width: 1.75rem;
    height: 1.75rem;
}

/* Focus ring */
.form-switch .form-check-input:focus {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent);
    border-color: var(--md-sys-color-outline);
}

.form-switch .form-check-input:checked:focus {
    border-color: var(--md-sys-color-primary);
}

/* Disabled state */
.form-switch .form-check-input:disabled {
    opacity: .38;
    cursor: default;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .form-check-input[type="checkbox"],
    .form-switch .form-check-input,
    .form-switch .form-check-input::before {
        transition: none;
    }
}

/* ============================================================
   M3 Flash banner (alert)
   The .alert-* classes from app.css already set M3 colours.
   This block adds the banner shape, leading icon, and ensures
   the dismiss button is an M3 icon button.
   ============================================================ */

.alert {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    border-radius: var(--md-shape-md, 12px);
    border: none;
    padding: .875rem 1rem .875rem 1.25rem;
}

/* Leading status icon */
.alert .md-alert-icon {
    flex-shrink: 0;
    font-size: 20px;
    margin-top: .05rem;
}

/* Alert text fills remaining space */
.alert .md-alert-body {
    flex: 1 1 auto;
    font-size: .9rem;
    line-height: 1.5;
    align-self: center;
}

/* Dismiss button: reset Bootstrap .btn-close, apply M3 icon button */
.alert .btn-close {
    flex-shrink: 0;
    align-self: flex-start;
    padding: 0;
    margin: 0;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    opacity: 1;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='currentColor' d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 18px;
    filter: none;
    transition: background-color var(--md-dur-short) var(--md-ease-standard);
}
.alert .btn-close:hover {
    background-color: rgba(0, 0, 0, .08);
}
.alert .btn-close:focus {
    box-shadow: 0 0 0 2px var(--md-sys-color-primary);
    outline: none;
}

/* Per-type close button colours (inherit the on-container text colour) */
.alert-success .btn-close  { color: var(--md-sys-color-on-success-container); }
.alert-info    .btn-close  { color: var(--md-sys-color-on-secondary-container); }
.alert-warning .btn-close  { color: var(--md-sys-color-on-warning-container); }
.alert-danger  .btn-close  { color: var(--md-sys-color-on-error-container); }
