/* AirCalendar — back-office stylesheet */

/* ============================================================
   Fonts — Inter Variable (https://rsms.me/inter, OFL)
   Drop InterVariable.woff2 into /public/assets/user/fonts/.
   ============================================================ */
@font-face {
    font-family: "Inter";
    src: url("../fonts/InterVariable.woff2") format("woff2-variations"),
         url("../fonts/InterVariable.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

/* ============================================================
   Design tokens — slate palette, light by default
   The theme is selected by an attribute on <html>: data-theme="light" or
   data-theme="dark". An inline <head> script sets it before render to avoid
   FOUC. Layouts that should be locked light (installer, auth) hard-code
   data-theme="light" on <html> and skip the script.
   ============================================================ */
:root,
html[data-theme="light"] {
    --bg:        #f4faf9;   /* faint mint tint */
    --bg-raised: #ffffff;
    --panel:     #ffffff;
    --panel-2:   #eaf4fc;   /* sky-50 (zebra stripes / soft panels) */
    --text:      #0e2a2a;   /* deep teal-ink */
    --text-2:    #234747;
    --muted:     #6b8688;
    --subtle:    #9bb1b3;
    --line:      #d3e6f5;   /* sky-200 */
    --line-2:    #eaf4fc;   /* sky-50 */

    /* Primary accent — sky blue. Used for buttons, links, focus rings,
       active nav, chart strokes, etc. */
    --accent:        #0284c7;   /* sky-600 */
    --accent-ink:    #ffffff;
    --accent-soft:   rgba(2, 132, 199, .08);
    --accent-ring:   rgba(2, 132, 199, .22);
    --accent-strong: #075985;   /* sky-800 — dashboard CTAs */
    --accent-tint:   #e0f2fe;   /* sky-100 — hero card background */
    --accent-tint-2: #bae6fd;   /* sky-200 — slightly stronger tint */

    --ok:   #0f7d5b;
    --warn: #92400e;        /* amber-800 */
    --err:  #b91c1c;        /* red-700  */

    --shadow-sm: 0 1px 2px rgba(15, 23, 42, .05);
    --shadow:    0 1px 3px rgba(15, 23, 42, .06), 0 4px 12px rgba(15, 23, 42, .05);

    --radius:    8px;
    --radius-lg: 12px;
    --radius-xl: 16px;

    --font-heading: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    --font-mono:    ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    --font-feature: "cv02", "cv03", "cv04", "cv11";
}

html[data-theme="dark"] {
    --bg:        #0f172a;   /* slate-900 */
    --bg-raised: #1e293b;   /* slate-800 */
    --panel:     #1e293b;   /* slate-800 */
    --panel-2:   #243044;   /* slate-750-ish (zebra stripes / soft panels) */
    --text:      #e2e8f0;   /* slate-200 */
    --text-2:    #cbd5e1;   /* slate-300 */
    --muted:     #94a3b8;   /* slate-400 */
    --subtle:    #64748b;   /* slate-500 */
    --line:      #334155;   /* slate-700 */
    --line-2:    #1e293b;   /* slate-800 */

    --accent:        #38bdf8;   /* sky-400 — bright sky blue */
    --accent-ink:    #0f172a;   /* slate-900 */
    --accent-soft:   rgba(56, 189, 248, .10);
    --accent-ring:   rgba(56, 189, 248, .28);
    --accent-strong: #7dd3fc;   /* sky-300 */
    --accent-tint:   rgba(56, 189, 248, .12);
    --accent-tint-2: rgba(56, 189, 248, .20);

    --ok:   #86efac;        /* green-300 */
    --warn: #fde68a;        /* amber-200 */
    --err:  #fca5a5;        /* red-300  */

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);
    --shadow:    0 2px 4px rgba(0, 0, 0, .35), 0 8px 24px rgba(0, 0, 0, .25);

    /* Font tokens MUST be redeclared here. `render_site_fonts(false)`
       in the layout emits `--font-heading` at `:root` after this
       stylesheet loads — light mode wins via `html[data-theme="light"]`
       specificity, but dark mode would otherwise pick up the user's
       configured serif heading font. Redeclaring here keeps both
       themes on Inter for the admin chrome. */
    --font-heading: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
    --font-mono:    ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    --font-feature: "cv02", "cv03", "cv04", "cv11";
}

/* Select chevron — separate per theme so the icon stays visible against the bg */
html[data-theme="light"] select {
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
html[data-theme="light"] select:focus {
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%230f172a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
html[data-theme="dark"] select {
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
html[data-theme="dark"] select:focus {
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23f1f5f9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5 9-11'/%3E%3C/svg%3E");
}

/* Stepper checkmark in light needs white on dark bg */
html[data-theme="light"] .step.done .step-dot::before {
    background: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5 9-11'/%3E%3C/svg%3E") center/contain no-repeat;
}
html[data-theme="dark"] .step.done .step-dot::before {
    background: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230f172a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5 9-11'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* Toggle thumb / accent-ink invert per theme — handled by var(--accent) */

* { box-sizing: border-box; }
html, body { height: 100%; }

body {
    font: 14px/1.55 var(--font-body);
    font-feature-settings: var(--font-feature);
    margin: 0;
    background: var(--bg);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ============================================================
   Typography
   ============================================================ */
h1, h2, h3, h4 {
    font-family: var(--font-heading);
    font-weight: 600;
    letter-spacing: -0.015em;
    margin: 0 0 12px;
    line-height: 1.2;
    color: var(--text);
}
h1 { font-size: 22px; }
h2 { font-size: 17px; }
h3 { font-size: 15px; }
h4 { font-size: 13px; }

p { margin: 0 0 12px; color: var(--text-2); }
small { font-size: 12px; color: var(--muted); }

a { color: var(--text); text-decoration: none; }
a:hover { color: var(--text); }

code {
    background: var(--line-2);
    padding: 2px 6px;
    border-radius: 4px;
    font: 12.5px var(--font-mono);
    color: var(--text-2);
}

hr { border: 0; border-top: 1px solid var(--line); margin: 24px 0; }

/* .muted and .small moved to shared.css */
.subtle  { color: var(--subtle); }
.tiny    { font-size: 11px; }

/* ============================================================
   Layout utilities
   ============================================================ */
.stack    { display: flex; flex-direction: column; gap: 12px; }
.stack-sm { display: flex; flex-direction: column; gap: 6px; }
.stack-lg { display: flex; flex-direction: column; gap: 20px; }
/* .hstack moved to shared.css */
.hstack-sm { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.spread   { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.grow     { flex: 1; }
.nowrap   { white-space: nowrap; }
.center   { text-align: center; }
.hidden   { display: none !important; }

/* ============================================================
   Cards — subtle elevation
   ============================================================ */
/* .card base moved to shared.css. Admin-only variants below. */
.card--flush { margin: 0; }
.card--padded { padding: 32px; }
.card > h2:first-child { margin-top: 0; }
.card h2 { margin: 24px 0 14px; font-size: 17px; }
.card h2:first-child { margin-top: 0; }
.card-divider { margin: 20px -24px; border-top: 1px solid var(--line); }

/* ============================================================
   Stats grid — proper dashboard cards
   ============================================================ */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin-bottom: 28px;
}
.stat {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 20px 22px;
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.stat-label {
    font-size: 11px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .08em;
    font-weight: 500;
}
.stat-value {
    font-family: var(--font-heading);
    font-size: 34px;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--text);
}
.stat-value.muted { color: var(--subtle); }
.stat-hint { color: var(--muted); font-size: 12px; }
.stat-delta { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); }

/* ============================================================
   Forms
   ============================================================ */
label {
    display: block;
    margin: 14px 0 5px;
    font-size: 12px;
    color: var(--muted);
    font-weight: 500;
    letter-spacing: 0.01em;
}
label:first-child { margin-top: 0; }
/* Labels inside a .row column ARE first-child of their own <div>, so
   the rule above nukes their top margin even though they sit in the
   middle of a form. Restore the standard vertical rhythm so the
   nested label (e.g. "Location", "Sub-location") doesn't hug the
   field directly above the row. Specificity beats :first-child. */
.row > div > label { margin-top: 14px; }

input[type="text"],
input[type="email"],
input[type="password"],
input[type="url"],
input[type="number"],
input[type="tel"],
input[type="search"],
input[type="date"],
input[type="datetime-local"],
input[type="time"],
select,
textarea {
    width: 100%;
    padding: 7px 11px;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    line-height: 1.5;
    transition: border-color .15s, box-shadow .15s, background .15s;
}
.row input, .row select, .row textarea,
.row-3 input, .row-3 select, .row-3 textarea { max-width: none; }

input:hover:not(:focus), select:hover:not(:focus), textarea:hover:not(:focus) {
    border-color: var(--subtle);
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-ring);
}

input::placeholder, textarea::placeholder { color: var(--subtle); opacity: 1; }

textarea { min-height: 96px; resize: vertical; font-family: inherit; line-height: 1.55; }

input[disabled], select[disabled], textarea[disabled] { opacity: .5; cursor: not-allowed; }

select {
    -webkit-appearance: none;
    appearance: none;
    padding-right: 36px;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23a3a3a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 14px;
    cursor: pointer;
}
select:focus {
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
select::-ms-expand { display: none; }
select option { background: var(--panel); color: var(--text); }

/* .row base moved to shared.css */
.row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 14px; }
.row-3 label:first-child { margin-top: 0; }

/* Consistent vertical rhythm between any block-level form group inside a card.
   Single labels already get margin-top via the `label` rule; this matches it
   for grids, toggles and helpers so they don't sit flush against the input above. */
.card .row,
.card .row-3,
.card > .toggle,
.card > .form-hint,
.card > .dropzone,
.card > p { margin-top: 14px; }
.card > h2 + .row,
.card > h2 + .row-3,
.card > h2 + .toggle,
.card > h2 + .form-hint,
.card > h2 + p { margin-top: 0; }

.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: var(--s-4);
    padding: 12px 0;
}
.pagination-info { font-variant-numeric: tabular-nums; }
.pagination-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pagination-select {
    -webkit-appearance: none;
    appearance: none;
    padding: 6px 28px 6px 10px;
    font-size: 13px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--panel, #fff);
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 8px center;
    background-size: 12px;
    color: var(--text);
    cursor: pointer;
    width: auto !important;
    max-width: 140px;
    flex: 0 0 auto;
}
.pagination-pages { display: flex; align-items: center; gap: 2px; }
.pagination-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    padding: 0 8px;
    border-radius: var(--radius);
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    text-decoration: none;
    transition: background .1s;
}
.pagination-btn:hover:not(.is-disabled):not(.is-current) { background: var(--surface-2); }
.pagination-btn.is-current { background: var(--accent); color: var(--accent-ink, #fff); font-weight: 600; }
.pagination-btn.is-disabled { opacity: .3; cursor: not-allowed; }
.pagination-ellipsis { padding: 0 4px; color: var(--muted); font-size: 13px; }

/* Tint control — preview + styled range slider */
.tint-control { margin-top: 8px; }
.tint-preview {
    position: relative;
    height: 120px;
    border-radius: var(--radius);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 14px;
}
.tint-preview-overlay {
    position: absolute;
    inset: 0;
    background: #000;
    pointer-events: none;
}
.tint-preview-text {
    position: relative;
    z-index: 1;
    color: #fff;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-shadow: 0 1px 4px rgba(0,0,0,.3);
}
.tint-slider {
    display: flex;
    align-items: center;
    gap: 14px;
}
.tint-value {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    min-width: 36px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Styled range input */
.range-wrap { position: relative; padding-bottom: 22px; }
.range-styled {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 6px;
    border-radius: 3px;
    background: var(--line);
    outline: none;
    border: 0;
    padding: 0;
    margin: 10px 0 0;
}
.range-styled::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--text);
    cursor: pointer;
    border: 3px solid var(--panel, #fff);
    box-shadow: 0 2px 6px rgba(0,0,0,.25);
    margin-top: -8px;
}
.range-styled::-webkit-slider-thumb:hover { box-shadow: 0 2px 8px rgba(0,0,0,.35); }
.range-styled::-moz-range-thumb {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--text);
    cursor: pointer;
    border: 3px solid var(--panel, #fff);
    box-shadow: 0 2px 6px rgba(0,0,0,.25);
}
.range-styled::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; }
.range-styled::-moz-range-track { height: 6px; border-radius: 3px; background: var(--line); }
.range-markers {
    display: flex;
    justify-content: space-between;
    margin-top: 6px;
    padding: 0 2px;
}
.range-markers span {
    font-size: 11px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}
.range-markers span.is-active { color: var(--text); font-weight: 600; }

.roles-perms { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--s-5); margin-top: var(--s-3); }
/* Group heading sits a clear gap below the card's subtitle/hint above
   so "Backoffice" / "Support" don't hug the line directly above them.
   The gap applies to EVERY group — including the first — so Backoffice
   and Support are visually balanced inside each role card. */
.roles-perm-group h3 { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin: 20px 0 8px; }
.roles-perm-group .toggle { margin: 4px 0; }

.email-preview { font-size: 14px; line-height: 1.6; color: var(--text); }
.email-preview table { border: 0 !important; background: transparent !important; box-shadow: none !important; }
.email-preview td { background: transparent !important; border: 0 !important; border-radius: 0 !important; }
.email-preview img { max-width: 100%; }

.ical-copy-field {
    position: relative;
    display: flex;
}
.ical-copy-field input {
    flex: 1;
    padding-right: 44px;
}
.ical-copy-btn {
    position: absolute;
    right: 1px; top: 1px; bottom: 1px;
    width: 38px;
    border: 0;
    background: var(--surface-2);
    border-radius: 0 var(--radius) var(--radius) 0;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text);
    transition: background .1s;
}
.ical-copy-btn:hover { background: var(--line); }

.feed-colors { display: flex; gap: 8px; flex-wrap: wrap; margin: 4px 0; }
.feed-color-dot {
    width: 28px; height: 28px;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    transition: border-color .1s, transform .1s;
    padding: 0;
}
.feed-color-dot:hover { transform: scale(1.15); }
.feed-color-dot.is-selected { border-color: var(--text); transform: scale(1.15); }

/* Daily-digest fields — give the time hint and the send-now row more
   breathing room than the default tight form rhythm. */
.digest-time-hint { margin-top: 10px; margin-bottom: 4px; }
.digest-send-row  { margin-top: 18px; margin-bottom: 8px; }

/* Generic input with a leading icon (social URLs, etc.). Icon sits
   inside the field so the layout lines up with a normal <input>. */
.input-prefixed { position: relative; }
.input-prefixed .input-prefix {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--muted);
    display: inline-flex;
    pointer-events: none;
}
.input-prefixed > input { padding-left: 36px; }

.account-photo-row { display: flex; align-items: center; gap: 20px; }
.account-photo {
    width: 80px; height: 80px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--surface-2);
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.account-photo img { width: 100%; height: 100%; object-fit: cover; }
.account-photo-initials { font-size: 28px; font-weight: 700; color: var(--muted); }
.account-photo-actions { display: flex; flex-direction: column; gap: 6px; }
.account-photo-actions .form-hint { margin: 0; }

.audit-details { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


th.sortable a {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
}
th.sortable a:hover { color: var(--text); }
.sort-arrow { font-size: 12px; line-height: 1; }
.sort-arrow-idle { opacity: .3; }
th.is-sorted .sort-arrow { opacity: 1; color: var(--text); }

.form-actions {
    display: flex; gap: 10px; align-items: center;
    margin-top: 24px; flex-wrap: wrap;
    justify-content: space-between;
}
.form-actions.compact { border: 0; margin-top: 10px; padding-top: 0; }
.form-actions a.secondary {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 10px 18px;
    background: var(--bg-raised);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    transition: background .1s, border-color .1s;
}
.form-actions a.secondary:hover {
    background: var(--panel-2);
    border-color: var(--subtle);
}
/* .form-hint moved to shared.css */

/* .field-error / .is-invalid moved to shared.css so the public site's
   forms (e.g. the contact form) pick them up without duplication. */

/* ============================================================
   Amenity picker — grid of toggle switches grouped by category
   ============================================================ */
.amenity-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 6px 20px;
}
.amenity-toggle {
    margin: 0;
    padding: 6px 4px;
    border-radius: 6px;
    transition: background .08s;
    width: 100%;
}
.amenity-toggle:hover { background: var(--accent-soft); }
.amenity-toggle .toggle-text { font-size: 13px; }

/* ============================================================
   Dropzone — photo upload area
   ============================================================ */
.dropzone {
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    border: 1.5px dashed var(--line);
    border-radius: var(--radius-lg);
    padding: 56px 24px;
    text-align: center;
    cursor: pointer;
    transition: border-color .15s, background .15s;
    background: transparent;
    min-height: 180px;
}
.dropzone:hover {
    border-color: var(--subtle);
    background: var(--accent-soft);
}
.dropzone.is-dragover {
    border-color: var(--accent);
    border-style: solid;
    background: var(--accent-soft);
}
.dropzone input[type=file] {
    position: absolute; inset: 0;
    opacity: 0;
    cursor: pointer;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
}
.dropzone-status {
    margin-top: 10px;
    font-size: 13px;
    color: var(--muted);
    min-height: 18px;
}
.dropzone-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    pointer-events: none;
}
.dropzone-icon {
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--text);
    margin-bottom: 4px;
}
.dropzone-title {
    font-size: 14px;
    font-weight: 500;
    color: var(--text);
}
.dropzone-sub {
    font-size: 12.5px;
    color: var(--muted);
    line-height: 1.5;
}
.dropzone-link {
    color: var(--text);
    text-decoration: underline;
    text-decoration-color: var(--muted);
    text-underline-offset: 3px;
}

/* ============================================================
   Photo grid (property photos)
   ============================================================ */
.photo-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 16px;
}
.photo-tile { display: flex; flex-direction: column; gap: 8px; }
.photo-thumb {
    position: relative;
    display: block;
    aspect-ratio: 4 / 3;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--panel-2);
    border: 1px solid var(--line);
    text-decoration: none;
}
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-tile.is-primary .photo-thumb { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.photo-badge {
    position: absolute;
    top: 6px; left: 6px;
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 10.5px;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 999px;
    letter-spacing: .04em;
}
.photo-alt {
    width: 100%;
    max-width: none;
    padding: 6px 9px;
    font-size: 12px;
}
.photo-actions { display: flex; gap: 6px; align-items: center; }
.photo-actions form { margin: 0; flex-shrink: 0; }
.photo-actions form:first-child { flex: 1; }
.photo-actions form:first-child button { width: 100%; }

/* Toggle switch — base rules moved to shared.css. Admin-only additions below. */
.toggle-hint { display: block; color: var(--muted); font-size: 12.5px; margin: -4px 0 14px 42px; line-height: 1.5; }

/* Container for a stack of toggles used as a multi-select group, e.g.
   the bookings filter modal's Status + Payment fields. Tightens the
   per-toggle margins so the group reads as a single field. */
.toggle-group {
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 4px 0 8px;
}
.toggle-group .toggle { margin: 4px 0; }

.checkbox { display: flex; align-items: center; gap: 8px; margin: 10px 0; font-size: 14px; cursor: pointer; }
/* Let the global custom-styled checkbox rule keep its 20x20 box — this
   override used to set width:auto back when checkboxes were native,
   which collapsed the new styled boxes to zero width and hid them. */
.checkbox input { margin: 0; }

/* Buttons — base rules moved to shared.css. Admin-only additions below. */

.link-button {
    background: none; border: 0; color: var(--text); padding: 0; cursor: pointer; font: inherit;
    text-decoration: underline; text-decoration-color: var(--subtle); text-underline-offset: 3px;
    box-shadow: none;
}
.link-button:hover { text-decoration-color: var(--text); background: none; filter: none; }

/* ============================================================
   Tables — single global pattern used everywhere
   ============================================================ */
.table-wrap { overflow-x: auto; }
table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 13px;
    color: var(--text);
}
thead th {
    text-align: left;
    padding: 10px 16px;
    color: var(--muted);
    font-weight: 500;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .06em;
    background: var(--panel-2);
    border-bottom: 1px solid var(--line);
    border-top: 1px solid var(--line);
    white-space: nowrap;
}
thead th:first-child { border-left: 1px solid var(--line); border-top-left-radius: var(--radius-lg); }
thead th:last-child  { border-right: 1px solid var(--line); border-top-right-radius: var(--radius-lg); }
tbody td {
    text-align: left;
    padding: 12px 16px;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
    color: var(--text);
    background: var(--panel);
}
tbody td:first-child { border-left: 1px solid var(--line); }
tbody td:last-child  { border-right: 1px solid var(--line); }
tbody tr:nth-child(even) td { background: var(--panel-2); }
tbody tr { transition: background .08s; }
tbody tr:hover td { background: var(--accent-soft); }

/* Unseen / needs-attention rows on bookings + enquiries lists. Two
   amber-tinted shades alternate within the unseen rows themselves, so
   the row stays readable as part of the table while clearly standing
   apart from the seen ones. Same `is-unseen` class drives both views. */
tbody tr.is-unseen td { background: color-mix(in srgb, #f59e0b 9%, var(--bg-raised)); }
tbody tr.is-unseen:nth-child(even) td { background: color-mix(in srgb, #f59e0b 14%, var(--bg-raised)); }
tbody tr.is-unseen:hover td { background: color-mix(in srgb, #f59e0b 20%, var(--bg-raised)); }
tbody tr:last-child td { border-bottom: 1px solid var(--line); }
tbody tr:last-child td:first-child { border-bottom-left-radius: var(--radius-lg); }
tbody tr:last-child td:last-child  { border-bottom-right-radius: var(--radius-lg); }

/* When a table sits inside a card alone, drop card chrome and let table draw its own */
.card.card--table { padding: 0; border: 0; box-shadow: none; background: transparent; }

/* Wrapper div placed inside an action <td>. The td stays a normal table cell
   (so vertical alignment works correctly); this div lays out the buttons. */
.table-actions {
    display: inline-flex;
    gap: 6px;
    align-items: center;
    flex-wrap: nowrap;
    vertical-align: middle;
}
.table-actions form { margin: 0; display: inline-flex; }
td.cell-actions { text-align: right; white-space: nowrap; }
.cell-strong { font-weight: 500; color: var(--text); }
.cell-sub { color: var(--muted); font-size: 12px; margin-top: 2px; }

/* Responsive: tables scroll horizontally on small screens rather than crushing.
   Place the table inside .table-wrap (or .card.card--table) and it'll behave. */
.card--table, .table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
.card--table table, .table-wrap table { min-width: 600px; }

/* Hide low-priority cells on small screens. Add .col-hide-sm to th/td you can drop. */
@media (max-width: 720px) {
    .col-hide-sm { display: none; }
}

/* ============================================================
   Flash + badges
   ============================================================ */
/* Toast container — fixed top-right stack. Individual toasts slide in
   from the right and auto-dismiss after a few seconds. */
.toast-container {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 400px;
    width: calc(100vw - 32px);
    pointer-events: none;
}
.toast {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 14px 16px;
    border-radius: var(--radius);
    border: 1px solid;
    font-size: 13.5px;
    line-height: 1.5;
    box-shadow: 0 8px 24px rgba(0,0,0,.12);
    pointer-events: auto;
    transform: translateX(calc(100% + 20px));
    opacity: 0;
    transition: transform .28s cubic-bezier(.2, .7, .2, 1), opacity .22s ease;
}
.toast.is-visible {
    transform: translateX(0);
    opacity: 1;
}
.toast.is-leaving {
    transform: translateX(calc(100% + 20px));
    opacity: 0;
}
.toast-close {
    margin-left: auto;
    background: none;
    border: 0;
    color: inherit;
    cursor: pointer;
    opacity: 0.6;
    padding: 0;
    font-size: 16px;
    line-height: 1;
}
.toast-close:hover { opacity: 1; }
.toast.success {
    background: var(--panel);
    color: var(--ok);
    border-color: rgba(134,239,172,.28);
}
.toast.error {
    background: var(--panel);
    color: var(--err);
    border-color: rgba(252,165,165,.28);
}
.toast.info {
    background: var(--panel);
    color: var(--text);
    border-color: var(--line);
}
.toast.warn {
    background: var(--panel);
    color: var(--warn);
    border-color: rgba(252,211,77,.28);
}

/* Legacy flash banner — kept as fallback if toast JS hasn't loaded. */
.flash {
    padding: 12px 16px;
    border-radius: var(--radius);
    margin-bottom: 20px;
    display: none; /* hidden by default — toast takes over */
    align-items: flex-start;
    gap: 10px;
    font-size: 13.5px;
    border: 1px solid;
    line-height: 1.5;
}

/* .badge moved to shared.css */

/* .icon moved to shared.css */

/* ============================================================
   Auth shell
   ============================================================ */
.auth-shell {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: var(--bg);
}
.auth-card {
    width: 100%;
    max-width: 420px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 40px 36px;
    box-shadow: var(--shadow);
}
.auth-subtitle { color: var(--muted); margin: 0 0 14px; font-size: 14px; line-height: 1.55; }

/* The first form label in each slider step sits flush against the
   subtitle above so the prompt + label read as a single grouped
   block. Default `label:first-child` doesn't fire here because
   csrf_field() emits a hidden <input> before the label. */
.slider-step form label:first-of-type {
    margin-top: 0;
}
.auth-foot     { margin-top: 20px; text-align: center; font-size: 14px; }
.auth-subfoot {
    margin-top: 24px;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 28px;
    font-size: 13px;
}
.auth-sublink {
    background: transparent;
    border: 0;
    padding: 0;
    color: var(--muted);
    font: inherit;
    font-weight: 400;
    cursor: pointer;
    text-decoration: none;
    box-shadow: none;
}
.auth-sublink:hover, .auth-sublink:focus {
    background: transparent;
    color: var(--text);
    text-decoration: none;
    outline: none;
    box-shadow: none;
    filter: none;
}

/* Login code slider */
.slider { position: relative; overflow: hidden; }
.slider-track { display: flex; transition: transform .35s cubic-bezier(.4,0,.2,1); }
.slider-track.show-code { transform: translateX(-100%); }
.slider-step { flex: 0 0 100%; min-width: 0; box-sizing: border-box; }

/* One shared style for the 6-digit verification code inputs. Used
   identically by the standalone login screen and the verifyAction
   in-modal flow — it's the same global verification system, so it
   should look the same everywhere. Fixed-width compact boxes,
   centred as a group. */
.code-inputs {
    display: flex;
    gap: 6px;
    justify-content: center;
    margin-bottom: 14px;
}
.code-inputs input {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    text-align: center;
    font: 500 15px/1 var(--font-body);
    letter-spacing: 0;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* ============================================================
   Install wizard shell
   ============================================================ */
.install-shell { max-width: 720px; margin: 48px auto; padding: 24px; }

.check-list { display: flex; flex-direction: column; }
.check-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid var(--line);
    font-size: 14px;
}
.check-row:last-child { border-bottom: 0; }
.check-row .check-hint { color: var(--muted); font-size: 12.5px; margin-top: 4px; }
.check-ok   { color: var(--ok); display: inline-flex; align-items: center; gap: 4px; }
.check-fail { color: var(--err); display: inline-flex; align-items: center; gap: 4px; }

/* Wizard stepper timeline */
.stepper {
    list-style: none; padding: 0; margin: 0 0 32px;
    display: flex; align-items: flex-start; justify-content: space-between; gap: 0;
    counter-reset: step;
}
.stepper .step { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 10px; position: relative; counter-increment: step; }
.stepper .step::before {
    content: ""; position: absolute; top: 14px; left: 50%; right: -50%;
    height: 1px; background: var(--line); z-index: 0;
}
.stepper .step:last-child::before { display: none; }
.stepper .step.done::before { background: var(--accent); }

.step-dot {
    position: relative; z-index: 1;
    width: 28px; height: 28px; border-radius: 50%;
    background: var(--bg); border: 1px solid var(--line);
    display: flex; align-items: center; justify-content: center;
    font: 12px/1 var(--font-body); font-weight: 500; color: var(--muted);
    box-shadow: var(--shadow-sm);
}
.step-dot::before { content: counter(step); }

.step.current .step-dot { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-ring); }
.step.done    .step-dot { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.step.done    .step-dot::before { content: ""; width: 12px; height: 12px; background: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5 9-11'/%3E%3C/svg%3E") center/contain no-repeat; }

.step-label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; text-align: center; font-weight: 500; }
.step.current .step-label { color: var(--text); }

/* ============================================================
   Admin shell — sidebar with collapsible groups (Cloudflare-style)
   ============================================================ */
.admin-shell { display: grid; grid-template-columns: 240px 1fr; min-height: 100vh; }
.admin-shell--collapsed { grid-template-columns: 56px 1fr; }
.admin-hamburger { display: none; border: 0; background: none; padding: 4px; cursor: pointer; color: var(--text); }
.admin-sidebar-scrim { display: none; }

.admin-sidebar {
    background: var(--panel);
    border-right: 1px solid var(--line);
    padding: 0 0 12px;
    position: sticky; top: 0; height: 100vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    z-index: 50;
}
.admin-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 15px;
    height: 53px;
    padding: 0 16px;
    border-bottom: 1px solid var(--line);
    color: var(--text);
    box-sizing: border-box;
    flex-shrink: 0;
}
.brand-mark { display: inline-flex; align-items: center; flex-shrink: 0; }
.brand-text { letter-spacing: -0.01em; }

.admin-nav {
    flex: 1;
    overflow-y: auto;
    padding: 10px 0;
}

/* Top-level item (no children) */
.nav-item, .nav-group-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    width: calc(100% - 16px);
    margin: 1px 8px;
    padding: 7px 12px;
    color: var(--text-2);
    text-decoration: none;
    font-size: 13px;
    font-weight: 400;
    border: 0;
    background: transparent;
    border-radius: 6px;
    box-shadow: none;
    text-align: left;
    cursor: pointer;
    font-family: inherit;
    line-height: 1.4;
    transition: background .08s, color .08s;
}
.nav-item:hover, .nav-group-toggle:hover {
    background: var(--accent-soft);
    color: var(--text);
    text-decoration: none;
    filter: none;
}
.nav-item.active {
    background: var(--accent-soft);
    color: var(--text);
    font-weight: 500;
}
.nav-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    color: var(--muted);
}
.nav-item:hover .nav-icon, .nav-item.active .nav-icon,
.nav-group-toggle:hover .nav-icon, .nav-group.open .nav-group-toggle .nav-icon { color: var(--muted); }
.nav-label { flex: 1; }

/* Collapsible group */
.nav-group { position: relative; }
.nav-chevron {
    margin-left: auto;
    display: inline-flex;
    color: var(--subtle);
    transition: transform .22s ease;
}
.nav-group.open > .nav-group-toggle .nav-chevron { transform: rotate(90deg); color: var(--muted); }

/* Height is managed by JS (initNavGroups in admin.js): it measures the
   actual content height and animates between 0 and that, then sets to auto
   so content can grow without re-measuring. CSS provides only the easing. */
.nav-group-items {
    height: 0;
    overflow: hidden;
    transition: height .22s cubic-bezier(.2, .8, .2, 1);
    padding: 0;
}
.nav-group-items > .nav-subitem:first-child { margin-top: 4px; }
.nav-group-items > .nav-subitem:last-child  { margin-bottom: 4px; }

.nav-subitem {
    display: flex;
    align-items: center;
    margin: 1px 8px;
    padding: 6px 12px 6px 40px;
    color: var(--text-2);
    text-decoration: none;
    font-size: 12.5px;
    border-radius: 6px;
    transition: background .08s, color .08s;
}
.nav-subitem:hover { background: var(--accent-soft); color: var(--text); text-decoration: none; }
.nav-subitem.active { background: var(--accent-soft); color: var(--text); font-weight: 500; }

/* ---------- Dashboard / analytics ---------- */
.kpi-grid {
    display: grid;
    /* Fixed column count so 6 tiles don't fall into a 5+1 stranded row.
       Modifier `.kpi-grid--wide` bumps to 4 for pages with 8 tiles. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 14px;
    margin: 0 0 20px;
}
.kpi-grid--wide { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 900px) {
    .kpi-grid,
    .kpi-grid--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
    .kpi-grid,
    .kpi-grid--wide { grid-template-columns: 1fr; }
}
.kpi {
    padding: 16px 18px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}
.kpi-label { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px; }
.kpi-value { font-size: 26px; font-weight: 700; line-height: 1.1; }
.kpi-hint  { font-size: 12px; margin-top: 4px; }

.dashboard-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
    margin: 20px 0;
}
.dashboard-row .card { margin: 0; }
.card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 10px;
}
.card-head h2 { margin: 0; font-size: 15px; }

/* Ordered top-list used on "Top properties". */
.top-list { margin: 0; padding: 0; list-style: none; counter-reset: n; }
.top-list li {
    counter-increment: n;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 8px 0;
    border-bottom: 1px solid var(--line);
    font-size: 14px;
}
.top-list li:last-child { border-bottom: 0; }
.top-list li::before {
    content: counter(n);
    display: inline-flex;
    width: 22px; height: 22px;
    align-items: center; justify-content: center;
    background: var(--bg-raised);
    color: var(--muted);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    margin-right: 10px;
}
.top-list a { color: inherit; text-decoration: none; flex: 1; }
.top-list a:hover { text-decoration: underline; }
.top-amount { font-variant-numeric: tabular-nums; font-weight: 600; }

/* Upcoming check-ins / check-outs. */
.stack-list { margin: 0; padding: 0; list-style: none; }
.stack-list li {
    display: grid;
    grid-template-columns: 90px 1fr;
    grid-template-rows: auto auto;
    column-gap: 12px;
    align-items: baseline;
    padding: 8px 0;
    border-bottom: 1px solid var(--line);
}
.stack-list li:last-child { border-bottom: 0; }
.stack-date { grid-row: 1 / span 2; font-variant-numeric: tabular-nums; color: var(--muted); font-size: 13px; }
.stack-main { font-size: 14px; font-weight: 500; }
.stack-sub  { font-size: 12px; }

/* SVG chart — colour driven by CSS so theme swap hits charts too. */
.chart { display: block; width: 100%; height: auto; }
.chart-bar  { fill: var(--accent, #2563eb); transition: fill 120ms ease; }
.chart-bar:hover { fill: var(--text); }
.chart-grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 4; }
.chart-xlabel { fill: var(--muted); font-size: 11px; font-family: inherit; }
.chart-ylabel { fill: var(--muted); font-size: 11px; font-family: inherit; }

/* ============================================================
   Dashboard v2 — sky-blue layout (matches reference design)
   ============================================================ */
.dash-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-top: 4px;
}
@media (max-width: 1080px) {
    .dash-grid { grid-template-columns: 1fr; }
}
.dash-col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }

/* ---- Hero revenue card ---- */
.hero-card {
    position: relative;
    background:
        radial-gradient(120% 80% at 90% 0%, rgba(2, 132, 199, .08) 0%, transparent 55%),
        linear-gradient(180deg, #eaf4fc 0%, #f6fbff 100%);
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    padding: 22px 24px 20px;
    overflow: hidden;
}
html[data-theme="dark"] .hero-card {
    background:
        radial-gradient(120% 80% at 90% 0%, rgba(56, 189, 248, .14) 0%, transparent 55%),
        linear-gradient(180deg, #1e293b 0%, #182238 100%);
}
.hero-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}
.hero-card-label {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-2);
    margin: 0;
}
.hero-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: rgba(255, 255, 255, .65);
    border: 1px solid rgba(2, 132, 199, .15);
    color: var(--text-2);
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
}
html[data-theme="dark"] .hero-pill {
    background: rgba(15, 23, 42, .55);
    border-color: rgba(56, 189, 248, .22);
    color: var(--text-2);
}
.hero-pill .icon { color: var(--accent); }
.hero-value-row {
    display: flex;
    align-items: baseline;
    gap: 12px;
    margin: 6px 0 4px;
}
.hero-value {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 38px;
    letter-spacing: -0.02em;
    line-height: 1.05;
    color: var(--text);
    margin: 0;
}
.hero-delta {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 12px;
    font-weight: 600;
    color: var(--ok);
    background: rgba(2, 132, 199, .10);
    padding: 3px 8px;
    border-radius: 999px;
}
.hero-delta.is-down { color: #b91c1c; background: rgba(185, 28, 28, .10); }
.hero-chart-wrap { margin: 6px -8px 14px; }
.hero-chart-wrap .chart-line-wrap { background: transparent; padding: 0; border: 0; }

/* ---- Hero inline stat tiles (4-up) ---- */
.hero-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    margin-top: 4px;
}
@media (max-width: 720px) {
    .hero-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.hero-stat {
    background: rgba(255, 255, 255, .72);
    border: 1px solid rgba(2, 132, 199, .10);
    border-radius: var(--radius);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}
html[data-theme="dark"] .hero-stat {
    background: rgba(15, 23, 42, .55);
    border-color: rgba(56, 189, 248, .14);
}
.hero-stat-head {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--text-2);
    font-size: 11.5px;
    line-height: 1.25;
    min-height: 28px;
}
.hero-stat-tick {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border-radius: 6px;
    background: var(--accent);
    color: var(--accent-ink);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.hero-stat-tick .icon { width: 12px; height: 12px; }
.hero-stat-value {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 22px;
    letter-spacing: -0.02em;
    color: var(--text);
}

/* ---- Generic dashboard card (white) ---- */
.d-card {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    padding: 20px 22px;
    box-shadow: var(--shadow-sm);
}
.d-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}
.d-card-title h2 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
}
.d-card-title p {
    margin: 2px 0 0;
    color: var(--muted);
    font-size: 12px;
}
.d-card-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ---- Heatmap (Top properties / Top clients) ----
   Each row has 5 grid items: 1 label + 4 cells. The grid template MUST
   declare all 5 tracks so successive rows don't shift one column right.
*/
.heatmap {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) repeat(4, minmax(0, 1fr));
    column-gap: 6px;
    row-gap: 6px;
    align-items: stretch;
}
.heatmap-row { display: contents; }
.heatmap-label {
    align-self: center;
    font-size: 12.5px;
    color: var(--text-2);
    padding-right: 6px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.heatmap-cell {
    position: relative;
    border-radius: 8px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 11.5px;
    font-variant-numeric: tabular-nums;
    transition: transform .12s ease;
}
.heatmap-cell:hover { transform: translateY(-1px); }
.heatmap-cell--0 { background: #eff6fb; color: transparent; }
.heatmap-cell--1 { background: #cfe6f8; color: #0c3a5b; }
.heatmap-cell--2 { background: #9ccaf0; color: #082b48; }
.heatmap-cell--3 { background: #4ea4dd; color: #ffffff; }
.heatmap-cell--4 { background: #1e7bbf; color: #ffffff; }
.heatmap-cell--5 { background: #0a4a78; color: #ffffff; }
html[data-theme="dark"] .heatmap-cell--0 { background: rgba(56, 189, 248, .06); }
html[data-theme="dark"] .heatmap-cell--1 { background: rgba(56, 189, 248, .18); color: #e6f1fa; }
html[data-theme="dark"] .heatmap-cell--2 { background: rgba(56, 189, 248, .32); color: #0f172a; }
html[data-theme="dark"] .heatmap-cell--3 { background: rgba(56, 189, 248, .55); color: #0f172a; }
html[data-theme="dark"] .heatmap-cell--4 { background: rgba(56, 189, 248, .75); color: #0f172a; }
html[data-theme="dark"] .heatmap-cell--5 { background: #38bdf8; color: #0f172a; }

/* ---- Progress / next-up sidebar list ---- */
.progress-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.progress-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--line-2);
}
.progress-item:last-child { padding-bottom: 0; border-bottom: 0; }
.progress-item-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.progress-item-name { font-weight: 600; font-size: 13.5px; color: var(--text); }
.progress-item-sub { color: var(--muted); font-size: 12px; }
.progress-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 6px;
    font-size: 12px;
    color: var(--text-2);
}
.progress-meta .avatar {
    width: 22px; height: 22px;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
}
.priority {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    font-size: 11px;
    font-weight: 600;
    border-radius: 999px;
    text-transform: capitalize;
    letter-spacing: .01em;
}
.priority--high { background: #ffe1d6; color: #b1450b; }
.priority--med  { background: #fff3cf; color: #92400e; }
.priority--low  { background: #dceefb; color: #0c4a78; }
html[data-theme="dark"] .priority--high { background: rgba(255,120,80,.15); color: #fcb89a; }
html[data-theme="dark"] .priority--med  { background: rgba(253, 230, 138, .12); color: #fde68a; }
html[data-theme="dark"] .priority--low  { background: rgba(56,189,248,.15); color: #7dd3fc; }

/* ---- Dashboard CTAs (dark sky-blue pill button) ---- */
.btn-cta,
.btn.btn-cta {
    background: var(--accent-strong);
    color: #ffffff;
    border: 1px solid var(--accent-strong);
    border-radius: 10px;
    padding: 9px 18px;
    height: auto;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    transition: filter .12s, transform .12s;
}
.btn-cta:hover,
.btn.btn-cta:hover { filter: brightness(1.12); }
.btn-cta:active { transform: translateY(1px); }
html[data-theme="dark"] .btn-cta,
html[data-theme="dark"] .btn.btn-cta {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-ink);
}
.btn-cta--block,
.btn.btn-cta--block {
    width: 100%;
    justify-content: center;
    padding: 12px;
}

/* ---- Compact data table inside dashboard cards ---- */
.d-card table { width: 100%; border-collapse: collapse; }
.d-card thead th {
    text-transform: uppercase;
    font-size: 10.5px;
    letter-spacing: .08em;
    color: var(--muted);
    font-weight: 600;
    text-align: left;
    padding: 14px 14px 10px;
    border-bottom: 1px solid var(--line);
}
.d-card thead th.text-right { text-align: right; }
.d-card tbody td {
    padding: 12px 14px;
    border-bottom: 1px solid var(--line-2);
    font-size: 13px;
    vertical-align: middle;
}
.d-card tbody tr:last-child td { border-bottom: 0; }
.d-card tbody td.text-right { text-align: right; }

/* Empty state inside a dashboard card */
.d-empty {
    padding: 18px 4px;
    color: var(--muted);
    font-size: 13px;
    text-align: center;
}

/* Input with a leading currency / unit label baked into the field
   chrome. Used by the extras editor (global catalog + per-property
   tab). `.input-prefix-text` sits in the rounded left side, the
   number input fills the rest. */
.input-prefix {
    display: flex;             /* flex (not inline-flex) so the row
                                  doesn't overflow its grid column with
                                  longer currency symbols like € or NZ$ */
    align-items: stretch;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--bg);
    max-width: 100%;           /* play nicely inside a grid column */
}
.input-prefix-text {
    /* `flex` (not inline-flex) so the element is a proper block-level
       flex container — inline-flex can drift vertically in Safari when
       the parent stretches the cross-axis, which pushed the glyph to
       the top of the cell. */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 8px;
    min-width: 28px;           /* consistent chrome regardless of symbol */
    background: var(--bg-raised);
    color: var(--muted);
    /* Match the input's font-size so both glyphs sit on the same
       typographic metric — stops the € from appearing to float high
       against a larger 0.00. line-height: 1 kills any half-leading
       added by the default line-height. */
    font-size: 14px;
    line-height: 1;
    border-right: 1px solid var(--line);
    flex-shrink: 0;
}
.input-prefix input {
    border: 0;
    background: transparent;
    padding: 8px 10px;
    min-width: 0;
    flex: 1 1 auto;            /* fill remaining width, shrink if needed */
    width: auto;
    font-size: 14px;
    color: var(--text);
}
.input-prefix input:focus { outline: none; }
/* Hide the browser-default +/− spin buttons on number inputs inside
   the extras editor. They look clunky next to the currency prefix
   and the admin can just type. */
.input-prefix input[type="number"],
.extras-row input[type="number"] {
    -moz-appearance: textfield;
}
.input-prefix input[type="number"]::-webkit-outer-spin-button,
.input-prefix input[type="number"]::-webkit-inner-spin-button,
.extras-row input[type="number"]::-webkit-outer-spin-button,
.extras-row input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Extras editor on property edit page — each row is a grid of four
   clusters (main info, price, qty, flags) so the form reads across
   like a table without being one. Collapses to a single column on
   narrow screens. */
.extras-editor-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    margin-bottom: 14px;
}
.extras-editor-rows { display: flex; flex-direction: column; gap: 12px; }
.extras-row {
    display: grid;
    grid-template-columns: 2fr 1.3fr 1fr 1fr;
    gap: 14px;
    padding: 14px;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}
.extras-row label {
    display: block;
    font-size: 11px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 0 0 4px;
    font-weight: 600;
}
.extras-row label.toggle {
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
    color: var(--text);
    display: flex;
    margin: 0 0 6px;
}
.extras-row input[type="text"],
.extras-row input[type="number"],
.extras-row select {
    width: 100%;
    margin: 0 0 10px;
}
/* The currency-prefixed price input is wrapped in .input-prefix —
   the wrapper itself carries the bottom margin so the chrome stays
   the same height as the bare inputs in the qty column. Without
   these overrides the inner input's margin would stretch the
   flex-stretch wrapper and the price field shows up visibly taller. */
.extras-row .input-prefix { margin: 0 0 10px; }
.extras-row .input-prefix input[type="number"] { margin: 0; }
.extras-row-flags { display: flex; flex-direction: column; justify-content: flex-start; }
.extras-row-flags .btn-icon { align-self: flex-end; margin-top: auto; }
@media (max-width: 860px) {
    .extras-row { grid-template-columns: 1fr; }
}

/* System-information modal — name + version up top, then a two-column
   grid of feature flags. Green dot = on, red dot = off. Kept compact
   so the modal fits without a scrollbar on a typical laptop. */
.sysinfo-header {
    margin-bottom: 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--line);
}
.sysinfo-top { display: flex; align-items: baseline; gap: 10px; }
.sysinfo-name { font-size: 15px; font-weight: 600; color: var(--text); }
.sysinfo-version { font-size: 12px; }
.sysinfo-credit { margin-top: 4px; font-size: 11.5px; }
.sysinfo-footer {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--line);
    display: flex;
    justify-content: flex-end;
}
.sysinfo-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px 20px;
}
@media (max-width: 480px) {
    .sysinfo-grid { grid-template-columns: 1fr; }
}
.sysinfo-row {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 13px;
    color: var(--text);
}
.sysinfo-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.6) inset;
}
.sysinfo-dot.is-on  { background: #22c55e; }
.sysinfo-dot.is-off { background: #ef4444; }

/* Updates page — current vs latest, big numbers, arrow between. */
.update-status {
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 6px 0 12px;
}
.update-status-block { flex: 0 0 auto; }
.update-status-arrow { color: var(--muted); opacity: 0.6; }
.update-status-value {
    font-size: 28px;
    font-weight: 600;
    line-height: 1.1;
    color: var(--text);
}
.update-status-value.is-newer  { color: #1d4ed8; }
.update-status-value.is-current { color: #059669; }
.update-actions {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
}
.update-actions ol { padding-left: 18px; margin: 6px 0 14px; line-height: 1.6; }

/* Update-available banner — sits above the admin page header on
   every route, dismissible per-tab via sessionStorage. Renders only
   when the cached manifest's `latest` beats APP_VERSION AND the user
   has the update permission. */
.update-banner {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    margin-bottom: 16px;
    background: #eef4ff;
    border: 1px solid #c7d9f8;
    border-radius: var(--radius);
    color: #1e3a8a;
    font-size: 13px;
    transition: opacity 200ms ease, transform 200ms ease;
}
.update-banner.is-leaving { opacity: 0; transform: translateY(-6px); }
.update-banner-icon { display: inline-flex; }
.update-banner-icon svg { stroke: currentColor; }
.update-banner-text { flex: 1 1 auto; }
.update-banner-text a { color: inherit; text-decoration: underline; margin-left: 6px; }
.update-banner-cta {
    display: inline-flex;
    align-items: center;
    padding: 6px 12px;
    background: #1d4ed8;
    color: #fff;
    border-radius: 999px;
    font-weight: 500;
    text-decoration: none;
    font-size: 12px;
}
.update-banner-cta:hover { background: #1e40af; }
.update-banner-close {
    background: transparent;
    border: 0;
    color: inherit;
    opacity: 0.7;
    cursor: pointer;
    padding: 4px;
}
.update-banner-close:hover { opacity: 1; }

/* Chart.js line-chart wrapper — needs a fixed height (set inline by
   admin.js from the data-chart-height attribute) because Chart.js
   sizes the canvas to the parent and the parent would otherwise
   collapse to zero. `position: relative` lets the canvas fill it. */
.chart-line-wrap {
    position: relative;
    width: 100%;
}
.chart-line-wrap canvas {
    display: block;
    width: 100% !important;
    height: 100% !important;
}

/* verifiedAction two-step slider — confirm panel + code panel laid
   side-by-side; the outer .verify-outer clips, the inner .verify-slider
   translates -50% when data-step="code" to slide the code panel in. */
.verify-outer { overflow: hidden; width: 100%; }
.verify-slider {
    display: flex;
    width: 200%;
    transition: transform 300ms cubic-bezier(.2, .8, .2, 1);
    will-change: transform;
}
.verify-slider[data-step="code"] { transform: translateX(-50%); }
.verify-slide {
    flex: 0 0 50%;
    box-sizing: border-box;
    padding: 0 2px;
    /* Column so the actions row can stretch itself to the bottom via
       margin-top: auto. Both slides share height (the taller one wins
       because they sit side-by-side), and this pins each slide's
       buttons to its own foot instead of leaving dead space below
       the confirm body. */
    display: flex;
    flex-direction: column;
}
.verify-body { flex: 1 1 auto; }
.verify-body p { margin: 0 0 8px; font-size: 13px; }
.verify-body p:last-child { margin-bottom: 12px; }
.verify-actions {
    display: flex;
    justify-content: flex-end;
    gap: 6px;
    margin-top: auto;
    padding-top: 12px;
}
.verify-actions button {
    padding: 6px 14px;
    border-radius: var(--radius);
    border: 1px solid transparent;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
}
.verify-actions button.secondary {
    background: transparent;
    border-color: var(--line);
    color: var(--text);
}
.verify-actions button.secondary:hover { background: var(--bg-raised); }
.verify-actions button.danger {
    background: #dc2626;
    color: #fff;
}
.verify-actions button.danger:hover { background: #b91c1c; }
.verify-actions button[disabled] { opacity: 0.6; cursor: wait; }

/* Modal-level compaction when verifiedAction has hijacked it: smaller
   shell, tighter padding and title so the OTP step doesn't dwarf the
   rest of the admin chrome. Scoped via .is-verify on the modal so it
   only affects this flow, not every other Modal.open caller. */
.modal.is-verify {
    max-width: 340px;
    padding: 16px 18px;
}
.modal.is-verify .modal-title {
    font-size: 14px;
    margin-bottom: 6px;
}
.modal.is-verify .modal-body {
    font-size: 13px;
    margin-bottom: 0;
}

/* Booking status pills (inline in dashboard tables). */
.pill-pending        { background: #d97706; color: #fff; }
.pill-confirmed      { background: #2563eb; color: #fff; }
.pill-paid           { background: #059669; color: #fff; }
.pill-declined       { background: #dc2626; color: #fff; }
.pill-cancelled      { background: #64748b; color: #fff; }
.pill-unpaid         { background: #94a3b8; color: #fff; }
.pill-deposit_paid   { background: #3b82f6; color: #fff; }
.pill-failed         { background: #ef4444; color: #fff; }
.pill-refunded       { background: #64748b; color: #fff; }
.pill-partial_refund { background: #d97706; color: #fff; }
.pill-approved       { background: #059669; color: #fff; }
.pill-rejected       { background: #dc2626; color: #fff; }
.pill-muted          { background: var(--bg-raised); color: var(--muted); }

/* ---------- Booking detail drawer (slides from right) ---------- */
.bk-dl { display: grid; grid-template-columns: 120px 1fr; gap: 8px 14px; font-size: 14px; margin: 0 0 20px; }
.bk-dl dt { color: var(--muted); }
.bk-dl dd { margin: 0; }
.bk-progress { margin-bottom: 20px; }
.bk-progress-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
}
.bk-progress-bar {
    height: 16px;
    background: var(--line);
    border-radius: 999px;
    overflow: hidden;
}
.bk-progress-fill {
    height: 100%;
    border-radius: 999px;
    transition: width .3s ease;
}
.bk-actions {
    display: flex;
    gap: 8px;
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}
.bk-pay-table { width: 100%; font-size: 13px; }
.bk-pay-table th { text-align: left; font-weight: 600; padding: 6px 8px; }
.bk-pay-table td { padding: 6px 8px; }

/* ---------- Guest email timeline ---------- */
.guest-timeline { display: flex; flex-direction: column; gap: 0; padding-left: 16px; border-left: 2px solid var(--line); }
.guest-timeline-item { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; position: relative; }
.guest-timeline-dot {
    position: absolute;
    left: -23px;
    top: 14px;
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--text);
    border: 2px solid var(--panel);
}
.guest-timeline-label { font-weight: 500; font-size: 14px; }

/* Small count bubble on nav items — unseen bookings, pending enquiries,
   pending reviews, draft rota slots. Solid amber + dark text gives the
   strongest contrast in both themes (white-on-amber fails WCAG AA). */
.nav-badge {
    margin-left: auto;
    min-width: 18px;
    height: 18px;
    padding: 0 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: #f59e0b;
    color: #1f1300;
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.nav-divider { height: 1px; background: var(--line); margin: 8px 16px; }

.nav-soon {
    pointer-events: none;
    opacity: .45;
}
.nav-soon::after {
    content: "soon";
    font-size: 9.5px;
    margin-left: auto;
    color: var(--subtle);
    text-transform: uppercase;
    letter-spacing: .1em;
    font-weight: 600;
}

/* Sidebar footer with collapse toggle */
.admin-sidebar-footer {
    border-top: 1px solid var(--line);
    padding: 6px 0;
    flex-shrink: 0;
}
.sidebar-collapse {
    display: flex;
    align-items: center;
    gap: 10px;
    width: calc(100% - 16px);
    margin: 4px 8px;
    padding: 6px 12px;
    background: transparent;
    border: 0;
    color: var(--muted);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
    border-radius: 6px;
    box-shadow: none;
    text-align: left;
}
.sidebar-collapse:hover { background: var(--accent-soft); color: var(--text); filter: none; }
.sidebar-collapse .nav-icon { color: inherit; transition: transform .2s; }
.admin-shell--collapsed .sidebar-collapse .nav-icon { transform: rotate(180deg); }

/* ---- Collapsed (icon-only) mode ---- */
.admin-shell--collapsed .admin-sidebar { overflow: visible; }
.admin-shell--collapsed .admin-nav     { overflow: visible; }
.admin-shell--collapsed .nav-label,
.admin-shell--collapsed .nav-chevron,
.admin-shell--collapsed .brand-text     { display: none; }
.admin-shell--collapsed .admin-brand    { padding: 0; justify-content: center; }
.admin-shell--collapsed .nav-item,
.admin-shell--collapsed .nav-group-toggle,
.admin-shell--collapsed .sidebar-collapse {
    justify-content: center;
    padding: 8px;
    width: 40px;
    margin: 1px 8px;
}
.admin-shell--collapsed .nav-divider { margin: 6px 12px; }

/* Tooltip on hover (collapsed only) */
.admin-shell--collapsed .nav-item,
.admin-shell--collapsed .nav-group { position: relative; }
.admin-shell--collapsed .nav-item:hover::after,
.admin-shell--collapsed .nav-group:hover > .nav-group-toggle::after {
    content: attr(data-label);
    position: absolute;
    left: 56px; top: 50%;
    transform: translateY(-50%);
    background: var(--text);
    color: var(--bg);
    font-size: 12px;
    padding: 5px 9px;
    border-radius: 6px;
    white-space: nowrap;
    z-index: 100;
    box-shadow: var(--shadow);
    pointer-events: none;
}

/* Flyout submenu in collapsed mode — overrides JS-set height entirely */
.admin-shell--collapsed .nav-group-items {
    display: none !important;
    height: auto !important;
    transition: none;
}
.admin-shell--collapsed .nav-group:hover > .nav-group-items {
    display: block !important;
    position: absolute;
    left: 56px;
    top: 0;
    background: var(--panel);
    border: 1px solid var(--line);
    box-shadow: var(--shadow);
    border-radius: var(--radius);
    min-width: 200px;
    padding: 6px 0;
    z-index: 99;
}
.admin-shell--collapsed .nav-group:hover .nav-subitem {
    padding: 7px 14px;
    margin: 0;
    border-radius: 0;
}
.admin-shell--collapsed .nav-group:hover > .nav-group-toggle::after { display: none; }

@media (max-width: 768px) {
    .admin-shell, .admin-shell--collapsed { display: block; }
    .admin-hamburger { display: inline-flex; align-items: center; }
    .sidebar-collapse { display: none; }
    .admin-sidebar {
        position: fixed;
        top: 0; left: 0; bottom: 0;
        width: 280px;
        z-index: 60;
        transform: translateX(-100%);
        transition: transform .24s cubic-bezier(.2,.7,.2,1);
        box-shadow: none;
        height: 100vh;
    }
    .admin-sidebar.is-open { transform: translateX(0); box-shadow: 4px 0 24px rgba(0,0,0,.15); }
    .admin-sidebar-scrim {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 55;
        background: rgba(0,0,0,.4);
        opacity: 0;
        pointer-events: none;
        transition: opacity .22s;
    }
    .admin-sidebar-scrim.is-open { opacity: 1; pointer-events: auto; }
    .admin-topbar { padding: 0 16px; }
}

.admin-main { display: flex; flex-direction: column; min-width: 0; }
.admin-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 53px;
    padding: 0 28px;
    border-bottom: 1px solid var(--line);
    background: var(--bg-raised);
    position: sticky; top: 0; z-index: 10;
    box-sizing: border-box;
}
.admin-crumbs { color: var(--muted); font-size: 13px; }
.admin-crumbs .crumb-sep { margin: 0 8px; color: var(--subtle); }
.admin-crumbs .crumb-current { color: var(--text); font-weight: 500; }
.admin-crumbs a { color: var(--muted); text-decoration: none; }
.admin-crumbs a:hover { color: var(--text); }
.admin-user { display: flex; align-items: center; gap: 12px; font-size: 13px; }

.admin-content { padding: 28px 32px 80px; width: 100%; }
.admin-content--narrow { max-width: 760px; }

.page-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 28px; gap: 16px; flex-wrap: wrap;
}
.page-header.no-divider { border-bottom: 0; padding-bottom: 0; }
.page-header-actions { display: flex; align-items: center; gap: 8px; }
.filter-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: #10b981; margin-left: 6px; vertical-align: middle; }
.clickable-row { cursor: pointer; }
.page-title {
    display: flex; align-items: center; gap: 10px; margin: 0;
    font-size: 22px;
    letter-spacing: -0.015em;
}
.page-subtitle { color: var(--muted); font-size: 13px; margin: 4px 0 0; }

/* ============================================================
   Filter / search bar
   ============================================================ */
.filter-bar {
    display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; align-items: center;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 10px 12px;
}
.filter-bar input, .filter-bar select {
    width: auto;
    padding: 7px 10px;
    font-size: 13px;
    background: var(--bg-raised);
}
.filter-bar .grow { flex: 1; min-width: 140px; }
.filter-bar .count { margin-left: auto; color: var(--muted); font-size: 13px; padding-right: 6px; }

.kv { font-family: var(--font-mono); font-size: 12px; color: var(--muted); word-break: break-all; max-width: 420px; }

.log-action  { font-family: var(--font-mono); font-size: 12px; color: var(--text-2); }
.log-when    { white-space: nowrap; color: var(--muted); font-size: 12px; }
.log-subject { font-size: 12px; color: var(--muted); }
.exception-cell { font-family: var(--font-mono); font-size: 11px; max-width: 420px; word-break: break-all; color: var(--err); }

/* ============================================================
   Public shell placeholder
   ============================================================ */
.public-shell { max-width: 720px; margin: 10vh auto; padding: 40px; }

/* .empty + .empty-title moved to shared.css */

/* Modal styles moved to shared.css */

/* ============================================================
   Toolbar (between pre-built card buttons)
   ============================================================ */
.toolbar { display: flex; gap: 10px; align-items: center; margin-top: 16px; flex-wrap: wrap; }

/* ============================================================
   User menu (avatar dropdown in topbar)
   ============================================================ */
.user-menu { position: relative; }
.user-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--accent-ink);
    border: 0;
    padding: 0;
    cursor: pointer;
    font: 500 12px/1 var(--font-body);
    letter-spacing: .02em;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    vertical-align: middle;
    flex-shrink: 0;
}
.user-avatar img { width: 34px; height: 34px; object-fit: cover; display: block; border-radius: 50%; }
.user-avatar:hover, .user-avatar:focus {
    background: var(--accent);
    filter: brightness(1.08);
    outline: none;
}
.user-menu-panel {
    position: fixed;
    top: 53px;
    right: 0;
    min-width: 240px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 0 0 var(--radius) var(--radius);
    box-shadow: 0 8px 24px rgba(0,0,0,.12);
    padding: 6px 0;
    z-index: 100;
    display: none;
}
.user-menu.open .user-menu-panel { display: block; }
.user-menu-header { padding: 10px 14px 8px; }
.user-menu-name { font-size: 13.5px; color: var(--text); font-weight: 500; }
.user-menu-email { font-size: 12px; color: var(--muted); margin-top: 2px; word-break: break-all; }
.user-menu-divider { height: 1px; background: var(--line); margin: 4px 0; }
.user-menu-item {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    padding: 8px 14px;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    text-decoration: none;
    box-shadow: none;
    border-radius: 0;
}
.user-menu-item:hover, .user-menu-item:focus {
    background: var(--accent-soft);
    color: var(--text);
    outline: none;
    filter: none;
    border-color: transparent;
}
.user-menu form { margin: 0; padding: 0; }

/* Make sure the global "primary button" hover doesn't apply to transparent
   utility buttons (dropdown items, nav toggles, tabs, link-buttons).
   Theme-agnostic so it works in both light and dark. */
.user-menu-item:hover,
.user-menu-item:focus,
.nav-group-toggle:hover,
.nav-item:hover,
.sidebar-collapse:hover,
.tab-trigger:hover,
.auth-sublink:hover,
.link-button:hover {
    background: var(--accent-soft);
    color: var(--text);
    border-color: transparent;
    filter: none;
}

/* ============================================================
   Tabs
   ============================================================ */
.tabs { width: 100%; }
.tab-list {
    display: flex;
    gap: 0;
    border-bottom: 1px solid var(--line);
    margin-bottom: 24px;
    overflow-x: auto;
    /* Hide the scrollbar visually — swipe/wheel still scrolls if tabs overflow */
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.tab-list::-webkit-scrollbar { display: none; }
.tab-trigger {
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    padding: 10px 18px;
    color: var(--muted);
    font: inherit;
    font-size: 13.5px;
    font-weight: 500;
    cursor: pointer;
    box-shadow: none;
    border-radius: 0;
    margin-bottom: -1px;
    transition: color .12s, border-color .12s;
    white-space: nowrap;
}
.tab-trigger:hover { color: var(--text); background: transparent; filter: none; }
.tab-trigger.active { color: var(--text); border-bottom-color: var(--accent); }
.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* ============================================================
   Pricing page — base rates + override rules
   ============================================================ */

.page-header.bare {
    border: 0;
    padding: 0;
    margin-bottom: 12px;
}

.link-btn {
    background: transparent;
    border: 0;
    padding: 4px 6px;
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 4px;
    display: inline-flex;
    align-items: center;
    gap: 2px;
}
.link-btn:hover { color: var(--text); background: var(--surface-2); }
.link-btn.danger:hover { color: var(--danger); }

/* Narrow column helpers reused by any table in the admin. Paired with the
   global table styles above — no custom base rules here. */
th.check, td.check   { width: 32px; padding-left: 12px; padding-right: 6px; }
th.expand, td.expand { width: 24px; padding-left: 4px; padding-right: 0; }
th.actions, td.actions {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}
tr.empty-row td {
    color: var(--muted);
    padding: 24px 16px;
    text-align: center;
    font-style: italic;
}

/* Rate-table expandable detail row (per-room ladder). Always force a distinct
   background so it reads as a sub-panel regardless of zebra position above. */
.rate-table .rate-detail td {
    background: var(--accent-soft) !important;
    padding: 14px 18px;
    border-top: 0;
}

.rooms-ladder {
    width: auto;
    border-collapse: collapse;
    font-size: 13px;
}
.rooms-ladder th,
.rooms-ladder td {
    padding: 4px 16px 4px 0;
    text-align: left;
}
.rooms-ladder th {
    color: var(--text-muted);
    font-weight: 500;
}

.muted.small { font-size: 12px; }

/* ============================================================
   Rate modal form — reuses global .row / .row-3 / label spacing.
   Only section-specific bits live here.
   ============================================================ */

/* .modal-large moved to shared.css */

/* Modal form rhythm. Rules apply at any depth so fields wrapped in
   type-section / data-when containers still space consistently. */
.rate-form { display: flex; flex-direction: column; }

/* Base rhythm for direct children of the form. */
.rate-form > * + *                 { margin-top: 10px; }
.rate-form > label                 { margin-top: 14px; margin-bottom: 5px; }
.rate-form > label:first-child     { margin-top: 0; }
.rate-form > label + input,
.rate-form > label + select,
.rate-form > label + textarea,
.rate-form > label + .segmented,
.rate-form > label + .weekday-row,
.rate-form > label + [data-daterange],
.rate-form > label + .staffpicker,
.rate-form > label + .timepicker,
.rate-form > label + .datepicker,
.rate-form > label + .locationpicker,
.rate-form > label + .numericpicker,
.rate-form > label + .toggle,
.rate-form > label + .row,
.rate-form > label + [data-staffpicker],
.rate-form > label + [data-timepicker],
.rate-form > label + [data-datepicker],
.rate-form > label + [data-colorpicker] { margin-top: 0; }
.rate-form > .segmented + label { margin-top: 18px; }

/* Same rhythm propagated into show/hide wrapper divs so the content
   inside them doesn't collapse against itself. */
.rate-form [data-type-section] > * + *,
.rate-form [data-when]          > * + * { margin-top: 10px; }
.rate-form [data-type-section] > label,
.rate-form [data-when]          > label { margin-top: 14px; margin-bottom: 5px; }
.rate-form [data-type-section] > label:first-child,
.rate-form [data-when]          > label:first-child,
.rate-form [data-type-section] > .form-group-title,
.rate-form [data-when]          > .form-group-title { margin-top: 18px; }
.rate-form [data-type-section] > .form-group-title:first-child,
.rate-form [data-when]          > .form-group-title:first-child { margin-top: 0; }
.rate-form [data-type-section] > label + input,
.rate-form [data-type-section] > label + select,
.rate-form [data-type-section] > label + textarea,
.rate-form [data-type-section] > label + .staffpicker,
.rate-form [data-type-section] > label + .timepicker,
.rate-form [data-type-section] > label + [data-staffpicker],
.rate-form [data-type-section] > label + [data-timepicker],
.rate-form [data-when]          > label + input,
.rate-form [data-when]          > label + select,
.rate-form [data-when]          > label + textarea,
.rate-form [data-when]          > label + [data-daterange] { margin-top: 0; }

/* Stacked .row grids — consistent 10px gap regardless of depth. */
.rate-form .row + .row,
.rate-form .row + .row-3,
.rate-form .row-3 + .row,
.rate-form .row-3 + .row-3 { margin-top: 10px; }

/* Section headers — consistent gap to the first control below them. */
.rate-form .form-group-title + .row,
.rate-form .form-group-title + .row-3,
.rate-form .form-group-title + [data-supplement-list],
.rate-form .form-group-title + label,
.rate-form .form-group-title + .segmented,
.rate-form .form-group-title + [data-daterange] { margin-top: 10px; }

.rate-form > label              { margin: 14px 0 5px; }
.rate-form > label:first-child { margin-top: 0; }
.rate-form .row label,
.rate-form .row-3 label        { margin: 0 0 5px; }
.rate-form p.form-hint         { margin: 4px 0 0; }
.form-group-title + .form-hint { margin-top: 2px; }
.rate-form .toggle { margin-top: 18px; margin-bottom: 0; }

.rate-form .block-field { max-width: none; }

.form-group-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    margin: 14px 0 8px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.form-group-title:first-child { margin-top: 0; }
.rate-form > .form-group-title { margin: 14px 0 8px; }
.rate-form > .form-group-title:first-child { margin-top: 0; }

/* Segmented picker — full width, equal columns. Unselected options carry a
   subtle border so the control still reads as "choose one" even when no
   state appears highlighted at first glance. */
.segmented {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 8px;
    margin: 0;
}
.segmented label {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    padding: 10px 16px;
    font-size: 13px;
    font-weight: 500;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--bg-raised);
    cursor: pointer;
    color: var(--text-muted);
    transition: background .12s, color .12s, border-color .12s;
    text-align: center;
}
.segmented label:hover { border-color: var(--accent); color: var(--text); }
.segmented label:has(input:checked) {
    background: var(--accent);
    color: var(--accent-ink);
    border-color: var(--accent);
}
.segmented input { position: absolute; opacity: 0; pointer-events: none; }

/* Weekday checkbox row — label + box on the same baseline. Wrapping each
   pair in its own flex line with fixed column widths keeps the 7 items
   visually tidy even when some days wrap to a second row. */
.weekday-row {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
    gap: 6px 12px;
    margin-top: 4px;
}
.weekday-row .checkbox {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
}
.weekday-row .checkbox input { margin: 0; }

[data-supplement-list] { display: flex; flex-direction: column; }
[data-supplement-list] .supplement-row:first-child { margin-top: 0; }

.supplement-row {
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 12px 14px 10px;
    margin-top: 10px;
    background: var(--surface-2);
}
.supplement-row .row,
.supplement-row .row-3 { margin-top: 10px; }
.supplement-row .row:first-child,
.supplement-row .row-3:first-child { margin-top: 0; }
.supplement-row-footer {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
}
.supplement-row-footer .toggle { margin: 0; }
.supplement-row-footer .link-btn { margin-left: auto; }

.mode-badge {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text-muted);
    vertical-align: middle;
}

/* ============================================================
   Preview-a-stay modal result
   ============================================================ */

.quote-result {
    margin-top: 16px;
    border-top: 1px solid var(--border);
    padding-top: 16px;
    display: grid;
    gap: 16px;
}

.quote-errors {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-left: 3px solid var(--err);
    padding: 10px 14px;
    border-radius: 6px;
    font-size: 13px;
}
.quote-errors ul { margin: 6px 0 0 18px; padding: 0; }

.quote-breakdown .quote-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}
.quote-table th, .quote-table td {
    padding: 6px 10px;
    border-bottom: 1px solid var(--border);
    text-align: left;
}
.quote-table thead th {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    font-size: 11px;
    color: var(--text-muted);
}
.quote-table .num { text-align: right; font-variant-numeric: tabular-nums; }

.quote-totals {
    display: grid;
    gap: 6px;
    font-size: 14px;
}
.quote-totals .row {
    display: flex;
    justify-content: space-between;
    padding: 4px 0;
}
.quote-totals .row.discount { color: var(--success, #2a7a3f); }
.quote-totals .row.total {
    border-top: 1px solid var(--border);
    padding-top: 10px;
    margin-top: 4px;
    font-weight: 600;
    font-size: 16px;
}
.quote-totals .row.supplement.optional { color: var(--text-muted); }
.quote-totals .row.optional-note { justify-content: space-between; }
.optional-tag {
    font-size: 10px;
    text-transform: uppercase;
    padding: 1px 6px;
    border-radius: 10px;
    background: var(--surface-2);
    color: var(--text-muted);
    margin-left: 6px;
    letter-spacing: 0.4px;
}

/* ============================================================
/* Channel sync card styles */
.outbound-feed input[readonly] { background: var(--bg-raised); cursor: text; }
.mode-badge.is-error { background: color-mix(in srgb, var(--err) 20%, var(--surface-2)); color: var(--err); }

/* Photo tiles — drag-to-reorder affordance. Primary is pinned (non-draggable)
   and shows a tiny "Pinned" hint on hover; other tiles get a grab cursor and
   a dashed placeholder treatment while dragging. */
.photo-tile[draggable="true"] { cursor: grab; }
.photo-tile[draggable="true"]:active { cursor: grabbing; }
.photo-tile.is-dragging {
    opacity: 0.45;
    outline: 2px dashed var(--accent);
    outline-offset: -4px;
    border-radius: var(--radius);
    transform: scale(0.98);
    transition: transform .1s, opacity .1s;
}
.photo-tile.is-dragging .photo-thumb img { filter: grayscale(40%); }
.photo-tile.is-primary { cursor: default; }
.photo-tile.is-primary::after {
    content: 'Pinned first';
    position: absolute;
    bottom: 6px; right: 6px;
    background: rgba(0,0,0,.55);
    color: #fff;
    font-size: 10px;
    padding: 2px 6px;
    border-radius: 3px;
    opacity: 0;
    transition: opacity .15s;
    pointer-events: none;
}
.photo-tile.is-primary:hover::after { opacity: 1; }
.photo-tile { position: relative; }

/* Featured-property star on the properties list */
.featured-star {
    color: #f59e0b;
    margin-right: 4px;
    vertical-align: -2px;
    display: inline-flex;
}

/* Custom colour picker — trigger button + popover with SV square, hue
   slider, hex input and preset row. Reusable via [data-colorpicker]. */
.colorpicker { position: relative; display: inline-block; }
.cp-trigger {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px 6px 6px;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    box-shadow: none;
}
.cp-trigger:hover { filter: none; border-color: var(--subtle); background: var(--bg-raised); }
.colorpicker.is-open .cp-trigger,
.cp-trigger:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-ring);
}
.cp-swatch {
    width: 26px; height: 26px;
    border-radius: 4px;
    border: 1px solid var(--line);
    display: inline-block;
}
.cp-hex-label { font-variant-numeric: tabular-nums; }

.cp-pop {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 40;
    width: 240px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 10px 28px rgba(0,0,0,.3);
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
/* Explicit display on .cp-pop overrides the browser's [hidden] rule —
   re-assert display:none so the popover actually hides. */
.cp-pop[hidden] { display: none; }
.cp-sv {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: 4px;
    overflow: hidden;
    cursor: crosshair;
    touch-action: none;
}
.cp-sv-saturation,
.cp-sv-value { position: absolute; inset: 0; pointer-events: none; }
.cp-sv-saturation { background: linear-gradient(to right, #fff, rgba(255,255,255,0)); }
.cp-sv-value      { background: linear-gradient(to top,   #000, rgba(0,0,0,0)); }
.cp-cursor {
    position: absolute;
    width: 12px; height: 12px;
    border: 2px solid #fff;
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.6);
    transform: translate(-50%, -50%);
    pointer-events: none;
}
.cp-hue {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 12px;
    border-radius: 6px;
    background: linear-gradient(to right,
        #ff0000 0%,   #ffff00 17%,  #00ff00 33%,
        #00ffff 50%,  #0000ff 67%,  #ff00ff 83%,  #ff0000 100%);
    outline: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
}
.cp-hue::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 16px; height: 16px;
    border-radius: 50%;
    background: #fff;
    border: 2px solid var(--text);
    cursor: pointer;
}
.cp-hue::-moz-range-thumb {
    width: 16px; height: 16px;
    border-radius: 50%;
    background: #fff;
    border: 2px solid var(--text);
    cursor: pointer;
}
.cp-row { display: flex; align-items: center; gap: 8px; }
.cp-hex { flex: 1; max-width: none; font-variant-numeric: tabular-nums; text-transform: uppercase; }
.cp-presets {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 6px;
}
.cp-preset {
    aspect-ratio: 1;
    border: 1px solid var(--line);
    border-radius: 4px;
    cursor: pointer;
    padding: 0;
    box-shadow: none;
}
.cp-preset:hover { transform: scale(1.08); filter: none; border-color: var(--accent); }

/* Generic styled file dropzone wrapping a real <input type="file">.
   File still travels via normal form submit; dropzone just provides the
   affordance (matches the photo-upload style). Reusable via
   [data-file-dropzone]. */
.filedrop-root,
[data-file-dropzone] {
    position: relative;
    cursor: pointer;
    display: block;
    margin-top: 20px;
    margin-bottom: 20px;
}
.filedrop-input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
    width: 1px; height: 1px;
}
.filedrop {
    border: 2px dashed var(--line);
    border-radius: var(--radius);
    padding: 22px 18px;
    background: var(--bg-raised);
    text-align: center;
    color: var(--muted);
    font-size: 13px;
    transition: border-color .1s, background .1s, color .1s;
}
.filedrop-root:hover .filedrop { border-color: var(--accent); color: var(--text); }
.filedrop-root.is-dragover .filedrop {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--text);
}
.filedrop-prompt  { display: inline-flex; align-items: center; gap: 10px; }
.filedrop-prompt svg { opacity: .7; }
.filedrop-selected {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--text);
    font-weight: 500;
}
.filedrop-filename { font-variant-numeric: tabular-nums; }
/* Explicit display wins over the browser's [hidden] rule — re-assert
   display:none so the prompt/selected toggles actually work. */
.filedrop-prompt[hidden],
.filedrop-selected[hidden] { display: none; }

/* Branding previews in the settings page */
.branding-preview {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 14px;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin: 6px 0 10px;
}
.branding-preview[hidden] { display: none; }
.branding-preview img { max-height: 48px; max-width: 160px; }
.branding-preview-fav img { max-height: 32px; max-width: 32px; }
.branding-preview-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    align-items: flex-start;
}
.filedrop-root[hidden] { display: none; }

/* Logo takes over the brand mark/text slot when uploaded */
.brand-logo { max-height: 28px; max-width: 100%; display: block; }

/* Mapbox pin-picker */
.map-picker {
    width: 100%;
    height: 320px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    margin-top: 4px;
}

/* Locations tree — nested list with a vertical guide line for children. */
.loc-tree { list-style: none; padding: 0; margin: 0; }
.loc-tree .loc-node { list-style: none; }
.loc-tree .loc-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--line);
}
.loc-tree > .loc-node:last-child > .loc-row { border-bottom: 0; }
.loc-drag-handle { cursor: grab; color: var(--muted); flex-shrink: 0; }
.loc-drag-handle:active { cursor: grabbing; }
.loc-node.is-dragging { opacity: .4; }
.loc-name { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; flex: 1; min-width: 0; }
.loc-actions { display: inline-flex; align-items: center; gap: 2px; }
.loc-children {
    list-style: none;
    margin: 0;
    padding-left: 22px;
    border-left: 1px dashed var(--line);
}
.loc-children .loc-node .loc-row { padding: 8px 0; }

/* Property FAQ list — draggable rows with a handle, question/answer
   body, and right-aligned actions. Mirrors the locations row pattern. */
.faq-list { list-style: none; margin: 0; padding: 0; }
.faq-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 0;
    border-bottom: 1px solid var(--line);
    cursor: grab;
}
.faq-row:last-child { border-bottom: 0; }
.faq-row:active { cursor: grabbing; }
.faq-row.is-dragging { opacity: .4; }
.faq-handle { color: var(--muted); flex-shrink: 0; padding-top: 2px; }
.faq-body { flex: 1; min-width: 0; }
.faq-question { font-weight: 600; color: var(--text); margin-bottom: 4px; }
.faq-answer { white-space: pre-wrap; }
.faq-actions { display: inline-flex; align-items: center; gap: 2px; flex-shrink: 0; }

/* Tab badge — small count chip next to tab labels on the enquiries page. */
.tab-badge {
    display: inline-block;
    min-width: 18px;
    padding: 0 6px;
    margin-left: 6px;
    background: var(--accent-soft);
    color: var(--text);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    line-height: 18px;
    text-align: center;
}

/* Status pill — used on the enquiries list. */
.status-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: var(--surface-2);
    color: var(--text-muted);
}
.status-badge.status-pending   { background: color-mix(in srgb, #f59e0b 18%, var(--surface-2)); color: #b45309; }
.status-badge.status-confirmed { background: color-mix(in srgb, #10b981 18%, var(--surface-2)); color: #065f46; }
.status-badge.status-paid      { background: color-mix(in srgb, #3b82f6 18%, var(--surface-2)); color: #1e40af; }
.status-badge.status-declined,
.status-badge.status-cancelled { background: color-mix(in srgb, #ef4444 15%, var(--surface-2)); color: #991b1b; }
html[data-theme="dark"] .status-badge.status-pending   { color: #fbbf24; }
html[data-theme="dark"] .status-badge.status-confirmed { color: #34d399; }
html[data-theme="dark"] .status-badge.status-paid      { color: #60a5fa; }
html[data-theme="dark"] .status-badge.status-declined,
html[data-theme="dark"] .status-badge.status-cancelled { color: #f87171; }

/* Form rule — visual separator inside a card form. */
hr.form-rule {
    border: 0;
    border-top: 1px solid var(--line);
    margin: 20px 0 4px;
}

/* Featured cell inside the Basics row-3 — its label sits above the toggle
   so it lines up with the Owner / Type select labels. */
.featured-cell { display: flex; flex-direction: column; }
.featured-cell .toggle { margin-top: 4px; }

/* ============================================================
   Reusable time picker — mirrors .colorpicker / .daterange shape
   ============================================================ */
.timepicker { position: relative; display: inline-block; width: 100%; max-width: 460px; }
.tp-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    width: 100%;
    padding: 7px 11px;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    text-align: left;
    box-shadow: none;
}
.tp-trigger:hover { filter: none; border-color: var(--subtle); background: var(--bg-raised); }
.tp-trigger:focus,
.timepicker.is-open .tp-trigger {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-ring);
}
.tp-value { font-variant-numeric: tabular-nums; }
.tp-value.is-placeholder { color: var(--muted); }
.tp-caret { opacity: .7; flex-shrink: 0; }
.tp-pop {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 40;
    width: auto;
    max-height: 240px;
    overflow-y: auto;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 10px 28px rgba(0,0,0,.3);
    padding: 4px;
}
.tp-pop[hidden] { display: none; }
.tp-list { display: flex; flex-direction: column; }
.tp-option {
    display: block;
    width: 100%;
    padding: 6px 10px;
    background: transparent;
    border: 0;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    text-align: left;
    border-radius: 4px;
    font-variant-numeric: tabular-nums;
}
.tp-option:hover { background: var(--accent-soft); }
.tp-option.is-selected { background: var(--accent); color: var(--accent-ink); font-weight: 600; }

/* ============================================================
   Reusable numeric picker — input + steppers either side.
   ============================================================ */
.numericpicker {
    display: inline-flex;
    align-items: stretch;
    width: 100%;
    max-width: 220px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--bg-raised);
    overflow: hidden;
}
.numericpicker:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-ring);
}
.np-step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: 6px;
    width: 38px;
    height: 38px;
    padding: 0;
    font-size: 18px;
    font-weight: 600;
    color: var(--text);
    cursor: pointer;
    line-height: 1;
    flex-shrink: 0;
    box-shadow: none;
}
.np-step:hover { background: var(--surface-2); filter: none; }
.np-step:disabled { opacity: .35; cursor: not-allowed; }
.np-field {
    flex: 1;
    min-width: 0;
    text-align: center;
    border: 0 !important;
    border-left:  1px solid var(--line) !important;
    border-right: 1px solid var(--line) !important;
    border-radius: 0 !important;
    background: var(--surface) !important;
    font-variant-numeric: tabular-nums;
    max-width: none;
    box-shadow: none !important;
    padding: 7px 6px;
}
.np-field:focus { outline: none; }
/* Nuke native spinners — our buttons replace them. */
.np-field::-webkit-outer-spin-button,
.np-field::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.np-field { -moz-appearance: textfield; }

/* Allow time picker to fill its parent cell. The global max-width was
   only useful for standalone contexts. */
.timepicker { max-width: none; }
.tp-trigger { width: 100%; }

/* Guest picker styles moved to shared.css */

/* ============================================================
   Location picker — tile-style dropdown with per-option photo.
   ============================================================ */
.locationpicker { position: relative; display: block; width: 100%; }
.lp-trigger {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px 11px;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    text-align: left;
    box-shadow: none;
}
.lp-trigger:hover { filter: none; border-color: var(--subtle); background: var(--bg-raised); }
.lp-trigger:focus,
.locationpicker.is-open .lp-trigger {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-ring);
}
.lp-trigger-photo { width: 28px; height: 28px; border-radius: 4px; object-fit: cover; flex-shrink: 0; }
.lp-trigger-text  { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lp-caret         { opacity: .7; flex-shrink: 0; }

.lp-pop {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 40;
    min-width: 320px;
    max-height: 420px;
    overflow-y: auto;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 10px 28px rgba(0,0,0,.3);
    padding: 6px;
}
.lp-pop[hidden] { display: none; }
.lp-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 2px;
}
.lp-option {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px;
    background: transparent;
    border: 0;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    text-align: left;
    border-radius: 6px;
    width: 100%;
    box-shadow: none;
}
.lp-option:hover { background: var(--accent-soft); }
.lp-option.is-selected { background: var(--accent); color: var(--accent-ink); }
.lp-option-photo {
    width: 40px; height: 40px;
    border-radius: 6px;
    object-fit: cover;
    flex-shrink: 0;
    background: var(--surface-2);
}
.lp-option-photo-empty { border: 1px dashed var(--line); }
.lp-option-label { flex: 1; min-width: 0; }
.lp-option-any .lp-option-photo { background: var(--surface-2); display: inline-block; }

/* Mapbox error fallback */
.map-error {
    padding: 14px 16px;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: var(--muted);
    font-size: 13px;
}

/* Settings hub: grid of cards linking to each section. */
.settings-hub {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 16px;
}
.settings-card {
    display: grid;
    grid-template-columns: 48px 1fr;
    grid-template-rows: auto auto;
    column-gap: 14px;
    row-gap: 4px;
    align-items: start;
    padding: 20px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    color: inherit;
    text-decoration: none;
    transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}
.settings-card:hover {
    border-color: var(--text);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, .06);
}
.settings-card-icon {
    grid-row: 1 / span 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 12px;
    background: var(--bg-raised);
    color: var(--text);
}
.settings-card-title {
    font-weight: 600;
    font-size: 16px;
}
.settings-card-desc {
    font-size: 13px;
    color: var(--muted);
    line-height: 1.4;
}

/* Reports — compact checkbox list sitting in the same box as a <select>,
   with a scrollable area when the property list is long. */
.report-checklist {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--bg);
    max-height: 200px;
    overflow-y: auto;
    padding: 6px 10px;
}
.report-checklist-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 0;
    font-size: 13px;
    line-height: 1.35;
    cursor: pointer;
}
.report-checklist-row input[type="checkbox"] { margin: 0; flex-shrink: 0; }
.report-checklist-empty { padding: 6px 0; }

/* Totals row sits under the last body row — same font-weight as body,
   with a subtle top border so the eye catches the summary without the
   centered/bold <th> default getting in the way. */
.card--table tfoot tr.row-totals td,
.card--table tbody tr.row-totals td {
    border-top: 2px solid var(--line);
    padding-top: 12px;
    padding-bottom: 12px;
    background: var(--bg-raised);
}

/* Headline stats block above each report table — four evenly-spaced
   tiles with a big number, a small label, and a delta line that
   compares the current window against the equivalent previous window. */
.report-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px;
    margin-bottom: 20px;
}
.report-stat {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 16px 18px;
}
.report-stat-label {
    font-size: 12px;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 6px;
}
.report-stat-value {
    font-size: 24px;
    font-weight: 600;
    line-height: 1.2;
    margin-bottom: 6px;
}
.report-stat-delta {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    font-weight: 500;
}
.report-stat-delta svg { display: block; }
.report-stat-up   { color: #059669; }
.report-stat-down { color: #dc2626; }
.report-stat-flat { color: var(--muted); }

/* Bar chart card — one row per group, label on left, rounded track on
   the right with a smooth animated fill. No inline styles: widths come
   from a data-pct attribute via tiny admin.js hook. */
.report-chart-card {
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 20px 22px;
    margin-bottom: 20px;
}
.report-chart-title {
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 14px;
    color: var(--text);
}
.report-chart-bars { display: flex; flex-direction: column; gap: 10px; }
.report-bar-row {
    display: grid;
    grid-template-columns: minmax(120px, 22%) 1fr minmax(80px, auto);
    align-items: center;
    gap: 12px;
    font-size: 13px;
}
.report-bar-label {
    color: var(--text);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.report-bar-track {
    position: relative;
    height: 10px;
    background: var(--bg-raised);
    border-radius: 999px;
    overflow: hidden;
}
.report-bar-fill {
    position: absolute;
    inset: 0 auto 0 0;
    width: 0;
    background: linear-gradient(90deg, var(--text), var(--text));
    border-radius: 999px;
    transition: width 420ms cubic-bezier(.2, .8, .2, 1);
}
.report-bar-value {
    text-align: right;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}
@media (max-width: 640px) {
    .report-bar-row { grid-template-columns: 1fr auto; row-gap: 4px; }
    .report-bar-row .report-bar-track { grid-column: 1 / -1; }
}

/* Mail test card: put the submit button on the same row as the email input. */
.mail-test { margin-top: 20px; }
.mail-test-submit {
    display: flex;
    align-items: flex-end;
}

/* Property form: toggles stack + description editor */
.prop-toggles {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 16px;
    padding: 14px 16px;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}
.prop-toggles .toggle { margin: 0; }
.prop-desc-editor {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
}
.prop-desc-editor .et-editable { min-height: 160px; }

/* Email template rich editor */
.et-editor-card { padding: 0; overflow: hidden; }
.et-toolbar {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--line);
    background: var(--bg-raised);
    position: sticky;
    top: 0;
    z-index: 2;
    flex-wrap: wrap;
}
html[data-theme="dark"] .et-toolbar { background: var(--bg); }
.et-tool {
    width: 32px; height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--text);
    cursor: pointer;
    font-size: 14px;
}
.et-tool:hover { background: var(--panel); border-color: var(--line); }
.et-tool.is-active { background: var(--accent-soft); border-color: var(--text); }
.et-divider {
    width: 1px;
    height: 20px;
    background: var(--line);
    margin: 0 6px;
}
.et-dropdown { position: relative; margin-left: 2px; }
.et-dropdown > .et-tool { width: auto; padding: 0 10px; gap: 4px; font-size: 12px; font-weight: 500; }
.et-dropdown-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 4px 0;
    z-index: 10;
    min-width: 160px;
}
.et-dropdown-menu button {
    display: block;
    width: 100%;
    text-align: left;
    padding: 7px 14px;
    border: 0;
    border-radius: 0;
    background: none;
    font: inherit;
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
}
.et-dropdown-menu button:hover { background: var(--surface-2); }
.et-dropdown-divider { height: 1px; background: var(--line); margin: 4px 0; }
.et-var-group { display: inline-flex; align-items: center; height: 32px; }
.et-var-select { max-width: 260px; font-size: 12px; height: 32px; }
.et-editable {
    min-height: 320px;
    padding: 20px 24px;
    font-size: 14px;
    line-height: 1.7;
    outline: none;
    color: var(--text);
}
.et-editable:focus { box-shadow: none; }
.et-editable p { margin: 0 0 10px; }
.et-editable a { color: var(--text); text-decoration: underline; }
.et-editable table { width: 100%; border-collapse: collapse; margin: 12px 0; }
.et-editable td, .et-editable th {
    border: 1px solid var(--line);
    padding: 8px 10px;
    text-align: left;
    font-size: 13px;
    min-width: 40px;
}
.et-editable th { background: var(--bg-raised); font-weight: 600; }
.et-bottom-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin-top: 10px;
}
.et-bottom-row h2 { margin-top: 0; }
.et-bottom-row .form-hint { margin-bottom: 14px; }
@media (max-width: 720px) { .et-bottom-row { grid-template-columns: 1fr; } }

/* Simple pill badges used on the template list status column. */
.pill {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}
.pill-success { background: color-mix(in srgb, #10b981 18%, transparent); color: #047857; }
.pill-muted   { background: var(--bg-raised); color: var(--muted); }

/* Copy-pasteable code block — used by the cron setup page and future
   install instructions. Respects the admin theme via tokens. */
.code-block {
    margin: 8px 0 6px;
    padding: 12px 14px;
    background: var(--bg-raised);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
    line-height: 1.5;
    overflow-x: auto;
    white-space: pre;
    color: var(--text);
    scrollbar-width: none;           /* Firefox: hide bar */
    -ms-overflow-style: none;        /* IE/Edge legacy */
}
.code-block::-webkit-scrollbar { display: none; }  /* WebKit/Blink */

/* Simple inline notice block — icon on the left, message on the right. */
.callout {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 14px;
    padding: 12px 14px;
    border-radius: var(--radius);
    font-size: 13px;
    line-height: 1.5;
}
.callout svg { flex: 0 0 auto; }
.callout-warn {
    background: color-mix(in srgb, #f59e0b 14%, transparent);
    color: #92400e;
    border: 1px solid color-mix(in srgb, #f59e0b 35%, transparent);
}
.callout-warn svg { color: #b45309; }

/* ---------- Rota (month view) ---------- */
.rota-month-label {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
}
.rota-month-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 4px;
}
.rota-month-dow {
    text-align: center;
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 6px 0;
}
.rota-month-cell {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    aspect-ratio: 1 / 1;
    padding: 8px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--bg-raised);
    color: var(--text);
    text-decoration: none;
    transition: border-color .15s, background .15s, transform .15s;
    min-height: 72px;
}
.rota-month-cell:hover {
    border-color: var(--subtle);
    background: var(--panel);
}
.rota-month-cell.is-out {
    background: transparent;
    color: var(--muted);
    opacity: 0.55;
}
.rota-month-cell.is-weekend:not(.is-out) {
    background: color-mix(in srgb, var(--bg-raised) 80%, var(--bg));
}
.rota-month-cell.is-today {
    border-color: #2563eb;
    box-shadow: 0 0 0 1px #2563eb inset;
}
.rota-month-cell.has-slots {
    cursor: pointer;
}
.rota-month-cell.has-slots:hover {
    transform: translateY(-1px);
}
.rota-month-day {
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
}
.rota-month-badge {
    align-self: flex-end;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 7px;
    border-radius: 999px;
    background: #2563eb;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
}

/* Stacked staff avatars on each populated day cell. Circles overlap by
   ~6px so a busy day reads as one cluster; if the row would exceed the
   cell width, flex-wrap drops the overflow onto a second line. */
.rota-month-staff {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 3px 0;
    align-self: flex-start;
    padding-left: 8px;
}
.rota-month-staff-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    object-fit: cover;
    background: var(--bg-raised);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    border: 2px solid var(--bg-raised);
    margin-left: -8px;
    flex-shrink: 0;
    box-sizing: border-box;
}
.rota-month-cell.is-weekend:not(.is-out) .rota-month-staff-avatar {
    border-color: color-mix(in srgb, var(--bg-raised) 80%, var(--bg));
}
.rota-month-staff-avatar-fallback {
    background: color-mix(in srgb, #2563eb 15%, var(--bg-raised));
    color: #1d4ed8;
}

/* ---------- Rota (day view) ---------- */
.rota-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}
.rota-date-nav { display: flex; gap: 8px; }
.rota-date-form { display: flex; align-items: center; gap: 8px; }
.rota-date-form label { margin: 0; }
.rota-date-form .datepicker { width: 150px; flex-shrink: 0; }
.rota-date-form .datepicker-input { height: 36px; }
.rota-legend { display: flex; gap: 8px; }
.rota-chip {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}
.rota-chip-draft     { background: color-mix(in srgb, #94a3b8 22%, transparent); color: #475569; }
.rota-chip-confirmed { background: color-mix(in srgb, #2563eb 22%, transparent); color: #1d4ed8; }
.rota-chip-done      { background: color-mix(in srgb, #10b981 22%, transparent); color: #047857; }

.rota-shell { padding: 0; overflow: hidden; }
.rota-scroll { overflow: auto; max-height: calc(100vh - 320px); }
.rota-grid {
    display: grid;
    grid-template-columns: 70px repeat(auto-fit, minmax(220px, 1fr));
    min-width: 100%;
}
.rota-gutter {
    position: sticky; left: 0; z-index: 2;
    background: var(--panel);
    border-right: 1px solid var(--line);
}
.rota-gutter-head {
    height: 56px;
    border-bottom: 1px solid var(--line);
}
.rota-gutter-hour {
    display: flex;
    align-items: flex-start;
    justify-content: flex-end;
    padding: 2px 10px 0 0;
    color: var(--muted);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    border-bottom: 1px dashed var(--line);
}
.rota-col { border-right: 1px solid var(--line); }
.rota-col:last-child { border-right: 0; }
.rota-col-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    height: 56px;
    border-bottom: 1px solid var(--line);
    position: sticky; top: 0; z-index: 1;
    background: var(--panel);
}
.rota-col-name { font-weight: 600; font-size: 13px; }
.rota-col-body {
    position: relative;
    background-image: repeating-linear-gradient(
        to bottom,
        transparent 0 calc(var(--rota-hour-px) - 1px),
        var(--line) calc(var(--rota-hour-px) - 1px) var(--rota-hour-px)
    );
    cursor: crosshair;
}
.rota-block {
    /* Side-by-side layout for overlapping slots in the same column.
       --track = this block's horizontal index (0..N-1),
       --tracks = number of concurrent blocks at its moment,
       defaulting to a single full-width block when unset. */
    --track: 0;
    --tracks: 1;
    position: absolute;
    left: calc(6px + (var(--track) / var(--tracks)) * (100% - 12px));
    width: calc((100% - 12px) / var(--tracks) - 4px);
    padding: 6px 8px;
    border-radius: 8px;
    border: 1px solid transparent;
    background: var(--bg-raised);
    color: var(--text);
    text-align: left;
    cursor: pointer;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 12px;
    line-height: 1.3;
    transition: transform 80ms ease, box-shadow 80ms ease;
}
.rota-block:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(0,0,0,.08); }
.rota-block-time { font-weight: 700; font-variant-numeric: tabular-nums; }
.rota-block-title { font-weight: 600; }
.rota-block-property { color: var(--muted); }
.rota-block-draft {
    background: color-mix(in srgb, #94a3b8 15%, var(--panel));
    border: 1px dashed #94a3b8;
}
.rota-block-confirmed {
    background: color-mix(in srgb, #2563eb 12%, var(--panel));
    border-color: #2563eb;
}
.rota-block-done {
    background: color-mix(in srgb, #10b981 14%, var(--panel));
    border-color: #10b981;
    opacity: 0.85;
}
.rota-block-cancelled {
    background: color-mix(in srgb, #ef4444 10%, var(--panel));
    border-color: #ef4444;
    text-decoration: line-through;
    opacity: 0.6;
}
/* Warning stripe for overlapping slots on the same staff member. */
.rota-block-clash {
    border-color: #ef4444 !important;
    box-shadow: inset 0 0 0 1px #ef4444;
    background-image: repeating-linear-gradient(
        135deg,
        transparent 0 8px,
        color-mix(in srgb, #ef4444 18%, transparent) 8px 10px
    );
}

/* Drop placeholder for rota drag-and-drop */
.rota-drop-placeholder {
    background: color-mix(in srgb, var(--accent) 15%, transparent);
    border: 2px dashed var(--accent);
    border-radius: var(--radius);
    z-index: 5;
}

/* ---------- Staff picker (availability maintenance, rota forms) ---------- */
.staffpicker { position: relative; display: block; }
.sp-trigger {
    display: flex; align-items: center; gap: 10px;
    width: 100%;
    padding: 8px 12px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    cursor: pointer;
    text-align: left;
    color: var(--text);
    font-size: 14px;
}
.sp-trigger:hover { border-color: var(--text); }
.staffpicker.is-open .sp-trigger { border-color: var(--text); }
.sp-trigger-text { flex: 1; }
.sp-trigger-role { color: var(--muted); font-weight: 400; }
.sp-caret { opacity: .6; transition: transform 120ms; }
.staffpicker.is-open .sp-caret { transform: rotate(180deg); }
.sp-pop {
    position: absolute; left: 0; right: 0; top: calc(100% + 4px);
    z-index: 20;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px rgba(0,0,0,.08);
    max-height: 320px;
    overflow-y: auto;
    padding: 4px;
}
.sp-option {
    display: flex; align-items: center; gap: 10px;
    width: 100%;
    padding: 8px 10px;
    background: none;
    border: 0;
    border-radius: 8px;
    cursor: pointer;
    text-align: left;
    color: var(--text);
    font-size: 14px;
}
.sp-option:hover { background: var(--bg-raised); }
.sp-option.is-selected { background: var(--accent-soft); }
.sp-option-body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.sp-option-name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sp-option-role { color: var(--muted); font-size: 12px; }

/* Shared avatar styling — reused by the trigger + every option row so
   swapping image <-> initials doesn't shift the layout. */
.sp-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px; height: 28px;
    border-radius: 999px;
    object-fit: cover;
    background: var(--bg-raised);
    color: var(--muted);
    font-weight: 600;
    font-size: 11px;
    text-transform: uppercase;
    flex-shrink: 0;
}
.sp-avatar-empty { color: var(--muted); }

/* Staff avatar — image or initial fallback. */
.staff-avatar-cell { width: 48px; }
.staff-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 999px;
    object-fit: cover;
    background: var(--bg-raised);
    color: var(--muted);
    font-weight: 600;
    font-size: 14px;
    text-transform: uppercase;
}

/* ===========================================================================
   Page builder — modal form, builder canvas, palette.
   Shared across the /admin/pages list (metadata modal) and
   /admin/pages/{id}/builder (block canvas stub).
   =========================================================================== */

/* Page metadata modal form — uses the same label / input flow as the
   rate-form: each label gets top margin, the input below it sits flush.
   Single column (modals are narrow); every control is full width. */
.pf-form { display: block; }
.pf-form > label {
    display: block;
    margin-top: 16px;
    margin-bottom: 6px;
    font-weight: 600;
    font-size: 13px;
}
.pf-form > label:first-child { margin-top: 0; }
.pf-form > label + input,
.pf-form > label + select,
.pf-form > label + textarea,
.pf-form > label + .pf-media-picker { margin-top: 0; }
.pf-form > input[type="text"],
.pf-form > input[type="number"],
.pf-form > select,
.pf-form > textarea {
    width: 100%;
    box-sizing: border-box;
}
.pf-form > .form-hint { margin: 4px 0 0; }
.pf-sep { border: 0; border-top: 1px solid var(--border); margin: 18px 0 12px; }
.pf-section-title {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
    margin: 0 0 4px;
    font-weight: 700;
}
/* The first label after a section title doesn't need its usual
   16px top — the section title already provides that gap. */
.pf-form > .pf-section-title + label { margin-top: 8px; }
.pf-counter {
    float: right;
    font-weight: 400;
    font-size: 12px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}
.pf-media-picker {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.pf-media-preview {
    width: 80px;
    height: 60px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--text) 6%, transparent);
    overflow: hidden;
    flex-shrink: 0;
}
.pf-media-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pf-media-preview:empty {
    background-image:
        linear-gradient(45deg, color-mix(in srgb, var(--text) 8%, transparent) 25%, transparent 25%),
        linear-gradient(-45deg, color-mix(in srgb, var(--text) 8%, transparent) 25%, transparent 25%);
    background-size: 12px 12px;
}
.pf-error {
    margin-top: 14px;
    padding: 10px 12px;
    border-radius: 8px;
    background: color-mix(in srgb, var(--danger, #c0392b) 10%, transparent);
    color: var(--danger, #c0392b);
    font-size: 13px;
}
/* Forceful hide — beats .pf-form > input's display:block and any
   other rule that might otherwise beat the [hidden] attribute. */
.is-hidden { display: none !important; }

/* Builder layout — palette column + canvas column */
.pb-builder {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 20px;
    align-items: start;
}
@media (max-width: 900px) { .pb-builder { grid-template-columns: 1fr; } }

.pb-palette {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 16px;
    position: sticky;
    top: 80px;
}
.pb-palette-title { margin: 0 0 4px; font-size: 14px; font-weight: 700; }
.pb-palette-list { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
.pb-palette-tile {
    display: grid;
    grid-template-columns: 28px 1fr;
    grid-template-rows: auto auto;
    column-gap: 10px;
    row-gap: 2px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    cursor: grab;
    transition: transform .12s ease, border-color .12s ease, background .12s ease;
}
.pb-palette-tile:hover { border-color: var(--text); transform: translateY(-1px); }
.pb-palette-tile:active { cursor: grabbing; }
.pb-palette-icon { grid-row: 1 / span 2; align-self: center; color: var(--text); }
.pb-palette-label { font-weight: 600; font-size: 14px; }
.pb-palette-desc { font-size: 12px; color: var(--muted); line-height: 1.3; }

.pb-canvas-wrap { min-width: 0; }
.pb-canvas {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 16px;
    min-height: 360px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.pb-canvas.is-dropping { border-color: var(--accent, var(--text)); }

/* Empty state — shown when no blocks are placed yet. */
.pb-empty {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 280px;
    border: 2px dashed var(--border);
    border-radius: 10px;
    background: color-mix(in srgb, var(--text) 3%, transparent);
}
.pb-empty[hidden] { display: none; }
.pb-empty-inner { text-align: center; color: var(--muted); padding: 40px 20px; }
.pb-empty-inner h3 { margin: 12px 0 6px; font-size: 16px; color: var(--text); }
.pb-empty-inner p  { margin: 0; font-size: 13px; max-width: 340px; }

/* Block tile — bar on top with type label + edit/delete/grip, body holds
   the rendered public HTML. Hover lifts the bar visibility. */
.pb-tile {
    position: relative;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    transition: border-color .15s ease, transform .15s ease, opacity .15s ease;
    overflow: hidden;
}
.pb-tile.is-dragging { opacity: .35; }
.pb-tile:hover { border-color: var(--text); }
.pb-tile-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 10px;
    background: color-mix(in srgb, var(--text) 6%, transparent);
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    font-weight: 600;
}
.pb-tile-type { text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); font-size: 11px; }
.pb-tile-actions { display: inline-flex; align-items: center; gap: 4px; }
.pb-tile-btn {
    border: 0;
    background: transparent;
    font-size: 12px;
    padding: 4px 8px;
    border-radius: 4px;
    color: var(--text);
    cursor: pointer;
}
.pb-tile-btn:hover { background: color-mix(in srgb, var(--text) 10%, transparent); }
.pb-tile-grip { cursor: grab; padding: 4px; color: var(--muted); font-weight: 700; }
.pb-tile-grip:active { cursor: grabbing; }
.pb-tile-body { padding: 8px; }
/* Scope block preview styles a bit so runaway inline CSS from a block's
   render doesn't blow out the canvas. */
.pb-tile-body img { max-width: 100%; height: auto; }

/* Placeholder — grows between blocks to show where the drop will land.
   Smooth transition gives the "speed" animation the brief calls for. */
.pb-placeholder {
    border: 2px dashed var(--accent, var(--text));
    background: color-mix(in srgb, var(--accent, var(--text)) 8%, transparent);
    border-radius: 10px;
    min-height: 64px;
    animation: pbPhAppear .18s ease;
}
@keyframes pbPhAppear { from { opacity: 0; transform: scaleY(.6); } to { opacity: 1; transform: scaleY(1); } }

/* Palette tile drag state */
.pb-palette-tile.is-dragging { opacity: .5; transform: scale(.97); }

/* Inline content editing — contenteditable hover/focus states so users
   can see what's editable without clicking first. */
.pb-tile-body [contenteditable="true"] {
    outline: none;
    border-radius: 4px;
    transition: box-shadow .12s ease, background .12s ease;
}
.pb-tile-body [contenteditable="true"]:hover {
    background: color-mix(in srgb, var(--text) 5%, transparent);
}
.pb-tile-body [contenteditable="true"]:focus {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, var(--text)) 45%, transparent);
    background: var(--surface);
}
/* Clickable image placeholder — Visual block empty state */
.pb-tile-body .pb-visual-image[data-pb-edit-image] {
    cursor: pointer;
    position: relative;
    transition: box-shadow .12s ease;
}
.pb-tile-body .pb-visual-image[data-pb-edit-image]:hover {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, var(--text)) 45%, transparent);
}
.pb-visual-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 120px;
    color: var(--muted);
    font-size: 13px;
    background: color-mix(in srgb, var(--text) 5%, transparent);
    border-radius: 8px;
}

/* Cog (properties) drawer content — each field stacks full-width
   inside the 420px right-hand drawer. */
.pb-cog-form { display: flex; flex-direction: column; gap: 16px; }
.pb-cog-form .pb-field > label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 6px;
}
.pb-cog-form .pb-field input,
.pb-cog-form .pb-field select {
    width: 100%;
    box-sizing: border-box;
}

/* 9-way alignment grid — small 3×3 that mirrors the anchor positions
   you'd set on the block. Active cell shows a filled dot. */
.pb-align9 {
    display: grid;
    grid-template-columns: repeat(3, 28px);
    grid-template-rows: repeat(3, 28px);
    gap: 4px;
    width: max-content;
    padding: 6px;
    border: 1px solid var(--line, var(--border));
    border-radius: 8px;
    background: color-mix(in srgb, var(--text) 4%, transparent);
}
.pb-align9-cell {
    border: 1px solid var(--line, var(--border));
    border-radius: 4px;
    background: var(--panel, var(--surface));
    cursor: pointer;
    position: relative;
    transition: background .12s ease, border-color .12s ease;
    padding: 0;
}
.pb-align9-cell:hover { border-color: var(--text); }
.pb-align9-cell::after {
    content: '';
    position: absolute;
    width: 8px; height: 8px;
    border-radius: 50%;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    background: transparent;
    transition: background .12s ease;
}
.pb-align9-cell.is-active {
    background: var(--text);
    border-color: var(--text);
}
.pb-align9-cell.is-active::after { background: var(--panel, #fff); }

/* FAQ inline editing — each Q&A is a sub-block with drag handle + delete */
.pb-faq-item--edit {
    position: relative;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 8px;
    background: var(--surface);
    transition: border-color .12s ease, box-shadow .12s ease, opacity .12s ease;
}
.pb-faq-item--edit.is-dragging { opacity: .45; }
.pb-faq-item--edit.is-drop-target { border-color: var(--accent, var(--text)); box-shadow: 0 -2px 0 var(--accent, var(--text)) inset; }
.pb-faq-item-controls {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}
.pb-faq-item-grip {
    cursor: grab;
    color: var(--muted);
    font-weight: 700;
    user-select: none;
    padding: 2px 6px;
}
.pb-faq-item-grip:active { cursor: grabbing; }
.pb-faq-item-del {
    border: 0;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
    padding: 2px 8px;
    border-radius: 6px;
}
.pb-faq-item-del:hover { color: var(--danger, #c0392b); background: color-mix(in srgb, var(--danger, #c0392b) 10%, transparent); }
.pb-faq-q { font-weight: 600; font-size: 15px; margin-bottom: 8px; }
.pb-faq-a { font-size: 14px; line-height: 1.55; }
.pb-faq-add {
    border: 1px dashed var(--border);
    background: transparent;
    color: var(--muted);
    padding: 10px 14px;
    border-radius: 8px;
    cursor: pointer;
    width: 100%;
    font-size: 13px;
    font-weight: 600;
    transition: border-color .12s ease, color .12s ease;
}
.pb-faq-add:hover { border-color: var(--text); color: var(--text); }

/* Pages nav subitem — force the active highlight to match other groups
   (fixes the malformed highlight when Pages/Media tabs are active). */
.nav-group-items .nav-subitem.active {
    color: var(--text);
    background: color-mix(in srgb, var(--text) 8%, transparent);
    border-radius: 6px;
}

/* Block editor fields (shared by inline editor) */
.pb-editor { display: flex; flex-direction: column; gap: 16px; }
.pb-editor .pb-field { display: block; }
.pb-editor .pb-field > label {
    display: block;
    font-weight: 600;
    font-size: 13px;
    margin-bottom: 6px;
}
.pb-editor .pb-field input[type="text"],
.pb-editor .pb-field input[type="number"],
.pb-editor .pb-field > select,
.pb-editor .pb-field > textarea {
    width: 100%;
    box-sizing: border-box;
}
.pb-field-row { display: flex; align-items: center; gap: 10px; }
.pb-field-alt { width: 100%; box-sizing: border-box; margin-top: 8px; }
.pb-media-picker {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.pb-media-preview {
    width: 100px;
    height: 72px;
    border-radius: 8px;
    overflow: hidden;
    background: color-mix(in srgb, var(--text) 6%, transparent);
    flex-shrink: 0;
}
.pb-media-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Repeater */
.pb-repeater-list { display: flex; flex-direction: column; gap: 12px; margin-bottom: 10px; }
.pb-repeater-item {
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    background: color-mix(in srgb, var(--text) 2%, transparent);
}
.pb-repeater-item-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    background: color-mix(in srgb, var(--text) 6%, transparent);
    font-weight: 600;
    font-size: 13px;
}
.pb-repeater-item-body { padding: 12px; display: flex; flex-direction: column; gap: 12px; }

/* ===========================================================================
   Media library — grid of uploaded images + toolbar + upload modal form.
   Shared with the picker modal (same tile styles).
   =========================================================================== */
.toolbar {
    display: flex;
    gap: 10px;
    align-items: center;
    margin: 0 0 16px;
}
.toolbar-search {
    flex: 1;
    max-width: 320px;
}
.ml-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 14px;
}
.ml-tile {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    overflow: hidden;
    transition: border-color .15s ease, transform .15s ease;
    position: relative;
}
.ml-tile:hover { border-color: var(--text); }
.ml-tile.is-selected { border-color: var(--text); box-shadow: 0 0 0 2px var(--text) inset; }
.ml-thumb {
    aspect-ratio: 4 / 3;
    background: color-mix(in srgb, var(--text) 6%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
.ml-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ml-meta { padding: 10px 12px; min-width: 0; }
.ml-name {
    font-weight: 600;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ml-dim { margin-top: 2px; }
.ml-actions {
    position: absolute;
    top: 8px;
    right: 8px;
    display: flex;
    gap: 4px;
    opacity: 0;
    transition: opacity .15s ease;
}
.ml-tile:hover .ml-actions { opacity: 1; }
.ml-picker-upload { cursor: pointer; margin-left: auto; }

/* Results header — gives "Showing 1-2 of 2" proper breathing room
   above the tile grid. */
.ml-results-head {
    padding: 4px 0 14px;
    border-bottom: 1px solid var(--border, var(--line));
    margin-bottom: 18px;
}
.ml-tags { margin-top: 4px; }
.ml-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--border, var(--line));
}
.ml-pagination .btn.is-disabled {
    opacity: .4;
    pointer-events: none;
    cursor: default;
}

/* Picker modal variant — denser grid with smaller thumbnails so
   more images fit on screen. Paired with `size: 'large'` on the
   Modal.open call, the picker ends up ~720px wide and fits 6
   thumbnails per row on desktop, falling back to 4 on narrow. */
.ml-picker {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-height: 360px;
}
.ml-picker .toolbar { margin: 0; }
.ml-picker .ml-grid {
    grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    max-height: 60vh;
    overflow: auto;
    padding: 4px;
    gap: 10px;
}
.ml-picker .ml-tile { cursor: pointer; }
.ml-picker .ml-meta { padding: 6px 8px; }
.ml-picker .ml-name { font-size: 12px; }
.ml-picker .ml-dim  { display: none; }

/* ===========================================================================
   LinkBrowser modal — segmented tabs, full-width search, SEO attrs.
   =========================================================================== */
.lb-browser { display: flex; flex-direction: column; gap: 14px; }

/* Tab bar — flat tabs sharing a bottom rule. Active tab: solid text
   colour fill on the tab body + a matching bottom bar that fuses with
   the divider beneath. Inactive tabs are transparent with a muted
   label; on hover the label comes forward. */
.lb-tabs {
    display: flex;
    gap: 0;
    border-bottom: 1px solid var(--border, var(--line));
    margin: 0;
}
.lb-tab {
    position: relative;
    padding: 10px 18px;
    border: 0;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    border-radius: 8px 8px 0 0;
    margin-bottom: -1px;
    transition: background .12s ease, color .12s ease;
}
.lb-tab:hover { color: var(--text); }
.lb-tab.is-active {
    background: var(--text);
    color: var(--panel, var(--surface));
}

/* Full-width search + inputs for the URL / SEO panels.
   background-color (not the `background` shorthand) so the global
   select { background-image: chevron } rule still applies — using
   the shorthand here wiped out the native-looking chevron and the
   browser's own fallback appeared stacked on top. */
.lb-search,
.lb-input {
    width: 100%;
    box-sizing: border-box;
    padding: 9px 12px;
    border: 1px solid var(--border, var(--line));
    border-radius: 8px;
    background-color: var(--surface, var(--panel));
    color: var(--text);
    font: inherit;
    font-size: 13px;
}
/* Selects need extra right padding for the shared chevron image. */
select.lb-input { padding-right: 36px; cursor: pointer; }
.lb-search { margin-bottom: 10px; }
.lb-search:focus,
.lb-input:focus { outline: none; border-color: var(--text); }
.lb-label { display: block; font-size: 12px; font-weight: 600; margin-bottom: 6px; color: var(--text); }
.lb-seo-field + .lb-seo-field { margin-top: 12px; }
.lb-nofollow-row { margin-top: 12px; }
.lb-url-panel { padding: 2px 0; }
.lb-list {
    /* Fixed 220px so every tab renders at the same height — no
       shifting between Pages (lots) / Locations (few) / URL panel. */
    min-height: 220px;
    max-height: 220px;
    overflow: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 4px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: color-mix(in srgb, var(--text) 2%, transparent);
}
.lb-url-panel,
.lb-panel[data-lb-panel="items"] { min-height: 260px; }

/* Loading spinner — centred in the list while the fetch is in flight. */
.lb-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 200px;
}
.lb-spinner {
    width: 22px;
    height: 22px;
    border: 2px solid color-mix(in srgb, var(--text) 12%, transparent);
    border-top-color: var(--text);
    border-radius: 50%;
    animation: lbSpin .6s linear infinite;
}
@keyframes lbSpin { to { transform: rotate(360deg); } }

/* Empty / error state — same height as the spinner so there's no
   jump when the request resolves with zero results. */
.lb-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 200px;
    color: var(--muted);
    font-size: 13px;
    padding: 16px;
}
.lb-item {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: 9px 12px;
    border-radius: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    cursor: pointer;
    text-align: left;
    gap: 2px;
    color: var(--text);
    font-weight: 500;
    transition: background .12s ease;
}
.lb-item:hover {
    background: color-mix(in srgb, var(--text) 10%, transparent);
    color: var(--text);
}
.lb-item.is-selected {
    background: color-mix(in srgb, var(--text) 18%, transparent);
    color: var(--text);
}
/* Force legible colour in both themes — the inherited colour inside the
   translucent list was washing out when the theme variable didn't
   cascade through the nested flex button. */
.lb-item-label { font-weight: 600; font-size: 13px; color: var(--text); }
.lb-item-sub   { color: var(--muted); }
.lb-seo {
    margin-top: 4px;
    padding-top: 14px;
    border-top: 1px solid var(--border, var(--line));
    display: block;
}

/* ===========================================================================
   RichText editor — restyled to match the rest of the admin.
   Single bordered card. Toolbar sits flush on the same surface as the
   editing area with a thin rule separating them (no shaded background
   strip). Icon-only buttons are uniform 28×28 squares, subtly hovered,
   using the text colour as the "on" state — same visual vocabulary as
   the rest of the system.
   =========================================================================== */
.rt {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border, var(--line));
    border-radius: var(--radius, 10px);
    background: var(--surface, var(--panel));
    overflow: visible; /* allow menu popovers to extend beyond the card */
}
.rt-toolbar {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 6px;
    border-bottom: 1px solid var(--border, var(--line));
    flex-wrap: wrap;
    color: var(--muted);
}

/* Buttons — uniform 28×28 icon tiles. Subtle hover, strong active. */
.rt-btn {
    width: 28px;
    height: 28px;
    border: 0;
    background: transparent;
    color: var(--muted);
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background .12s ease, color .12s ease;
}
.rt-btn svg { display: block; }
.rt-btn:hover { background: color-mix(in srgb, var(--text) 6%, transparent); color: var(--text); }
.rt-btn.is-active {
    background: var(--text);
    color: var(--panel, var(--surface));
}
.rt-btn.is-active svg { color: inherit; }

/* Separator — hairline that spans only the button height, consistent
   with the thin-rule style used elsewhere in the admin. */
.rt-sep {
    width: 1px;
    align-self: stretch;
    background: var(--border, var(--line));
    margin: 4px 4px;
}

/* Block-format dropdown — styled as a text+chevron tile that reads
   like a compact select. */
.rt-menu { position: relative; }
.rt-menu-trigger {
    width: auto;
    min-width: 108px;
    padding: 0 8px 0 10px;
    justify-content: space-between;
    gap: 6px;
    font-size: 12px;
    font-weight: 500;
    color: var(--text);
    text-align: left;
}
.rt-menu-trigger svg { opacity: .55; }
.rt-menu-pop {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 10;
    background: var(--surface, var(--panel));
    border: 1px solid var(--border, var(--line));
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .08);
    padding: 4px;
    min-width: 140px;
    display: flex;
    flex-direction: column;
}
.rt-menu-pop[hidden] { display: none; }
.rt-menu-pop button {
    border: 0;
    background: transparent;
    padding: 8px 10px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 13px;
    text-align: left;
    color: var(--text);
}
.rt-menu-pop button:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }

/* Text-colour popover — one-click swatch grid + hex fallback. No
   expandable wrapped picker: opening the popover IS the picker. */
.rt-color { position: relative; }
.rt-color-pop {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 10;
    background: var(--surface, var(--panel));
    border: 1px solid var(--border, var(--line));
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .08);
    padding: 10px;
    min-width: 180px;
}
.rt-color-pop[hidden] { display: none; }
.rt-color-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 6px;
}
.rt-color-swatch {
    width: 100%;
    aspect-ratio: 1 / 1;
    border: 1px solid var(--border, var(--line));
    border-radius: 6px;
    cursor: pointer;
    padding: 0;
    transition: transform .1s ease, border-color .1s ease;
}
.rt-color-swatch:hover { transform: scale(1.08); border-color: var(--text); }
.rt-color-hex {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 10px;
    padding: 6px 8px;
    border: 1px solid var(--border, var(--line));
    border-radius: 6px;
}
.rt-color-hex span { color: var(--muted); font-size: 13px; }
.rt-color-hex input {
    width: 100%;
    border: 0;
    background: transparent;
    outline: none;
    font: inherit;
    font-size: 13px;
    color: var(--text);
    font-family: ui-monospace, Menlo, monospace;
    letter-spacing: 0.02em;
}

/* Editing area — consistent typography with the rest of form inputs. */
.rt-area {
    padding: 14px 16px;
    min-height: 180px;
    outline: none;
    font-size: 14px;
    line-height: 1.6;
    color: var(--text);
}
.rt-area h2 { font-size: 22px; margin: 18px 0 8px; font-weight: 600; }
.rt-area h3 { font-size: 18px; margin: 14px 0 6px; font-weight: 600; }
.rt-area p  { margin: 0 0 12px; }
.rt-area a  { color: var(--text); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; }
.rt-area:focus-visible { outline: none; }
.rt:focus-within { border-color: color-mix(in srgb, var(--text) 30%, var(--border, var(--line))); }

/* Privacy policy editor: longer form, taller minimum. */
.privacy-rt .rt-area { min-height: 360px; }

/* Floating toolbar — opt-in via `RichText.mount(host, { floating: true })`.
   The toolbar is hidden until the editor takes focus, then slides in
   as a pill just above the editing area. Used in the page-builder
   canvas so inline text edits don't each show a heavy bar; other
   RichText callers (Settings etc.) keep the default anchored layout. */
.rt--floating { border: 1px solid transparent; background: transparent; overflow: visible; }
.rt--floating .rt-area { padding: 0; min-height: 0; font-size: inherit; }
.rt--floating .rt-toolbar {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 0;
    z-index: 30;
    border: 1px solid var(--border, var(--line));
    background: var(--surface, var(--panel));
    border-radius: 8px;
    padding: 4px;
    box-shadow: 0 6px 20px rgba(0,0,0,.12);
    opacity: 0;
    visibility: hidden;
    transform: translateY(4px);
    transition: opacity .12s ease, transform .12s ease, visibility 0s linear .12s;
}
.rt--floating:focus-within .rt-toolbar,
.rt--floating .rt-toolbar:hover {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition: opacity .12s ease, transform .12s ease;
}
.rt--floating { position: relative; }

/* ===========================================================================
   Enquiry conversation drawer — iMessage-style thread inside the global
   Drawer panel. The drawer-body's default scroll/padding are flattened
   via :has() so the inner .thread-messages is the only scrolling layer,
   keeping the meta header and reply form sticky.
   =========================================================================== */
.drawer-body:has(> .thread-drawer) { padding: 0; gap: 0; overflow: hidden; }

.thread-drawer {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
}
.thread-drawer-meta {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 14px 20px;
    border-bottom: 1px solid var(--line, var(--border));
}
.thread-drawer-meta-status {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
}
.thread-drawer-meta-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}

.thread-messages {
    flex: 1 1 auto;
    overflow-y: auto;
    margin-top: 12px;
    padding: 16px 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: color-mix(in srgb, var(--text) 3%, transparent);
}
.thread-messages-empty {
    margin: auto;
    text-align: center;
}
.thread-msg { max-width: 80%; }
.thread-msg-in  { align-self: flex-start; }
.thread-msg-out { align-self: flex-end; }
.thread-msg-bubble {
    padding: 8px 12px;
    border-radius: 16px;
    line-height: 1.45;
    white-space: pre-wrap;
    word-wrap: break-word;
    font-size: 14px;
}
.thread-msg-in .thread-msg-bubble {
    background: var(--panel, #fff);
    color: var(--text);
    border: 1px solid var(--line, var(--border));
    border-bottom-left-radius: 4px;
}
.thread-msg-out .thread-msg-bubble {
    background: #007aff;
    color: #fff;
    border-bottom-right-radius: 4px;
}
.thread-msg-meta {
    font-size: 11px;
    color: var(--muted);
    margin-top: 3px;
    padding: 0 6px;
}
.thread-msg-out .thread-msg-meta { text-align: right; }

.thread-reply {
    flex: 0 0 auto;
    position: relative;
    padding: 12px 0;
    border-top: 1px solid var(--line, var(--border));
    background: var(--panel, var(--surface));
}
.thread-reply textarea {
    display: block;
    width: 100%;
    box-sizing: border-box;
    resize: none;
    min-height: 44px;
    max-height: 140px;
    padding: 10px 92px 10px 12px;
    /* inherit global border + border-radius + bg-raised — the
       "boxed input" look the rest of the admin uses for textareas */
}
.thread-reply button {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    margin: 0;
}
.thread-reply textarea {
    flex: 1 1 auto;
    resize: none;
    min-height: 38px;
    max-height: 140px;
    font: inherit;
    line-height: 1.4;
}
.thread-reply button { flex: 0 0 auto; }

/* Make table rows on the enquiries index feel clickable. */
[data-enquiries-table] tbody tr:hover {
    background: color-mix(in srgb, var(--text) 4%, transparent);
}

/* Stacked radio-button row used in the approve-enquiry modal (and
   anywhere else that needs a labelled-with-help radio choice). */
.radio-row {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 10px 12px;
    border: 1px solid var(--line, var(--border));
    border-radius: 8px;
    margin-bottom: 8px;
    cursor: pointer;
}
.radio-row:has(input:checked) {
    border-color: var(--accent);
    background: var(--accent-soft);
}
.radio-row input[type="radio"] { margin-top: 4px; }
.radio-row > span { flex: 1 1 auto; }
