/* VP theme - palette lifted verbatim from the approved prototypes
   (vp_admin_console.html / vp_officer_console.html). These are the design source of truth
   for the VP web consoles; keep them in sync. Montserrat is not bundled, so it falls back
   to Segoe UI. */
:root {
    --font: 'Montserrat', 'Segoe UI', system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
    --page-bg: #eef1f5;
    --card: #ffffff;
    --ink: #525f7f;
    --ink-strong: #2f3a54;
    --muted: #8a94a6;
    --line: #e6eaf0;
    --line-soft: #eef1f5;
    --brand: #4a7dfc;
    --brand-ink: #1a2dbc;
    --grad-a: #7b9eea;
    --grad-b: #93b4f0;
    --nav-active-bg: #c2ecfb;
    --nav-active-ink: #4f5dce;
    --thead: #c8d9f0;
    --thead-border: #93b4f0;
    --ok: #2ecc71;
    --ok-d: #118260;
    --warn: #f39c12;
    --danger: #d81b60;
    --cyan: #00acc1;
    --teal: #16a085;
    --shadow: 0 2px 10px rgba(31, 45, 80, .08);
    --shadow-lg: 0 6px 24px rgba(31, 45, 80, .14);
    --radius: 12px;
}

/* ================= console shell: topbar + sidebar + content =================
   Follows the approved admin console prototype. The active-item colours
   (--nav-active-bg / --nav-active-ink) are the prototype's own values.

   x-cloak hides Alpine-controlled elements until Alpine initialises, which stops the mobile
   scrim flashing on first paint. It needs a CSS rule to work at all. */
[x-cloak] {
    display: none !important;
}

.vp-shell {
    margin: 0;
    min-height: 100vh;
    background: var(--page-bg);
    font-family: var(--font);
    color: var(--ink);
}

.vp-topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: 14px;
    height: 58px;
    padding: 0 18px;
    background: var(--card);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow);
}

.vp-topbar__brand {
    display: flex;
    align-items: center;
}

.vp-topbar__toggle {
    display: none;   /* desktop: the sidebar is always visible */
    padding: 6px 10px;
    font-size: 18px;
    line-height: 1;
    color: var(--ink-strong);
    background: none;
    border: 1px solid var(--line);
    border-radius: 8px;
    cursor: pointer;
}

.vp-topbar__user {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-left: auto;
}

.vp-topbar__name {
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-strong);
}

.vp-topbar__action {
    font-size: 13px;
    color: var(--brand);
    text-decoration: none;
}

.vp-topbar__action:hover {
    color: var(--brand-ink);
    text-decoration: underline;
}

.vp-body {
    display: flex;
    align-items: flex-start;
}

.vp-sidebar__wrap {
    flex: 0 0 232px;
    width: 232px;
    align-self: stretch;
    background: var(--card);
    border-right: 1px solid var(--line);
    min-height: calc(100vh - 58px);
}

.vp-sidebar {
    padding: 18px 12px;
    position: sticky;
    top: 58px;
}

.vp-sidebar__group {
    padding: 0 10px;
    margin: 16px 0 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--muted);
}

.vp-sidebar__group:first-child {
    margin-top: 0;
}

.vp-sidebar__list {
    list-style: none;
    margin: 0 0 4px;
    padding: 0;
}

.vp-sidebar__link {
    display: block;
    padding: 9px 10px;
    margin-bottom: 2px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink);
    text-decoration: none;
    border-radius: 8px;
    transition: background .12s, color .12s;
}

.vp-sidebar__link:hover {
    background: var(--line-soft);
    color: var(--ink-strong);
}

.vp-sidebar__link.is-active {
    background: var(--nav-active-bg);
    color: var(--nav-active-ink);
}

.vp-sidebar__empty {
    padding: 10px;
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--muted);
}

.vp-main {
    flex: 1 1 auto;
    min-width: 0;   /* lets wide tables scroll instead of stretching the layout */
    padding: 26px 28px 40px;
}

.vp-scrim {
    position: fixed;
    inset: 58px 0 0;
    z-index: 18;
    background: rgba(31, 45, 80, .35);
}

@media (max-width: 900px) {
    .vp-topbar__toggle {
        display: inline-block;
    }

    .vp-topbar__name,
    .vp-topbar__action {
        display: none;   /* keep the sign-out button reachable on a narrow bar */
    }

    .vp-sidebar__wrap {
        position: fixed;
        top: 58px;
        bottom: 0;
        left: 0;
        z-index: 20;
        transform: translateX(-100%);
        transition: transform .18s ease-out;
        box-shadow: var(--shadow-lg);
    }

    .vp-sidebar__wrap.is-open {
        transform: translateX(0);
    }

    .vp-main {
        padding: 20px 18px 32px;
    }
}

/* ================= schedule calendar =================
   Slot-bubble colours are the prototype's: green for open, pink for full. */
.vp-cal {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 6px;
}

.vp-cal__head {
    padding: 4px 0;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
    text-align: center;
}

.vp-cal__day {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    min-height: 56px;
    padding: 6px 4px;
    text-decoration: none;
    color: var(--ink);
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 10px;
    transition: border-color .12s, background .12s;
}

.vp-cal__day:hover {
    border-color: var(--brand);
}

.vp-cal__num {
    font-size: 13px;
    font-weight: 600;
}

.vp-cal__note {
    font-size: 10px;
    font-variant-numeric: tabular-nums;
    color: var(--muted);
}

.vp-cal__day.is-today .vp-cal__num {
    color: var(--brand-ink);
    text-decoration: underline;
}

.vp-cal__day.has-slots {
    background: #e7f8ef;
    border-color: #8fd9b4;
    color: var(--ok-d);
}

.vp-cal__day.has-slots .vp-cal__note {
    color: var(--ok-d);
}

.vp-cal__day.is-full {
    background: #fde7ef;
    border-color: #f0a9c6;
    color: #c01860;
}

.vp-cal__day.is-full .vp-cal__note {
    color: #c01860;
}

.vp-cal__day.is-leave {
    background: var(--line-soft);
    border-color: var(--line);
    color: var(--muted);
}

.vp-cal__day.is-selected {
    outline: 2px solid var(--brand);
    outline-offset: 1px;
}

/* ---------- auth pages: login, forgot password, change password ----------
   Also rendered inside the mobile app's web view, since tblSetupSite.ForgotPasswordURL points
   here for VP sites - hence the generous tap targets and the 16px inputs, which stop iOS from
   zooming when a field takes focus. */
.vp-auth-page {
    margin: 0;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px 16px;
    background: var(--page-bg);
    font-family: var(--font);
    color: var(--ink);
    -webkit-text-size-adjust: 100%;
}

.vp-card {
    width: 100%;
    max-width: 420px;
    background: var(--card);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

/* Brand accent carried over from the prototype card headers, reduced to a rule so the
   dark-blue wordmark below it keeps full contrast against white. */
.vp-card__accent {
    height: 4px;
    background: linear-gradient(90deg, var(--brand-ink), var(--grad-a), var(--grad-b));
}

.vp-card__brand {
    padding: 26px 28px 20px;
    text-align: center;
    border-bottom: 1px solid var(--line-soft);
}

.vp-card__brand img {
    display: inline-block;
    width: auto;
    height: 40px;
    max-width: 100%;
}

.vp-card__body {
    padding: 26px 28px 28px;
}

.vp-title {
    margin: 0;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: .2px;
    color: var(--ink-strong);
}

.vp-subtitle {
    margin: 6px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--muted);
}

/* Space between the heading block and whatever follows it, without the heading needing to know
   whether a subtitle was rendered. */
.vp-title + form,
.vp-subtitle + form,
.vp-title + .vp-prose,
.vp-subtitle + .vp-prose {
    margin-top: 22px;
}

@media (max-width: 480px) {
    .vp-card__brand {
        padding: 22px 20px 16px;
    }

    .vp-card__brand img {
        height: 34px;
    }

    .vp-card__body {
        padding: 22px 20px;
    }
}

/* ---------- text ---------- */
.vp-prose {
    margin: 0 0 18px;
    font-size: 14px;
    line-height: 1.6;
}

.vp-prose--muted {
    font-size: 13px;
    color: var(--muted);
}

.vp-hint {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    color: var(--muted);
}

/* ---------- fields ---------- */
.vp-field {
    margin-bottom: 18px;
}

.vp-field label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-strong);
}

.vp-field input {
    width: 100%;
    box-sizing: border-box;
    padding: 12px 13px;
    font-family: inherit;
    /* 16px keeps iOS Safari from zooming the page when the field takes focus. */
    font-size: 16px;
    color: var(--ink-strong);
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 8px;
    transition: border-color .15s, box-shadow .15s;
}

.vp-field input:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(74, 125, 252, .15);
}

.vp-field input.input-validation-error {
    border-color: var(--danger);
}

/* ---------- buttons and links ---------- */
.vp-btn {
    width: 100%;
    padding: 13px 16px;
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    color: #fff;
    background: var(--brand);
    border: 0;
    border-radius: 8px;
    cursor: pointer;
    transition: background .15s, opacity .15s;
}

.vp-btn:hover {
    background: var(--brand-ink);
}

.vp-btn[disabled] {
    opacity: .6;
    cursor: default;
}

.vp-btn--spaced {
    margin-top: 22px;
}

.vp-links {
    margin: 18px 0 0;
    font-size: 13px;
    text-align: center;
}

.vp-links a {
    color: var(--brand);
    text-decoration: none;
}

.vp-links a:hover {
    color: var(--brand-ink);
    text-decoration: underline;
}

/* A form button that should read as a link - used for "Sign out instead", which has to be a
   POST for antiforgery but should not compete with the primary action. */
.vp-linkbtn {
    padding: 0;
    font-family: inherit;
    font-size: 13px;
    color: var(--brand);
    background: none;
    border: 0;
    cursor: pointer;
}

.vp-linkbtn:hover {
    color: var(--brand-ink);
    text-decoration: underline;
}

/* ================= schedule overview =================
   The administrator's day monitor. Bubble colours are the prototype's slot legend - green
   available, pink booked - with an amber middle state the prototype had no need for: its slots
   were one seat each, so a slot was either free or taken. Ours carry a capacity, and a half-full
   slot reading as "available" would overstate what is left. */
.vp-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(124px, 1fr));
    gap: 10px;
}

.vp-stat {
    padding: 12px 14px;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 10px;
}

.vp-stat__num {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--ink-strong);
    font-variant-numeric: tabular-nums;
}

.vp-stat__label {
    margin-top: 2px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--muted);
}

.vp-stat--ok .vp-stat__num {
    color: var(--ok-d);
}

.vp-stat--warn .vp-stat__num {
    color: var(--danger);
}

.vp-bubbles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(116px, 1fr));
    gap: 8px;
}

.vp-bubble {
    padding: 7px 10px;
    border: 1px solid;
    border-radius: 10px;
}

.vp-bubble__time {
    display: block;
    font-size: 12.5px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.vp-bubble__seats {
    display: block;
    margin-top: 1px;
    font-size: 11px;
}

.vp-bubble--open {
    background: #e7f8ef;
    border-color: #8fd9b4;
    color: var(--ok-d);
}

.vp-bubble--part {
    background: #fff6e5;
    border-color: #f0cd8c;
    color: #8a5600;
}

.vp-bubble--full {
    background: #fde7ef;
    border-color: #f0a9c6;
    color: #c01860;
}

/* Legend swatches, so the bubble colours are readable without hovering anything. */
.vp-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    font-size: 11.5px;
    color: var(--muted);
}

.vp-legend span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.vp-legend i {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 1px solid;
    border-radius: 4px;
}

/* ---------- table row actions ----------
   The Edit / View link at the end of a list row. A bare text link disappeared into the row and
   gave no tap target, so it reads as a quiet pill: neutral until pointed at, brand on hover. Not
   a Bootstrap .btn, because .btn-outline-* pulls in Bootstrap's own palette rather than this one. */
.vp-action {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 14px;
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
    color: var(--ink);
    text-decoration: none;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 999px;
    cursor: pointer;
    transition: color .12s, background .12s, border-color .12s, box-shadow .12s;
}

.vp-action:hover {
    color: var(--brand-ink);
    background: rgba(74, 125, 252, .08);
    border-color: var(--grad-b);
    text-decoration: none;
}

.vp-action:active {
    background: rgba(74, 125, 252, .16);
    border-color: var(--brand);
}

/* Keyboard focus has to be visible on its own: the hover tint alone is too weak to locate. */
.vp-action:focus-visible {
    outline: none;
    color: var(--brand-ink);
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(74, 125, 252, .20);
}

/* ---------- alerts ---------- */
.vp-alert {
    margin-bottom: 18px;
    padding: 11px 13px;
    font-size: 13px;
    line-height: 1.45;
    border-radius: 8px;
    background: rgba(216, 27, 96, .08);
    border: 1px solid rgba(216, 27, 96, .25);
    color: var(--danger);
}

/* asp-validation-summary always emits the wrapper, so hide it until it has content. */
.vp-alert:empty,
.vp-alert.validation-summary-valid {
    display: none;
}

.vp-alert ul {
    margin: 0;
    padding-left: 18px;
}

.vp-alert--ok {
    background: rgba(46, 204, 113, .10);
    border-color: rgba(17, 130, 96, .25);
    color: var(--ok-d);
}
