/* ==========================================================================
   Quoin design system
   --------------------------------------------------------------------------
   Standalone: no Bootstrap, no theme, no CDN. Everything a page needs is here.
   Brand navy (#14213d) is the same one the branded emails use, so the web app
   and the mail a resident receives read as one product.

   Sections: 1 tokens · 2 reset · 3 shell · 4 sidebar · 5 topbar · 6 layout
             7 cards · 8 stats · 9 tables · 10 badges · 11 buttons · 12 misc
   ========================================================================== */

/* 1 — tokens ============================================================== */
:root {
    /* brand */
    --qm-navy: #14213d;
    --qm-navy-700: #1c2d52;
    --qm-navy-500: #33456f;
    --qm-gold: #c8a35a;

    /* surfaces */
    --qm-bg: #f4f6f8;
    --qm-surface: #ffffff;
    --qm-surface-2: #fafbfc;
    --qm-border: #e4e7ec;
    --qm-border-strong: #d0d5dd;

    /* text */
    --qm-ink: #14213d;
    --qm-ink-2: #475467;
    --qm-ink-3: #667085;
    --qm-ink-inv: #ffffff;

    /* semantic — money states carry meaning, so they get their own ramp */
    --qm-ok: #067647;
    --qm-ok-bg: #ecfdf3;
    --qm-due: #b54708;
    --qm-due-bg: #fffaeb;
    --qm-overdue: #b42318;
    --qm-overdue-bg: #fef3f2;
    --qm-info: #175cd3;
    --qm-info-bg: #eff8ff;

    /* geometry */
    --qm-r-sm: 8px;
    --qm-r: 12px;
    --qm-r-lg: 16px;
    --qm-sidebar-w: 256px;

    /* elevation — kept shallow; depth comes from borders, not drop shadows */
    --qm-shadow-xs: 0 1px 2px rgba(16, 24, 40, .05);
    --qm-shadow: 0 1px 3px rgba(16, 24, 40, .08), 0 1px 2px rgba(16, 24, 40, .04);
    --qm-shadow-lg: 0 12px 32px -8px rgba(16, 24, 40, .14);

    --qm-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* 2 — reset =============================================================== */
*, *::before, *::after { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    /* The old theme leaked horizontal scroll on every page; contain it once here. */
    overflow-x: hidden;
}

body {
    font-family: var(--qm-font);
    font-size: 14px;
    line-height: 1.5;
    color: var(--qm-ink-2);
    background: var(--qm-bg);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 { margin: 0; color: var(--qm-ink); font-weight: 600; letter-spacing: -.01em; }
h1 { font-size: 24px; }
h2 { font-size: 20px; }
h3 { font-size: 16px; }
p { margin: 0; }
a { color: var(--qm-info); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
    outline: 2px solid var(--qm-info);
    outline-offset: 2px;
    border-radius: 4px;
}

/* 3 — shell =============================================================== */
.qm-shell { display: flex; min-height: 100vh; }

.qm-main {
    flex: 1;
    min-width: 0; /* lets wide tables scroll inside instead of stretching the page */
    display: flex;
    flex-direction: column;
    margin-left: var(--qm-sidebar-w); /* clears the fixed sidebar */
}

/* 4 — sidebar ============================================================= */
/* Fixed, not sticky: `overflow-x: hidden` on body turns an ancestor into a
   scroll container, which quietly kills position:sticky. Fixed is immune, so
   the nav stays put no matter how far the page scrolls. .qm-main is inset by
   the same width to make room for it. */
.qm-sidebar {
    width: var(--qm-sidebar-w);
    flex-shrink: 0;
    background: var(--qm-navy);
    color: rgba(255, 255, 255, .72);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: 30;
}

.qm-sidebar__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 22px 20px;
    color: #fff;
    font-weight: 600;
    font-size: 15px;
    letter-spacing: -.01em;
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.qm-sidebar__brand:hover { text-decoration: none; color: #fff; }

.qm-sidebar__mark {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--qm-gold);
    color: var(--qm-navy);
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: 13px;
    flex-shrink: 0;
}

.qm-sidebar__nav { padding: 14px 12px; flex: 1; overflow-y: auto; }

.qm-sidebar__label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: rgba(255, 255, 255, .38);
    padding: 14px 10px 6px;
    font-weight: 600;
}

.qm-nav-item {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 10px;
    border-radius: var(--qm-r-sm);
    color: rgba(255, 255, 255, .72);
    font-weight: 500;
    margin-bottom: 2px;
    transition: background .12s ease, color .12s ease;
}
.qm-nav-item:hover { background: rgba(255, 255, 255, .07); color: #fff; text-decoration: none; }
.qm-nav-item.is-active { background: var(--qm-navy-700); color: #fff; box-shadow: inset 2px 0 0 var(--qm-gold); }
.qm-nav-item svg { width: 17px; height: 17px; flex-shrink: 0; opacity: .85; }

.qm-sidebar__foot { padding: 14px 12px; border-top: 1px solid rgba(255, 255, 255, .08); }

/* 5 — topbar ============================================================== */
.qm-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 28px;
    background: var(--qm-surface);
    border-bottom: 1px solid var(--qm-border);
    position: sticky;
    top: 0;
    z-index: 20;
}

.qm-topbar__crumb { font-size: 12px; color: var(--qm-ink-3); margin-bottom: 2px; }

.qm-user {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--qm-ink);
}
.qm-user:hover { text-decoration: none; }

.qm-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--qm-navy);
    color: #fff;
    display: grid;
    place-items: center;
    font-weight: 600;
    font-size: 13px;
    flex-shrink: 0;
}

.qm-user__name { font-weight: 600; font-size: 13px; line-height: 1.3; }
.qm-user__role { font-size: 12px; color: var(--qm-ink-3); text-transform: capitalize; }

/* 6 — layout ============================================================== */
.qm-container { padding: 28px; max-width: 1400px; width: 100%; }

.qm-page-head { margin-bottom: 22px; }
.qm-page-head p { color: var(--qm-ink-3); margin-top: 4px; }

.qm-grid { display: grid; gap: 16px; margin-bottom: 16px; }
/* --auto adapts to however many cards a role actually gets: a leaseholder-only
   user has fewer stats than someone who is also a landlord. */
.qm-grid--auto { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.qm-grid--4 { grid-template-columns: repeat(4, 1fr); }
.qm-grid--3 { grid-template-columns: repeat(3, 1fr); }
.qm-grid--2 { grid-template-columns: repeat(2, 1fr); }
/* Three equal tracks with the main column spanning two — NOT 2fr/1fr. With a
   16px gap those aren't the same thing: 2fr/1fr has one gap to distribute where
   a 3-up --auto row above has two, so its right column lands ~5px left of the
   third card and the page reads as very slightly out of true. Sharing the track
   system makes the edges line up exactly. */
.qm-grid--sidebar-right { grid-template-columns: repeat(3, 1fr); align-items: start; }
.qm-grid--sidebar-right > :first-child { grid-column: span 2; }

/* 7 — cards =============================================================== */
.qm-card {
    background: var(--qm-surface);
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-r);
    box-shadow: var(--qm-shadow-xs);
}

.qm-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--qm-border);
}
.qm-card__head p { font-size: 13px; color: var(--qm-ink-3); margin-top: 2px; }

.qm-card__body { padding: 18px; }
.qm-card__body--flush { padding: 0; }

/* 8 — stats =============================================================== */
/* Column layout so the sub-line can be pinned to the bottom. The cards already
   stretch to equal height as grid items, but their CONTENT drifted: a value that
   wraps (a long building name at 28px) pushed its sub-line lower than the
   single-digit cards beside it, so the three rows of text didn't line up. */
.qm-stat { padding: 18px; display: flex; flex-direction: column; }
.qm-stat__label {
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--qm-ink-3);
    display: flex;
    align-items: center;
    gap: 7px;
}
.qm-stat__value {
    font-size: 28px;
    font-weight: 700;
    color: var(--qm-ink);
    margin-top: 8px;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums; /* money columns must align */
}
/* margin-top:auto rather than 4px — the sub-line sits on the card's baseline so
   it agrees with its neighbours; padding-top keeps the gap when nothing wraps. */
.qm-stat__sub { font-size: 12px; color: var(--qm-ink-3); margin-top: auto; padding-top: 4px; }
.qm-stat__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--qm-ink-3); }
.qm-stat__dot--ok { background: var(--qm-ok); }
.qm-stat__dot--due { background: var(--qm-due); }
.qm-stat__dot--overdue { background: var(--qm-overdue); }

.qm-progress {
    height: 8px;
    border-radius: 999px;
    background: var(--qm-border);
    overflow: hidden;
    margin-top: 14px;
}
.qm-progress__bar { height: 100%; border-radius: 999px; background: var(--qm-ok); }

/* 9 — tables ============================================================== */
.qm-table-wrap { overflow-x: auto; }

.qm-table { width: 100%; border-collapse: collapse; font-size: 13px; }

.qm-table th {
    text-align: left;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--qm-ink-3);
    background: var(--qm-surface-2);
    padding: 10px 18px;
    border-bottom: 1px solid var(--qm-border);
    white-space: nowrap;
}

.qm-table td {
    padding: 14px 18px;
    border-bottom: 1px solid var(--qm-border);
    color: var(--qm-ink-2);
    vertical-align: middle;
}
.qm-table tbody tr:last-child td { border-bottom: 0; }
.qm-table tbody tr:hover td { background: var(--qm-surface-2); }

.qm-table__strong { color: var(--qm-ink); font-weight: 600; }
.qm-table__num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.qm-table__ref { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--qm-ink-3); }

/* 10 — badges ============================================================= */
.qm-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    background: var(--qm-bg);
    color: var(--qm-ink-2);
    white-space: nowrap;
}
.qm-badge--ok { background: var(--qm-ok-bg); color: var(--qm-ok); }
.qm-badge--due { background: var(--qm-due-bg); color: var(--qm-due); }
.qm-badge--overdue { background: var(--qm-overdue-bg); color: var(--qm-overdue); }
.qm-badge--info { background: var(--qm-info-bg); color: var(--qm-info); }

/* 11 — buttons ============================================================ */
.qm-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    /* Never break the label. In a narrow table cell "Pay now" was wrapping to
       two lines and reading as a stacked button; .qm-table-wrap already scrolls
       horizontally, so holding the width costs nothing. */
    white-space: nowrap;
    padding: 9px 15px;
    border-radius: var(--qm-r-sm);
    border: 1px solid transparent;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
}
.qm-btn:hover { text-decoration: none; }

.qm-btn--primary { background: var(--qm-navy); color: #fff; }
.qm-btn--primary:hover { background: var(--qm-navy-700); color: #fff; }

.qm-btn--ghost { background: var(--qm-surface); border-color: var(--qm-border-strong); color: var(--qm-ink); }
.qm-btn--ghost:hover { background: var(--qm-surface-2); color: var(--qm-ink); }

.qm-btn--sm { padding: 6px 11px; font-size: 12px; }

/* 12 — misc =============================================================== */
/* Quick-action tiles — replaces the old dashboard's stock-photo cards. */
.qm-action {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px;
    background: var(--qm-surface);
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-r);
    color: var(--qm-ink);
    font-weight: 600;
    box-shadow: var(--qm-shadow-xs);
    transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.qm-action:hover {
    text-decoration: none;
    color: var(--qm-ink);
    border-color: var(--qm-navy-500);
    box-shadow: var(--qm-shadow);
    transform: translateY(-1px);
}
.qm-action__icon {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    background: var(--qm-info-bg);
    color: var(--qm-info);
    flex-shrink: 0;
}
.qm-action__icon svg { width: 18px; height: 18px; }
.qm-action__icon--gold { background: #fdf6e7; color: #a97e28; }
.qm-action__icon--ok { background: var(--qm-ok-bg); color: var(--qm-ok); }
.qm-action__icon--due { background: var(--qm-due-bg); color: var(--qm-due); }
/* Teal. Deliberately not a status token: the dashboard tiles use green (--ok),
   amber (--due) and the indigo accent (default), so a 4th tile needs a hue none
   of those already own — --gold read as a second amber next to Maintenance. */
.qm-action__icon--teal { background: #cfeae5; color: #0b5f57; }
.qm-action small { display: block; font-weight: 400; font-size: 12px; color: var(--qm-ink-3); }

/* Property / announcement rows */
.qm-list { list-style: none; margin: 0; padding: 0; }
.qm-list li { padding: 14px 18px; border-bottom: 1px solid var(--qm-border); }
.qm-list li:last-child { border-bottom: 0; }

.qm-item__title { font-weight: 600; color: var(--qm-ink); }
.qm-item__meta { font-size: 12px; color: var(--qm-ink-3); margin-top: 3px; }
.qm-item__body {
    font-size: 13px;
    margin-top: 6px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.qm-empty { padding: 40px 20px; text-align: center; color: var(--qm-ink-3); }
.qm-empty svg { width: 30px; height: 30px; opacity: .35; margin-bottom: 10px; }
.qm-empty__title { font-weight: 600; color: var(--qm-ink-2); }
.qm-empty p { font-size: 13px; margin-top: 4px; }

.qm-money { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--qm-ink); }

/* Embedded documents-app PDF (invoice / receipt) */
.qm-doc-frame {
    width: 100%;
    height: 520px;
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-r-sm);
    background: var(--qm-surface-2);
}
.qm-doc-frame--tall { height: 720px; }

/* Key/value summary (payment page) */
.qm-kv { display: grid; grid-template-columns: 110px 1fr; gap: 10px 16px; margin: 0; }
.qm-kv dt { font-size: 12px; color: var(--qm-ink-3); font-weight: 600; }
.qm-kv dd { margin: 0; color: var(--qm-ink); }

.qm-amount {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--qm-border);
}
.qm-amount span { font-size: 13px; color: var(--qm-ink-3); }
.qm-amount strong {
    font-size: 24px;
    font-weight: 700;
    color: var(--qm-ink);
    font-variant-numeric: tabular-nums;
}

/* Forms */
.qm-label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--qm-ink);
    margin: 18px 0 7px;
}
.qm-label:first-child { margin-top: 0; }

.qm-input {
    width: 100%;
    padding: 13px 14px;
    font-family: inherit;
    font-size: 15px;
    line-height: 20px;
    color: var(--qm-ink);
    background: var(--qm-surface);
    border: 1px solid var(--qm-border-strong);
    border-radius: 10px;
    transition: border-color .12s ease, box-shadow .12s ease;
}
.qm-input::placeholder { color: #98a2b3; }
.qm-input:focus,
.qm-input--card.StripeElement--focus {
    outline: none;
    border-color: var(--qm-navy-500);
    box-shadow: 0 0 0 4px rgba(20, 33, 61, .08);
}

/* Stripe mounts its own iframe in here. It needs real height (the iframe is
   ~20px tall and was being crushed by input padding) and no text styling of its
   own — the type is set through Stripe's `style` API in the template instead. */
.qm-input--card {
    padding: 14px;
    min-height: 50px;
}
.qm-input--card.StripeElement--invalid { border-color: var(--qm-overdue); }

.qm-field-error { color: var(--qm-overdue); font-size: 13px; min-height: 18px; margin-top: 7px; }

.qm-check { display: flex; gap: 10px; align-items: flex-start; margin-top: 18px; font-size: 13px; }
.qm-check input { margin-top: 2px; width: 16px; height: 16px; accent-color: var(--qm-navy); }

/* Card-brand marks + the "secure" reassurance line on the pay form */
.qm-cards { display: flex; gap: 6px; align-items: center; }
.qm-cards span {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .02em;
    color: var(--qm-ink-3);
    background: var(--qm-bg);
    border: 1px solid var(--qm-border);
    border-radius: 4px;
    padding: 3px 5px;
}

.qm-secure {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--qm-border);
    font-size: 12px;
    color: var(--qm-ink-3);
}
.qm-secure svg { width: 14px; height: 14px; flex-shrink: 0; }

.qm-btn--lg { padding: 14px 18px; font-size: 15px; border-radius: 10px; }

/* Django-rendered forms ({{ form.as_p }}). website.forms stamps `form-control`
   onto every non-checkbox widget, so style that class rather than rewriting the
   forms. Scoped inside .qm-form so it can't touch the old Bootstrap pages. */
.qm-form p { margin: 0 0 16px; }
.qm-form label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--qm-ink);
    margin-bottom: 7px;
}
.qm-form .form-control,
.qm-form input[type="text"],
.qm-form input[type="email"],
.qm-form input[type="password"],
.qm-form input[type="number"],
.qm-form input[type="date"],
.qm-form select,
.qm-form textarea {
    width: 100%;
    padding: 12px 14px;
    font-family: inherit;
    font-size: 15px;
    color: var(--qm-ink);
    background: var(--qm-surface);
    border: 1px solid var(--qm-border-strong);
    border-radius: 10px;
    transition: border-color .12s ease, box-shadow .12s ease;
}
.qm-form textarea { min-height: 110px; resize: vertical; }

/* iOS Safari gives input[type="date"] a native control with its own intrinsic
   width that ignores the width:100% above, so on a narrow card the field runs
   past the edge. Resetting the appearance makes it size like every other input;
   min-width:0 lets it actually shrink. Left-align the value because iOS centres
   it once the appearance is reset. */
.qm-form input[type="date"] {
    -webkit-appearance: none;
    appearance: none;
    min-width: 0;
    max-width: 100%;
}
.qm-form input[type="date"]::-webkit-date-and-time-value { text-align: left; }
.qm-form .form-control:focus,
.qm-form select:focus,
.qm-form textarea:focus {
    outline: none;
    border-color: var(--qm-navy-500);
    box-shadow: 0 0 0 4px rgba(20, 33, 61, .08);
}
.qm-form .helptext { display: block; font-size: 12px; color: var(--qm-ink-3); margin-top: 5px; }
.qm-form ul.errorlist {
    list-style: none;
    margin: 0 0 6px;
    padding: 0;
    color: var(--qm-overdue);
    font-size: 12px;
    font-weight: 500;
}

/* Profile header */
.qm-profile { padding: 22px; }
.qm-profile__head { display: flex; gap: 18px; align-items: center; }
.qm-profile__head h2 { font-size: 20px; }

.qm-profile__pic,
.qm-profile__initials {
    width: 68px;
    height: 68px;
    border-radius: 50%;
    flex-shrink: 0;
    object-fit: cover;
}
.qm-profile__initials {
    display: grid;
    place-items: center;
    background: var(--qm-navy);
    color: #fff;
    font-size: 22px;
    font-weight: 600;
}
.qm-profile__roles { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.qm-profile__roles .qm-badge { text-transform: capitalize; }
.qm-profile__facts { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--qm-border); }

/* Tabs */
.qm-tabs {
    display: flex;
    gap: 2px;
    padding: 0 18px;
    border-bottom: 1px solid var(--qm-border);
    overflow-x: auto;
}
.qm-tab {
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    padding: 14px 12px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    color: var(--qm-ink-3);
    cursor: pointer;
    white-space: nowrap;
}
.qm-tab:hover { color: var(--qm-ink); }
.qm-tab.is-active { color: var(--qm-ink); border-bottom-color: var(--qm-navy); }

.qm-panel { display: none; }
.qm-panel.is-active { display: block; }

/* Notification preferences */
.qm-pref {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 16px 0;
    border-bottom: 1px solid var(--qm-border);
}
.qm-pref:first-child { padding-top: 0; }
.qm-pref__channels { display: flex; gap: 8px; flex-shrink: 0; }

.qm-switch {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 11px;
    border: 1px solid var(--qm-border-strong);
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    text-transform: capitalize;
    color: var(--qm-ink-2);
    cursor: pointer;
    background: var(--qm-surface);
}
.qm-switch input { accent-color: var(--qm-navy); margin: 0; }
.qm-switch svg { width: 12px; height: 12px; opacity: .5; }
.qm-switch.is-locked { background: var(--qm-bg); color: var(--qm-ink-3); cursor: not-allowed; }

.qm-alert--ok { background: var(--qm-ok-bg); color: var(--qm-ok); }

/* ---------- Calendar ---------- */
/* Filter pills (all buildings / per block) */
.qm-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.qm-filter {
    padding: 7px 13px;
    border-radius: 999px;
    border: 1px solid var(--qm-border);
    background: var(--qm-surface);
    font-size: 13px;
    font-weight: 600;
    color: var(--qm-ink-2);
}
.qm-filter:hover { text-decoration: none; border-color: var(--qm-navy-500); color: var(--qm-ink); }
.qm-filter.is-active { background: var(--qm-navy); border-color: var(--qm-navy); color: #fff; }

.qm-monthnav { display: flex; gap: 6px; }
.qm-monthnav svg { width: 14px; height: 14px; }

/* Month grid — server-rendered, no calendar library */
.qm-cal { padding: 0 4px 4px; }
.qm-cal__head,
.qm-cal__week { display: grid; grid-template-columns: repeat(7, 1fr); }

.qm-cal__head span {
    padding: 10px 8px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--qm-ink-3);
    text-align: left;
}

.qm-cal__day {
    min-height: 104px;
    padding: 7px;
    border-top: 1px solid var(--qm-border);
    border-right: 1px solid var(--qm-border);
    display: flex;
    flex-direction: column;
    gap: 3px;
    overflow: hidden;
}
.qm-cal__week > .qm-cal__day:last-child { border-right: 0; }
.qm-cal__day.is-outside { background: var(--qm-surface-2); }
.qm-cal__day.is-outside .qm-cal__num { color: #b8bfc9; }

.qm-cal__num {
    font-size: 12px;
    font-weight: 600;
    color: var(--qm-ink-2);
    width: 22px;
    height: 22px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    flex-shrink: 0;
}
.qm-cal__day.is-today .qm-cal__num { background: var(--qm-navy); color: #fff; }

/* Event chip. Operational categories read muted; community ones are the ones
   residents act on, so they carry the colour. */
.qm-chip {
    display: block;
    padding: 3px 6px;
    border-radius: 5px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.35;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    background: var(--qm-bg);
    color: var(--qm-ink-2);
    border-left: 3px solid var(--qm-ink-3);
    cursor: default;
}
.qm-chip__time { opacity: .65; margin-right: 4px; font-variant-numeric: tabular-nums; }

/* operational */
.qm-chip--MT { background: var(--qm-due-bg); color: var(--qm-due); border-left-color: var(--qm-due); }
.qm-chip--CO { background: var(--qm-due-bg); color: var(--qm-due); border-left-color: var(--qm-due); }
.qm-chip--SI { background: var(--qm-bg); color: var(--qm-ink-2); border-left-color: var(--qm-ink-3); }
.qm-chip--GR { background: var(--qm-ok-bg); color: var(--qm-ok); border-left-color: var(--qm-ok); }
.qm-chip--PY { background: var(--qm-overdue-bg); color: var(--qm-overdue); border-left-color: var(--qm-overdue); }
/* community — these accept RSVPs */
.qm-chip--AG { background: var(--qm-info-bg); color: var(--qm-info); border-left-color: var(--qm-info); }
.qm-chip--ME { background: var(--qm-info-bg); color: var(--qm-info); border-left-color: var(--qm-info); }
.qm-chip--SO { background: #fdf6e7; color: #a97e28; border-left-color: var(--qm-gold); }
.qm-chip--WK { background: #f4f1ff; color: #5b4bc4; border-left-color: #5b4bc4; }

/* Upcoming-event cards */
.qm-event__image {
    display: block;
    width: 100%;
    max-height: 140px;
    object-fit: cover;
    border-radius: var(--qm-r-sm);
    margin-bottom: 10px;
}
.qm-event__when {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    color: var(--qm-ink-3);
    margin-top: 5px;
}
.qm-event__when svg { width: 13px; height: 13px; flex-shrink: 0; }

.qm-event__rsvp {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--qm-border);
}
.qm-rsvp { display: flex; gap: 4px; }
.qm-rsvp__btn {
    padding: 6px 11px;
    border: 1px solid var(--qm-border-strong);
    background: var(--qm-surface);
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    color: var(--qm-ink-2);
    cursor: pointer;
}
.qm-rsvp__btn:first-child { border-radius: 8px 0 0 8px; }
.qm-rsvp__btn:last-child { border-radius: 0 8px 8px 0; }
.qm-rsvp__btn:hover:not(:disabled) { background: var(--qm-bg); color: var(--qm-ink); }
.qm-rsvp__btn.is-on { background: var(--qm-navy); border-color: var(--qm-navy); color: #fff; }
.qm-rsvp__btn:disabled { opacity: .45; cursor: not-allowed; }
.qm-rsvp__error:not(:empty) {
    margin-top: 8px;
    font-size: 12px;
    font-weight: 500;
    color: var(--qm-overdue);
}

@media (max-width: 900px) {
    .qm-cal__day { min-height: 72px; }
    .qm-chip { font-size: 10px; }
}

/* Report-an-issue: file input + photo preview */
.qm-form input[type="file"] {
    width: 100%;
    padding: 11px 13px;
    font-size: 13px;
    color: var(--qm-ink-2);
    background: var(--qm-surface-2);
    border: 1px dashed var(--qm-border-strong);
    border-radius: 10px;
    cursor: pointer;
}
.qm-form input[type="file"]:hover { border-color: var(--qm-navy-500); }

.qm-preview {
    display: block;
    margin-top: 10px;
    max-width: 100%;
    max-height: 220px;
    border-radius: var(--qm-r-sm);
    border: 1px solid var(--qm-border);
}

/* Maintenance */
.qm-issue { display: flex; align-items: flex-start; gap: 11px; }
.qm-issue__thumb {
    width: 44px;
    height: 44px;
    border-radius: 8px;
    object-fit: cover;
    border: 1px solid var(--qm-border);
    flex-shrink: 0;
}
.qm-issue__text {
    display: block;
    max-width: 380px; /* one long paragraph must not blow the row height out */
    color: var(--qm-ink);
}
.qm-issue__text .qm-item__meta { display: block; }

/* "Report an issue" -> pick which tenancy/block it's against */
/* flex:0 0 auto — as a flex child in the page header it must not shrink below
   its own label; it wraps to the next line instead (see pages/issues.html). */
.qm-report { position: relative; flex: 0 0 auto; }
.qm-report__menu {
    display: none;
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    min-width: 240px;
    background: var(--qm-surface);
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-r);
    box-shadow: var(--qm-shadow-lg);
    padding: 6px;
    z-index: 40;
}
.qm-report__menu.is-open { display: block; }
/* Once the page header wraps, the button sits at the LEFT of its own row, so
   right:0 anchors the menu's right edge to the button's and the 240px panel
   runs off the left of the screen. Anchor it left instead, and cap the width
   to the viewport (36px = the .qm-container padding either side). */
@media (max-width: 820px) {
    .qm-report__menu {
        right: auto;
        left: 0;
        min-width: min(240px, calc(100vw - 36px));
        max-width: calc(100vw - 36px);
    }
}
.qm-report__menu a {
    display: block;
    padding: 9px 11px;
    border-radius: var(--qm-r-sm);
    font-size: 13px;
    font-weight: 500;
    color: var(--qm-ink);
}
.qm-report__menu a:hover { background: var(--qm-bg); text-decoration: none; }

/* Document viewer — an uploaded photo is routinely 4000px wide; contain it to the
   card rather than letting the browser paint it at natural size. */
.qm-viewer {
    display: flex;
    justify-content: center;
    background: var(--qm-bg);
    border: 1px solid var(--qm-border);
    border-radius: var(--qm-r-sm);
    padding: 12px;
}
.qm-viewer img {
    display: block;
    max-width: 100%;
    max-height: 70vh;
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: 4px;
}

/* Document rows */
.qm-file { display: flex; align-items: center; gap: 11px; }
.qm-file__icon {
    width: 34px;
    height: 34px;
    border-radius: 8px;
    display: grid;
    place-items: center;
    background: var(--qm-info-bg);
    color: var(--qm-info);
    flex-shrink: 0;
}
.qm-file__icon svg { width: 16px; height: 16px; }
.qm-file .qm-table__strong,
.qm-file .qm-item__meta { display: block; }

/* Announcements feed */
.qm-feed {
    display: grid;
    gap: 16px;
    max-width: 760px; /* a readable measure — full-width prose is hard to scan */
}

.qm-post { overflow: hidden; }
.qm-post--pinned { border-color: var(--qm-navy-500); box-shadow: var(--qm-shadow); }

.qm-post__image {
    display: block;
    width: 100%;
    max-height: 280px;
    object-fit: cover;
    border-bottom: 1px solid var(--qm-border);
}

.qm-post__body { padding: 18px; }

.qm-post__meta {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}
.qm-post__date { font-size: 12px; color: var(--qm-ink-3); margin-left: auto; }

.qm-post__title { font-size: 17px; margin-bottom: 8px; }
.qm-post__text { color: var(--qm-ink-2); line-height: 1.6; }

.qm-post__block {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 14px;
    font-size: 12px;
    font-weight: 600;
    color: var(--qm-ink-3);
}
.qm-post__block:hover { color: var(--qm-ink); text-decoration: none; }
.qm-post__block svg { width: 13px; height: 13px; }

.qm-alert {
    padding: 11px 13px;
    border-radius: var(--qm-r-sm);
    font-size: 13px;
    margin-bottom: 14px;
}
.qm-alert--error { background: var(--qm-overdue-bg); color: var(--qm-overdue); }

/* Page-level legal small print — sits below the content grid, full width,
   centred and quiet so it reads as a notice rather than page content. */
.qm-legal {
    margin: 22px 0 0;
    text-align: center;
    font-size: 11px;
    line-height: 1.6;
    color: var(--qm-ink-3);
}

/* Two children only (copyright, link group) so space-between reads as
   left/right rather than scattering uneven columns across the width. */
.qm-footer {
    margin-top: auto;
    padding: 16px 28px;
    border-top: 1px solid var(--qm-border);
    font-size: 12px;
    color: var(--qm-ink-3);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 20px;
}
.qm-footer__links {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}
.qm-footer a {
    color: var(--qm-ink-3);
    text-decoration: none;
    transition: color .12s ease;
}
.qm-footer a:hover {
    color: var(--qm-ink-2);
    text-decoration: underline;
}
/* Stacked and left-aligned on narrow screens — space-between would otherwise
   push the two rows apart once they wrap. */
@media (max-width: 560px) {
    .qm-footer { justify-content: flex-start; gap: 10px; }
}

/* responsive ============================================================== */
@media (max-width: 1100px) {
    .qm-grid--4 { grid-template-columns: repeat(2, 1fr); }
    .qm-grid--sidebar-right { grid-template-columns: 1fr; }
    /* Single column now — a span of 2 would overflow the track count. */
    .qm-grid--sidebar-right > :first-child { grid-column: auto; }
}

@media (max-width: 820px) {
    .qm-shell { flex-direction: column; }
    /* Back into the flow on a phone — a fixed nav would sit on top of the page. */
    .qm-sidebar { width: 100%; height: auto; position: static; }
    .qm-main { margin-left: 0; }
    .qm-sidebar__nav { display: flex; gap: 6px; overflow-x: auto; padding: 10px; }
    .qm-sidebar__label, .qm-sidebar__foot { display: none; }
    .qm-nav-item { white-space: nowrap; margin-bottom: 0; }
    .qm-grid--4, .qm-grid--3, .qm-grid--2 { grid-template-columns: 1fr; }
    .qm-container { padding: 18px; }
    .qm-topbar { padding: 14px 18px; }
}