* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    display: flex;
    min-height: 100vh;
    font-family: 'Archivo', Arial, Helvetica, sans-serif;
    background: #f4f5f7;
    color: #333;
}

/* Matches the 'Archivo Black' treatment already used for headings on
   the marketing site (Assets/css/home.css) — the font itself is loaded
   via a Google Fonts <link> in each dashboard page's <head>. */
h1, h2, h3, h4, h5, h6 {
    font-family: 'Archivo Black', Arial, Helvetica, sans-serif;
}

/* ================
   Modernized cards, buttons & shadows
   Softer, more contemporary corners than Bootstrap's ~6px default
   (matching the 12px already used on the marketing site), plus the
   same navy-tinted shadow the marketing site uses in place of
   Bootstrap's flat .shadow-sm. Hover-lift stays limited to
   .card-clickable (above) so non-interactive cards don't imply
   they're clickable when they aren't.
   ================== */

.card {
    border-radius: 14px;
}

.btn {
    border-radius: 10px;
}

/* Prev/Next pagination buttons (Hall Bookings and Events, both the
   calendar nav and the events list pager) — same soft navy-tinted
   hover as the outline-primary buttons elsewhere, even though these
   are btn-outline-secondary the rest of the time. Excludes :disabled
   so a button already at the first/last page doesn't look hoverable. */
.btn-page-nav:hover:not(:disabled) {
    background-color: #e3e9f4;
    border-color: #1b3f7a;
    color: #1b3f7a;
}

.card.shadow-sm,
.card.shadow {
    box-shadow: 0 4px 16px rgba(1, 26, 61, .08) !important;
}

/* ================
   Soft status badges
   Pill-shaped, tinted badges instead of Bootstrap's solid saturated
   bg-success/bg-warning/etc. Pair with the base .badge class for
   sizing; these only override color/shape. Adopt by pointing a
   page's status→class map (e.g. STATUS_BADGE) at these instead of
   the bg-* utilities.
   ================== */

.badge-soft {
    border-radius: 999px;
    font-weight: 600;
    padding: 0.4em 0.75em;
}

.badge-soft-success {
    background-color: #e1f5e9;
    color: #1e7a44;
}

.badge-soft-warning {
    background-color: #fdf1d9;
    color: #8a5a00;
}

.badge-soft-danger {
    background-color: #fbe6e6;
    color: #b3261e;
}

.badge-soft-secondary {
    background-color: #e9ecf2;
    color: #4a5568;
}

.badge-soft-primary {
    background-color: #e3e9f4;
    color: #1b3f7a;
}

.badge-soft-info {
    background-color: #e0f4f7;
    color: #0f6674;
}

.badge-soft-purple {
    background-color: #f1e9fb;
    color: #6f42c1;
}

/* ================
   Clickable dashboard cards
   ================== */

.card-clickable {
    cursor: pointer;
    transition: transform .15s ease, box-shadow .15s ease;
}

.card-clickable:hover,
.card-clickable:focus-visible {
    transform: translateY(-3px);
    box-shadow: 0 10px 24px rgba(1, 26, 61, .14) !important;
}

.card-clickable:active {
    transform: translateY(-1px);
}

/* Marker class on the "entity list" cards — Members, Officers, Hall
   Bookings, Events — so their spacing has one dedicated hook instead
   of the bare .card selector (which Bootstrap also uses inside
   modals, filter bars, etc.). No styling of its own; the actual
   horizontal gap lives on .gmp-dashboard-card-row below, since gap
   between columns is a property of the row, not the card. */
.gmp-dashboard-card {
}

/* Goes on the <div class="row ..."> that lays these cards out side by
   side. Bootstrap gutters are implemented as padding on the columns
   driven by this CSS variable, so overriding it here is the correct
   way to change the gap between cards without fighting Bootstrap's
   own gutter math or double-applying spacing with a separate `gap`
   property. 1.5rem matches Bootstrap's own .g-4 value, which is what
   every data-card row uses — same gap on both card types. */
.gmp-dashboard-card-row {
    --bs-gutter-x: 1.5rem;
}

/* Marker class on the small stat/KPI tiles (Total Members, Dues
   Collected, etc.) — deliberately styled as nothing extra, so they
   stay at Bootstrap's original gutter spacing rather than picking up
   the wider gap meant for the bigger entity cards above. */
.gmp-data-card {
}

.row-clickable {
    cursor: pointer;
    transition: background-color .15s ease;
}

.row-clickable:hover {
    background-color: rgba(0, 0, 0, .04);
}

/* ================
   Sidebar
   ================== */

.sidebar {
    width: 250px;
    background: #1b2a4a;
    color: #ffffff;
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
}

.sidebar-logo {
    padding: 24px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.sidebar-logo img {
    max-width: 100%;
    height: auto;
}

.sidebar-nav {
    padding: 16px 0;
    flex-grow: 1;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 24px;
    color: rgba(255, 255, 255, 0.7);
    text-decoration: none;
    transition: background 0.2s, color 0.2s;
}

.nav-item i {
    width: 20px;
    height: 20px;
}

.nav-item:hover {
    background: rgba(255, 255, 255, 0.1);
    color: #ffffff;
}

/* Sidebar built by sidebar.js (Assets/JS/sidebar.js) uses Bootstrap's
   .nav-pills markup, not the .nav-item rows above — give its links the
   same light hover feedback. Excludes .active since that already gets
   a solid navy fill via --bs-nav-pills-link-active-bg below. */
#sidebar .nav-link:hover:not(.active) {
    background-color: rgba(0, 0, 0, 0.05);
}

/* Breathing room between tabs so hovering one doesn't visually touch
   the active tab above/below it. */
#sidebar .nav-pills > li:not(:last-child) {
    margin-bottom: 12px;
}

/* ================
   Info Card
   Shared "avatar/icon circle + title + pill, then an icon-line list of
   details, then a footer action" card pattern — used by Members,
   Officers, Hall Bookings, and Events. It used to be four copies of
   the same Bootstrap utility classes hand-typed into four separate
   render() functions, which is exactly how they quietly drifted out
   of sync with each other (e.g. one page's footer had an extra
   wrapper div the others didn't). Defining the spacing here once
   means every page that opts into these classes stays visually
   identical by construction, not by remembering to copy-paste
   correctly.
   ================== */

.info-card-header {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
}

/* Works on either an <img> (a real photo) or a <div> (initials/icon
   fallback) — object-fit only matters for the <img> case, and is
   harmless on a <div>. */
.info-card-icon {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    flex-shrink: 0;
    margin-right: 1rem;
    object-fit: cover;
}

/* Extra styling only the initials/icon fallback needs — a real photo
   already fills the circle on its own. */
.info-card-icon-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #1b3f7a;
    color: #fff;
    font-size: 1.1rem;
}

.info-card-icon-fallback svg {
    width: 24px;
    height: 24px;
}

.info-card-pills {
    margin-top: 0.25rem;
}

.info-card-list {
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
}

/* :last-child, not "every item except the JS-guessed last one" — the
   list of which lines actually render varies per card (not everyone
   has a phone number, not every event has a location), so letting CSS
   figure out which is actually last is what keeps this correct
   automatically instead of depending on every render() function
   remembering to special-case its own final line. */
.info-card-list li {
    margin-bottom: 0.5rem;
}

.info-card-list li:last-child {
    margin-bottom: 0;
}

.info-card-footer {
    background: transparent;
    border: 0;
    padding: 0 1rem 1rem;
    display: flex;
    gap: 0.5rem;
}

/* ================
   Membership Card Icons
   ================== */

/* Icons replacing emoji on the membership cards (members.html), sized
   down from the 20px sidebar-nav-icon convention to sit inline with
   card text and badge labels. Lucide's SVGs default to
   stroke="currentColor", so they pick up the surrounding text/badge
   color automatically. */
.member-card-icon {
    width: 14px;
    height: 14px;
    vertical-align: -2px;
    margin-right: 4px;
    flex-shrink: 0;
}

.badge-icon {
    width: 12px;
    height: 12px;
    vertical-align: -1px;
    margin-right: 3px;
}

.nav-item.active {
    background: rgba(255, 255, 255, 0.15);
    color: #ffffff;
    border-left: 3px solid #ffffff;
}

.sidebar-bottom {
    padding: 16px 0;
    border-top: 1px solid rgba(255, 255, 255, 0.1);
}

/* Icons injected by sidebar.js (Assets/JS/sidebar.js) into the actual
   Bootstrap nav-pills sidebar every dashboard page uses — sized to
   match the 20px convention already used for the admin panel's own
   sidebar icons. Lucide's SVGs default to stroke="currentColor", so
   they automatically pick up whatever color the surrounding nav-link
   text already has, active or not. */
.sidebar-nav-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

/* Bootstrap's .nav-pills sets --bs-nav-pills-link-active-bg itself
   (defaulting to Bootstrap blue, #0d6efd) rather than deriving it from
   --bs-primary, so overriding --bs-primary elsewhere in the dashboard
   never touched the sidebar's active-item highlight. Override that
   variable directly, scoped to the sidebar, so the clicked/active nav
   item gets a navy fill instead. */
#sidebar .nav-pills {
    --bs-nav-pills-link-active-bg: #1b2a4a;
}

/* The sidebar's user-menu (Settings / Sign out) is the one actual
   Bootstrap dropdown-menu popup in the dashboard — its hover/active
   item highlight defaults to Bootstrap blue same as the form controls
   above, so brand it navy too. */
#sidebar .dropdown-item:hover,
#sidebar .dropdown-item:focus,
#sidebar .dropdown-item:active {
    background-color: #1b2a4a;
    color: #fff;
}

/* ================
   Mobile/Tablet Nav (sidebar.js's setupMobileNav())
   Below the lg breakpoint (991.98px — same cutoff the media query at
   the bottom of this file uses) the real sidebar built by sidebar.js
   (id="sidebar", 280px wide, Bootstrap .nav-pills markup — NOT the
   dead .sidebar/.nav-item rules above, which nothing on the actual
   pages uses) switches from a normal in-flow flex column to an
   off-canvas drawer opened by a hamburger button in a slim top bar.
   ================== */

/* Fixed, not sticky/in-flow: `body` itself is display:flex (see top of
   this file), so a plain inserted child would sit beside the sidebar
   row as a flex item instead of stacking above it. Fixed positioning
   sidesteps that regardless of the parent's layout mode; the content
   wrapper gets margin-top to compensate (see the media query below). */
.gmp-mobile-topbar {
    display: none;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    background: #ffffff;
    border-bottom: 1px solid #dee2e6;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1020;
}

.gmp-mobile-toggle-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    color: #1b2a4a;
    padding: 6px;
    cursor: pointer;
}

.gmp-mobile-toggle-btn i {
    width: 24px;
    height: 24px;
}

.gmp-mobile-topbar-logo {
    height: 28px;
    width: auto;
}

.gmp-sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: 1040;
}

.gmp-sidebar-backdrop.show {
    display: block;
}

/* Locks background scroll behind the open drawer. */
body.gmp-sidebar-locked {
    overflow: hidden;
}

/* ================
   Main Content
   ================== */

.dashboard-main {
    margin-left: 250px;
    padding: 40px;
    flex-grow: 1;
}

.dashboard-header h1 {
    font-size: 1.6rem;
    margin-bottom: 4px;
}

.dashboard-header p {
    color: #777;
}

/* ================
   Stats Cards
   ================== */

.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
    margin-top: 30px;
}

.stat-card {
    background: #ffffff;
    border-radius: 8px;
    padding: 24px;
    display: flex;
    align-items: center;
    gap: 16px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

.stat-card i {
    width: 36px;
    height: 36px;
    color: #1b2a4a;
}

.stat-info {
    display: flex;
    flex-direction: column;
}

.stat-number {
    font-size: 1.5rem;
    font-weight: 700;
}

.stat-label {
    font-size: 0.85rem;
    color: #777;
}

/* ================
   Dashboard Grid
   ================== */

.dashboard-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    margin-top: 30px;
}

.dashboard-card {
    background: #ffffff;
    border-radius: 8px;
    padding: 24px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

.dashboard-card h3 {
    margin-bottom: 20px;
    font-size: 1.1rem;
}

/* ================
   Activity List
   ================== */

.activity-list {
    list-style: none;
}

.activity-list li {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid #f0f0f0;
}

.activity-list li:last-child {
    border-bottom: none;
}

.activity-list li i {
    width: 20px;
    height: 20px;
    color: #1b2a4a;
    flex-shrink: 0;
}

.activity-list li p {
    font-size: 0.95rem;
}

.activity-list li span {
    font-size: 0.8rem;
    color: #999;
}

/* ================
   Events List
   ================== */

.events-list {
    list-style: none;
}

.events-list li {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid #f0f0f0;
}

.events-list li:last-child {
    border-bottom: none;
}

.event-date {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: #1b2a4a;
    color: #ffffff;
    border-radius: 6px;
    padding: 8px 12px;
    min-width: 50px;
}

.event-month {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 1px;
}

.event-day {
    font-size: 1.2rem;
    font-weight: 700;
}

.events-list li p {
    font-size: 0.95rem;
}

.events-list li span {
    font-size: 0.8rem;
    color: #999;
}

/* ================
   Image Upload Slots
   Shared across any page that needs a bounded image-upload
   preview box — events, website builder, profile/logo uploads, etc.
   Usage:
     <div class="image-upload-slot" data-slot="1">
       <span class="upload-placeholder">+ Add Image</span>
       <button type="button" class="remove-image-btn" data-slot="1">&times;</button>
     </div>
     <input type="file" accept="image/*" class="d-none" id="...-image-input-1">
   ================== */

.image-upload-slot {
    border: 2px dashed #dee2e6;
    border-radius: 8px;
    height: 140px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
    cursor: pointer;
    background: #f8f9fa;
}

.image-upload-slot img {
    display: block !important;
    width: 100% !important;
    height: 100% !important;
    max-width: 100% !important;
    max-height: 100% !important;
    object-fit: cover !important;
    margin: 0 !important;
}

.image-upload-slot .upload-placeholder {
    text-align: center;
    color: #777;
    font-size: 0.85rem;
}

.image-upload-slot .remove-image-btn {
    position: absolute;
    top: 4px;
    right: 4px;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    border: none;
    border-radius: 50%;
    width: 22px;
    height: 22px;
    line-height: 1;
    font-size: 0.85rem;
    display: none;
}

.image-upload-slot.has-image .remove-image-btn {
    display: block;
}

/* Size variants — add one of these alongside .image-upload-slot
   for pages that need something other than the 140px default
   (e.g. a wide website-builder banner image). */
.image-upload-slot--sm {
    height: 90px;
}

.image-upload-slot--wide {
    height: 200px;
}

/* ================
   Ticket Tier Rows
   Used on the events page for ticket types / bundles, but generic
   enough to reuse anywhere you need a repeatable, removable row
   of form fields (e.g. website builder page sections).
   ================== */

.ticket-tier-row {
    border: 1px solid #dee2e6;
    border-radius: 8px;
    padding: 12px;
    margin-bottom: 10px;
}

/* ================
   Calendar Grid
   Shared month-view calendar — used on Hall Bookings, and reusable
   for Events or anywhere else a month grid is useful.
   ================== */

.calendar-grid {
    display: grid;
    /* minmax(0, 1fr), not a bare 1fr — a plain 1fr track's implicit
       minimum is its content's max-content width, so a day with a
       long event name (or several events) refuses to shrink below
       that and forces the whole grid, and the page along with it,
       to overflow horizontally instead of just wrapping/eliding the
       event text inside its cell like it's supposed to. */
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 4px;
}

.calendar-grid .cal-dow {
    font-weight: 600;
    font-size: 0.8rem;
    text-align: center;
    padding: 4px 0;
    color: #777;
}

.calendar-grid .cal-cell {
    min-height: 90px;
    border: 1px solid #dee2e6;
    border-radius: 6px;
    padding: 4px;
    font-size: 0.8rem;
}

.calendar-grid .cal-cell.cal-empty {
    border-color: transparent;
}

.calendar-grid .cal-daynum {
    font-weight: 600;
    margin-bottom: 2px;
}

.calendar-grid .cal-event {
    display: block;
    color: #fff;
    border-radius: 4px;
    padding: 1px 4px;
    margin-bottom: 2px;
    font-size: 0.72rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}

.cal-legend-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-right: 4px;
}

/* ================
   Form Fields, Dropdowns & Popups
   Shared focus appearance across every dashboard page — inside modals
   ("pop ups") and on regular pages alike — so native date/time pickers,
   <select> dropdowns, and text/textarea fields all match the same
   brand navy interactive state instead of Bootstrap's default blue.
   The CDN Bootstrap build's own focus colors are hardcoded at compile
   time, so they don't pick up the --bs-primary navy override above;
   these rules override them directly.
   ================== */

input[type="date"],
input[type="time"],
input[type="datetime-local"] {
    color-scheme: light;
}

input[type="date"]:focus,
input[type="time"]:focus,
input[type="datetime-local"]:focus,
.form-select:focus,
.form-control:focus {
    border-color: #1b2a4a;
    box-shadow: 0 0 0 0.25rem rgba(27, 42, 74, 0.25);
}

input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
    cursor: pointer;
    border-radius: 4px;
    padding: 3px;
    transition: background-color 0.15s;
}

input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="time"]::-webkit-calendar-picker-indicator:hover,
input[type="datetime-local"]::-webkit-calendar-picker-indicator:hover {
    background-color: rgba(27, 42, 74, 0.1);
}

/* Bootstrap's .is-invalid paints a background icon meant for plain
   text inputs; it overlaps the native calendar/clock icon on these,
   so drop it and keep just the red border + focus ring. */
input[type="date"].is-invalid,
input[type="time"].is-invalid,
input[type="datetime-local"].is-invalid {
    background-image: none;
    padding-right: 0.75rem;
}

/* Checkboxes, radios, and toggle switches (role="switch") — used for
   things like the deceased flag, the hall booking amount-type radios,
   and the officer public/private visibility switches. Bootstrap's
   checked-state color comes from its own separate
   --bs-form-check-input-checked-bg-color variable, hardcoded at
   compile time, not from --bs-primary above, so it still showed
   Bootstrap's default blue instead of navy until overridden directly. */
.form-check-input:checked {
    background-color: #1b2a4a;
    border-color: #1b2a4a;
}

.form-check-input:focus {
    border-color: #1b2a4a;
    box-shadow: 0 0 0 0.25rem rgba(27, 42, 74, 0.25);
}

/* ================
   Custom Dropdown (Assets/JS/custom-select.js)
   The browser draws a native <select>'s open option list itself (OS
   square corners, OS blue highlight) — CSS can only style the closed
   control, not that popup. custom-select.js progressively enhances
   every <select class="form-select"> with a trigger button + list
   built from real HTML, so the open state can finally match the same
   rounded, navy-accented look as the date/time inputs above.
   ================== */

.gmp-select {
    position: relative;
    display: block;
    width: 100%;
}

.gmp-select-native {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
}

.gmp-select-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    /* A <button> doesn't size itself the same way an <input> does even
       with identical padding/line-height/border — this pins it to
       Bootstrap's own .form-control height formula (padding-y*2 +
       line-height + border*2) so it's pixel-exact with the text inputs
       it sits next to (e.g. the City/State/Zip row). */
    height: calc(1.5em + 0.75rem + 2px);
    padding: 0.375rem 0.75rem;
    font-size: 1rem;
    font-family: inherit;
    line-height: 1.5;
    color: #212529;
    background-color: #fff;
    border: 1px solid #ced4da;
    border-radius: 0.375rem;
    text-align: left;
    cursor: pointer;
}

/* Single line, elided with "…" — this has to stay a fixed one-line
   height so a select sits flush with the plain-text inputs next to it
   (e.g. City/State/Zip rows). min-width: 0 is required alongside
   flex-shrink on a flex child for ellipsis to kick in at all instead
   of the row just overflowing. The full, un-truncated text is still
   available two other ways: the native title tooltip set in
   custom-select.js, and the open option list itself, which wraps
   instead of eliding (see .gmp-select-option). */
.gmp-select-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.gmp-select-trigger:hover {
    border-color: #adb5bd;
}

.gmp-select-trigger:focus,
.gmp-select-trigger.open {
    outline: 0;
    border-color: #1b2a4a;
    box-shadow: 0 0 0 0.25rem rgba(27, 42, 74, 0.25);
}

.gmp-select-trigger.is-invalid {
    border-color: #dc3545;
}

.gmp-select-caret {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    color: #666;
    transition: transform 0.15s;
}

.gmp-select-trigger.open .gmp-select-caret {
    transform: rotate(180deg);
}

.gmp-select-sm .gmp-select-trigger {
    height: calc(1.5em + 0.5rem + 2px);
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
    border-radius: 0.25rem;
}

/* Portaled to <body> (see custom-select.js) so it's never clipped by
   a scrolling panel or trapped under a modal's stacking context. */
.gmp-select-menu {
    position: fixed;
    z-index: 1080;
    display: none;
    background: #fff;
    border: 1px solid #ced4da;
    border-radius: 0.5rem;
    box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.15);
    padding: 6px;
    max-height: 260px;
    overflow-y: auto;
}

.gmp-select-menu.open {
    display: block;
}

.gmp-select-option {
    padding: 8px 12px;
    border-radius: 0.375rem;
    font-size: 1rem;
    cursor: pointer;
}

.gmp-select-option:hover,
.gmp-select-option.active {
    background-color: rgba(27, 42, 74, 0.08);
}

.gmp-select-option.selected {
    background-color: #1b2a4a;
    color: #fff;
}

.gmp-select-option.selected:hover,
.gmp-select-option.selected.active {
    background-color: #14213a;
}

/* ================
   Responsive
   ================== */

@media (max-width: 1024px) {
    .stats-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .dashboard-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 768px) {
    .sidebar {
        width: 60px;
    }

    .sidebar-nav span,
    .sidebar-bottom span {
        display: none;
    }

    .nav-item {
        justify-content: center;
        padding: 12px;
    }

    .dashboard-main {
        margin-left: 60px;
    }
}

/* Flex items default to min-width:auto — meaning a page's content
   wrapper won't actually shrink below its own content's natural
   width, no matter how much room the (now off-canvas, or even still
   280px-wide) sidebar frees up. That's what let wide content on a
   couple of pages (a calendar grid, a horizontally-scrolling tab bar)
   push the whole page into a horizontal scrollbar instead of
   containing/wrapping/eliding within itself the way each was meant
   to. Applies at every width, not just mobile — harmless wherever
   content already fit, since min-width:0 only matters once something
   inside actually needs to shrink below its natural size. */
#sidebar ~ .flex-grow-1 {
    min-width: 0;
}

/* Real sidebar (id="sidebar", built by sidebar.js) → off-canvas drawer.
   991.98px matches Bootstrap's own lg breakpoint, so this also covers
   tablets in portrait, not just phones — a 280px static sidebar plus
   a page's own content (or, on the website builder, an additional
   360px editor panel) doesn't leave usable room below that width. */
@media (max-width: 991.98px) {
    .gmp-mobile-topbar {
        display: flex;
    }

    /* Every dashboard page's content wrapper is the sidebar's next
       sibling and carries flex-grow-1 (that's what makes it fill the
       rest of the row next to the sidebar in the first place) — this
       reserves room for the fixed topbar above it without needing to
       enumerate each page's own extra classes. */
    #sidebar ~ .flex-grow-1 {
        margin-top: 52px;
        /* The floating help button (Assets/JS/help-widget.js) is a
           fixed 56px circle sitting over the bottom-right corner on
           every page. Reserve 2x its height as bottom padding so
           scrolling to the end of a page's content never leaves the
           last bit of it hidden behind the button. !important because
           every page sets this wrapper's padding via Bootstrap's `.p-4`
           utility, which is itself !important — a plain override here
           would silently lose to it. */
        padding-bottom: calc(56px * 2) !important;
    }

    #sidebar {
        position: fixed;
        top: 0;
        left: 0;
        width: 280px;
        height: 100vh;
        z-index: 1045;
        transform: translateX(-100%);
        transition: transform 0.25s ease;
    }

    #sidebar.gmp-sidebar-open {
        transform: translateX(0);
    }

    #sidebar > div {
        height: 100%;
        overflow-y: auto;
    }
}

/* Safety net for the page-header / toolbar / filter-bar pattern used
   throughout the dashboard — a heading (or descriptive text) paired
   with one or more buttons/selects via `d-flex justify-content-between`,
   with no flex-wrap. That fits fine on desktop, but on a narrow phone
   the two sides can no longer share a row without overflowing or
   squeezing the control down to nothing. Wrapping only changes
   anything once a row is already too tight to fit unwrapped, so this
   is free on every screen size it doesn't affect. */
@media (max-width: 767.98px) {
    .d-flex.justify-content-between {
        flex-wrap: wrap;
        row-gap: 0.75rem;
    }
}