/* SalonOS — install wizard styling. Same palette/token approach the
   public site and admin area will use later (see salonos-v3-spec.md):
   purple/pink/blue/green, light/dark toggle via [data-theme]. */

:root {
    --sos-primary: #7C3AED;
    --sos-secondary: #EC4899;
    --sos-accent: #0EA5E9;
    --sos-success: #10B981;
    --sos-bg: #F7F5FF;
    --sos-surface: #FFFFFF;
    --sos-text: #1F1B2E;
    --sos-muted: #6B6478;
    --sos-border: #E4DEF5;
}

[data-theme="dark"] {
    --sos-bg: #15121F;
    --sos-surface: #1E1A2E;
    --sos-text: #F1EEFA;
    --sos-muted: #A79FC0;
    --sos-border: #322B49;
}

* { box-sizing: border-box; }

body {
    background: linear-gradient(160deg, var(--sos-bg) 0%, var(--sos-bg) 60%, color-mix(in srgb, var(--sos-secondary) 8%, var(--sos-bg)) 100%);
    color: var(--sos-text);
    font-family: 'Poppins', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
    min-height: 100vh;
}

.sos-shell {
    max-width: 760px;
    margin: 0 auto;
    padding: 2.5rem 1rem 4rem;
}

.sos-brand {
    display: flex;
    align-items: center;
    gap: .6rem;
    font-weight: 700;
    font-size: 1.35rem;
    margin-bottom: 1.75rem;
}

.sos-brand .dot {
    width: 12px; height: 12px; border-radius: 50%;
    background: linear-gradient(135deg, var(--sos-primary), var(--sos-secondary));
    display: inline-block;
}

.sos-card {
    background: var(--sos-surface);
    border: 1px solid var(--sos-border);
    border-radius: 1rem;
    padding: 2rem;
    box-shadow: 0 12px 32px -18px rgba(124, 58, 237, .25);
}

.sos-stepper {
    display: flex;
    gap: .5rem;
    margin-bottom: 1.75rem;
}

.sos-step {
    flex: 1;
    text-align: center;
    padding: .5rem .25rem;
    border-radius: .6rem;
    font-size: .8rem;
    font-weight: 600;
    background: var(--sos-bg);
    border: 1px solid var(--sos-border);
    color: var(--sos-muted);
}

.sos-step.is-active {
    background: linear-gradient(135deg, var(--sos-primary), var(--sos-secondary));
    color: #fff;
    border-color: transparent;
}

.sos-step.is-done {
    color: var(--sos-success);
    border-color: var(--sos-success);
}

.btn-sos {
    background: linear-gradient(135deg, var(--sos-primary), var(--sos-secondary));
    border: none;
    color: #fff;
    font-weight: 600;
}
.btn-sos:hover, .btn-sos:focus { color: #fff; filter: brightness(1.08); }

.sos-check-row { display: flex; justify-content: space-between; align-items: center; padding: .5rem 0; border-bottom: 1px dashed var(--sos-border); }
.sos-check-row:last-child { border-bottom: none; }
.sos-badge-ok { color: var(--sos-success); font-weight: 600; }
.sos-badge-fail { color: #E11D48; font-weight: 600; }

.form-control, .form-select {
    background: var(--sos-bg);
    border: 1px solid var(--sos-border);
    color: var(--sos-text);
}
.form-control:focus, .form-select:focus {
    background: var(--sos-bg);
    color: var(--sos-text);
    border-color: var(--sos-primary);
    box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--sos-primary) 25%, transparent);
}

/* Chrome/Edge/Safari paint autofilled fields with their own yellow
   background + dark text via an internal UA style — a plain
   `background`/`color` rule (even with !important) can't override it.
   The only thing that beats it is painting our own theme colour over
   the top with an inset box-shadow large enough to fully cover the
   field, plus -webkit-text-fill-color to recolour the text itself.
   Uses var(--sos-bg)/var(--sos-text) so it matches whichever theme
   (light/dark) is active, same as every other themed input. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px var(--sos-bg) inset !important;
    box-shadow: 0 0 0 1000px var(--sos-bg) inset !important;
    -webkit-text-fill-color: var(--sos-text) !important;
    caret-color: var(--sos-text);
    /* Chrome re-applies its own autofill paint after a delay unless the
       transition is pushed out this far — a standard part of this fix. */
    transition: background-color 5000s ease-in-out 0s;
}

.theme-toggle {
    border: 1px solid var(--sos-border);
    background: var(--sos-surface);
    border-radius: 2rem;
    padding: .35rem .8rem;
    font-size: .8rem;
    color: var(--sos-muted);
}

a.sos-link { color: var(--sos-primary); font-weight: 600; text-decoration: none; }
a.sos-link:hover { text-decoration: underline; }

/* ---------------------------------------------------------------------
   Public site + admin area — wider layout than the wizard's narrow
   .sos-shell, same colour tokens/theme toggle above. Milestone 17 added
   admin/site-settings.php, the first (and only) screen that actually
   sets hero_style/hero_image_path — .pub-hero-fullscreen below is that
   template's real CSS; .pub-hero (the plain gradient) stays the default
   and is unchanged.
   --------------------------------------------------------------------- */

.pub-shell { max-width: 1080px; margin: 0 auto; padding: 0 1rem 4rem; }

.pub-nav {
    display: flex; justify-content: space-between; align-items: center;
    padding: 1.25rem 0; flex-wrap: wrap; gap: .75rem;
}
.pub-brand { display: inline-flex; align-items: center; gap: .6rem; }
.pub-brand-logo { max-height: 36px; max-width: 160px; object-fit: contain; }

/* Milestone 32 — the salon's logo again, this time as a small centred
   header above the "Staff login"/"Owner login" card title
   (staff/login.php, admin/login.php), rather than the nav-sized
   .pub-brand-logo — bigger since it's the sole visual anchor of the
   card, not sitting next to a business-name wordmark. */
.pub-login-logo { display: block; max-height: 64px; max-width: 220px; object-fit: contain; margin: 0 auto 1rem; }
.pub-nav-links { display: flex; gap: 1.25rem; align-items: center; flex-wrap: wrap; }
.pub-nav-links a { color: var(--sos-text); text-decoration: none; font-weight: 500; font-size: .95rem; }
.pub-nav-links a:hover, .pub-nav-links a.is-active { color: var(--sos-primary); }
.pub-nav-links a.is-active { font-weight: 700; }
.pub-nav-links a.btn-sos { color: #fff; padding: .5rem 1.1rem; border-radius: 2rem; }

/* Milestone 34 — <992px: Services/Our team/Waitlist drop out of the
   always-visible row (into #pubNavDropdown instead, see header.php) and
   Login/Register collapse to icon-only. The burger toggle itself is
   desktop-hidden and only appears at this same width. All untouched at
   >=992px, where the nav looks exactly as it did before. */
.pub-nav-toggle {
    display: none;
    background: none; border: none; color: var(--sos-text);
    font-size: 1.15rem; line-height: 1; padding: .5rem .6rem;
    border-radius: .5rem; cursor: pointer;
}
.pub-nav-toggle:hover { color: var(--sos-primary); }

.pub-nav-backdrop { display: none; }

/* Milestone 36 — off-canvas panel (was a drop-down under the nav row
   through Milestone 35): fixed to the viewport, slides in from the right
   via transform rather than display/height, so the .25s transition
   actually animates. Shared by both the guest links and (new this
   milestone) the account-nav links — header.php switches its contents
   on $accountNav, not its markup/CSS. Untouched at >=992px (display:none
   below is overridden inside the media query only). */
.pub-nav-dropdown { display: none; }

/* Milestone 35 — plain icon theme toggle for the public nav (book/partials/
   header.php only — admin/staff/setup keep their existing .theme-toggle
   pill, not touched here). Both icons are always in the DOM; which one
   shows is driven purely by the html[data-theme] attribute the inline
   head script (and sosToggleTheme(), footer.php) already sets, so the
   icon flips the instant the attribute changes with no extra JS. */
.pub-theme-toggle {
    background: none; border: none; color: var(--sos-text);
    font-size: 1.05rem; line-height: 1; padding: .5rem .4rem;
    cursor: pointer;
}
.pub-theme-toggle:hover { color: var(--sos-primary); }
.pub-theme-icon-dark { display: none; }
html[data-theme="dark"] .pub-theme-icon-light { display: none; }
html[data-theme="dark"] .pub-theme-icon-dark { display: inline; }

@media (max-width: 991.98px) {
    .pub-nav-link-collapsible { display: none; }
    .pub-nav-link-text { display: none; }
    .pub-nav-toggle { display: inline-flex; align-items: center; justify-content: center; }

    /* Milestone 37 — brand + icon row was wrapping onto two lines at
       mobile widths (worse once logged in, since "Log out" renders as
       text rather than an icon like Login/Register do). Force a single
       row: the icon row never wraps or shrinks (flex: 0 0 auto, gap
       closed right up), and the brand is the one thing allowed to give
       up space — its logo/name shrink first, and a long business name
       ellipsizes (.pub-brand-name) rather than pushing the icons around
       or wrapping the row. */
    .pub-nav { flex-wrap: nowrap; }
    .pub-brand { gap: .4rem; min-width: 0; flex: 1 1 auto; overflow: hidden; }
    .pub-brand-logo { max-height: 22px; max-width: 72px; }
    .pub-brand-name {
        font-size: .95rem;
        min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
    }
    .pub-nav-links { gap: .35rem; flex-wrap: nowrap; flex: 0 0 auto; }

    .pub-nav-backdrop {
        display: block;
        position: fixed; inset: 0;
        background: rgba(0, 0, 0, .4);
        opacity: 0; pointer-events: none;
        transition: opacity .25s ease;
        z-index: 1040;
    }
    .pub-nav-backdrop.is-open { opacity: 1; pointer-events: auto; }

    .pub-nav-dropdown {
        display: flex; flex-direction: column; gap: .1rem;
        position: fixed; top: 0; right: 0; bottom: 0;
        width: min(78vw, 320px);
        padding: 4.5rem 1.25rem 1.5rem;
        background: var(--sos-surface); border-left: 1px solid var(--sos-border);
        box-shadow: -12px 0 32px rgba(0, 0, 0, .3);
        transform: translateX(100%);
        transition: transform .25s ease;
        overflow-y: auto;
        z-index: 1050;
    }
    .pub-nav-dropdown.is-open { transform: translateX(0); }

    .pub-nav-dropdown-close {
        position: absolute; top: 1rem; right: 1rem;
        background: none; border: none; color: var(--sos-text);
        font-size: 1.2rem; line-height: 1; padding: .4rem;
        cursor: pointer;
    }
    .pub-nav-dropdown-close:hover { color: var(--sos-primary); }

    .pub-nav-dropdown a {
        color: var(--sos-text); text-decoration: none; font-weight: 500; font-size: .95rem;
        padding: .65rem .25rem;
    }
    .pub-nav-dropdown a:hover, .pub-nav-dropdown a.is-active { color: var(--sos-primary); }
    .pub-nav-dropdown a.is-active { font-weight: 700; }
    .pub-nav-dropdown a:not(:last-child) { border-bottom: 1px solid var(--sos-border); }
}

.pub-hero {
    background: linear-gradient(135deg, var(--sos-primary), var(--sos-secondary));
    color: #fff; border-radius: 1.25rem; padding: 3rem 2rem; text-align: center; margin-bottom: 2.5rem;
}
.pub-hero h1 { font-weight: 700; margin-bottom: .5rem; }

/* Milestone 17 — the "full-viewport background image" template. Breaks
   out of .pub-shell's 1080px max-width via the standard negative-margin
   full-bleed trick (calc(50% - 50vw) on each side cancels the shell's own
   centering) so the image genuinely spans the whole browser width, not
   just the content column. min-height (not height) fills most of the
   viewport while still growing for extra-long business names/taglines
   without clipping content. The dark linear-gradient layered into the
   same background-image (rather than a separate overlay element) keeps
   the markup identical to the default hero — same h1/p/a structure. */
.pub-hero-fullscreen {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    border-radius: 0;
    min-height: 80vh;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    padding: 3rem 1.5rem;
}
.pub-hero p { opacity: .92; max-width: 46rem; margin: 0 auto 1.5rem; }
.pub-hero .btn-light { font-weight: 600; }

.pub-section-title { font-weight: 700; margin: 2.5rem 0 1rem; }

.pub-card {
    background: var(--sos-surface); border: 1px solid var(--sos-border); border-radius: .9rem;
    padding: 1.25rem; height: 100%;
}

/* Service category accordion (book/index.php) — Bootstrap's own accordion
   re-themes fine under data-bs-theme (same mechanism the theme toggle
   already relies on), this just matches its corners/border/surface colour
   to the rest of the public site's .pub-card look rather than Bootstrap's
   own smaller default radius. */
.pub-service-accordion .accordion-item {
    background: var(--sos-surface); border: 1px solid var(--sos-border); border-radius: .9rem;
    overflow: hidden; margin-bottom: .75rem;
}
.pub-service-accordion .accordion-item:last-child { margin-bottom: 0; }
.pub-service-accordion .accordion-button {
    background: var(--sos-surface); color: inherit; font-weight: 600; font-size: 1rem;
    box-shadow: none;
}
.pub-service-accordion .accordion-button:not(.collapsed) {
    background: var(--sos-surface); color: var(--sos-primary); box-shadow: none;
}
.pub-service-accordion .accordion-button:focus { box-shadow: none; border-color: var(--sos-border); }
.pub-service-accordion .accordion-body { padding-top: .5rem; }

/* Milestone 26 — "Meet the team" cards are now clickable links through
   to a staff member's public profile page (book/staff.php); this
   modifier keeps the same .pub-card look while adding a hover cue and
   overriding the default <a> colour/underline. */
.pub-card-link {
    color: inherit;
    transition: border-color .15s ease, transform .15s ease;
}
.pub-card-link:hover {
    border-color: var(--sos-primary);
    transform: translateY(-2px);
    color: inherit;
}

.pub-service-row {
    display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem;
    padding: .85rem 0; border-bottom: 1px dashed var(--sos-border);
}
.pub-service-row:last-child { border-bottom: none; }
.pub-service-price { font-weight: 700; color: var(--sos-primary); white-space: nowrap; }

.pub-staff-avatar {
    width: 64px; height: 64px; border-radius: 50%; object-fit: cover;
    background: linear-gradient(135deg, var(--sos-primary), var(--sos-accent));
    display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; font-size: 1.3rem;
}

/* Milestone 26 — a smaller variant for a booking-history table row
   (book/bookings.php, book/account.php, book/dashboard.php), where a
   full 64px avatar would dwarf the rest of the row. Same photo-or-
   initial markup as index.php's "Meet the team" section, just sized
   down. */
.pub-staff-avatar-sm { width: 28px; height: 28px; font-size: .8rem; flex-shrink: 0; }

.pub-hours-row { display: flex; justify-content: space-between; padding: .35rem 0; border-bottom: 1px dashed var(--sos-border); font-size: .9rem; }
.pub-hours-row:last-child { border-bottom: none; }

.pub-slot-btn {
    border: 1px solid var(--sos-border); background: var(--sos-bg); color: var(--sos-text);
    border-radius: .6rem; padding: .5rem .4rem; font-weight: 600; font-size: .9rem; width: 100%;
}
.pub-slot-btn:hover { border-color: var(--sos-primary); color: var(--sos-primary); }

/* Milestone 19 — a real 3-column public-site footer (About / Explore /
   Contact), full-bleed out of .pub-shell the same way .pub-hero-fullscreen
   already does, since a footer band reads as more "real site" when it
   spans the full viewport rather than staying boxed inside the content
   column. Opening hours was dropped from the original 4-column draft —
   the homepage already has its own "Opening hours" section, and
   repeating it in the footer on every page was pure duplication. */
.pub-footer {
    margin-top: 3rem;
    /* Cancels .pub-shell's own 4rem bottom padding (needed on pages that
       have no .pub-footer at all, e.g. the staff portal's own footer
       partial) — without this, that padding still applied AFTER this
       footer band on every page that does include it, leaving a fixed
       ~64px dead gap below the footer on every single one. */
    margin-bottom: -4rem;
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    padding: 2.5rem 1.5rem 1.5rem;
    background: var(--sos-surface);
    border-top: 1px solid var(--sos-border);
    color: var(--sos-muted);
    font-size: .9rem;
}
.pub-footer-inner { max-width: 1080px; margin: 0 auto; }
.pub-footer-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
    margin-bottom: 2rem;
}
.pub-footer-heading {
    font-weight: 700; color: var(--sos-primary); margin-bottom: .75rem;
    font-size: .82rem; text-transform: uppercase; letter-spacing: .04em;
}
.pub-footer-links, .pub-footer-contact { display: flex; flex-direction: column; }
.pub-footer-links a, .pub-footer-contact a { color: var(--sos-muted); text-decoration: none; padding: .2rem 0; }
.pub-footer-links a:hover, .pub-footer-contact a:hover { color: var(--sos-primary); }
.pub-footer-contact span { padding: .2rem 0; }
.pub-footer-bottom {
    border-top: 1px solid var(--sos-border);
    padding-top: 1.25rem;
    display: flex; justify-content: space-between; flex-wrap: wrap; gap: .5rem;
    font-size: .8rem;
}
@media (max-width: 767px) {
    .pub-footer-grid { grid-template-columns: 1fr; gap: 1.5rem; }
}

.pub-step-indicator { display: flex; gap: .5rem; margin-bottom: 1.5rem; font-size: .85rem; color: var(--sos-muted); }
.pub-step-indicator .is-current { color: var(--sos-primary); font-weight: 700; }

/* ---------------------------------------------------------------------
   Admin area — same tokens/theme mechanism again, a bit wider still
   than the public site since dashboards and the calendar benefit from
   the extra room.
   --------------------------------------------------------------------- */

.adm-shell { max-width: 1240px; margin: 0 auto; padding: 0 1rem 4rem; }

/* Milestone 12 — desktop sidebar + slim always-visible top strip. The
   top strip (brand, "+ New booking", "Hi, name", logout, theme toggle)
   is global identity/actions, shown at every width. The page-nav links
   themselves render twice from the same $navItems array (see
   admin/partials/header.php): .adm-sidebar (a vertical column, >=992px)
   and .adm-nav-links-mobile (the original horizontal wrapping bar,
   <992px) — exactly one of the two is ever visible at a given width, so
   mobile stays pixel-identical to Milestone 9a's already-verified 390px
   layout, and the sidebar is purely additive on top of it. */
.adm-topbar {
    display: flex; justify-content: space-between; align-items: center;
    padding: 1.1rem 0; flex-wrap: wrap; gap: .75rem;
    max-width: 1240px; margin: 0 auto; padding-left: 1rem; padding-right: 1rem;
    border-bottom: 1px solid var(--sos-border);
}
.adm-topbar-actions { display: flex; gap: 1.1rem; align-items: center; flex-wrap: wrap; }
.adm-topbar-actions a { color: var(--sos-text); text-decoration: none; font-weight: 500; font-size: .9rem; }
.adm-topbar-actions a:hover { color: var(--sos-primary); }

.adm-nav-links { display: flex; gap: 1.1rem; align-items: center; flex-wrap: wrap; }
.adm-nav-links a { color: var(--sos-text); text-decoration: none; font-weight: 500; font-size: .9rem; }
.adm-nav-links a:hover, .adm-nav-links a.is-active { color: var(--sos-primary); }
.adm-nav-links a.is-active { font-weight: 700; }

.adm-nav-links-mobile {
    padding: .85rem 1rem; margin: 0 auto; max-width: 1240px;
    border-bottom: 1px solid var(--sos-border);
}

.adm-sidebar { display: none; }
.adm-main { min-width: 0; }

@media (min-width: 992px) {
    .adm-nav-links-mobile { display: none; }

    .adm-shell { display: flex; align-items: flex-start; gap: 2rem; }
    .adm-sidebar {
        display: flex; flex-direction: column; gap: .35rem;
        width: 200px; flex: 0 0 200px;
        position: sticky; top: 1.5rem;
        padding-top: 1.5rem;
    }
    .adm-sidebar a {
        padding: .5rem .75rem; border-radius: .5rem;
        color: var(--sos-text); text-decoration: none; font-weight: 500; font-size: .92rem;
    }
    .adm-sidebar a:hover { background: var(--sos-bg); color: var(--sos-primary); }
    .adm-sidebar a.is-active { background: var(--sos-bg); color: var(--sos-primary); font-weight: 700; }

    .adm-main { flex: 1 1 auto; padding-top: 1.5rem; }
}

.adm-stat-card {
    background: var(--sos-surface); border: 1px solid var(--sos-border); border-radius: .9rem;
    padding: 1.1rem; height: 100%; position: relative;
}
.adm-stat-card .adm-stat-value { font-size: 1.7rem; font-weight: 700; color: var(--sos-primary); }
.adm-stat-card .adm-stat-label { color: var(--sos-muted); font-size: .85rem; }
.adm-stat-icon {
    position: absolute; top: 1rem; right: 1rem; font-size: 1.3rem;
    color: color-mix(in srgb, var(--sos-primary) 35%, transparent);
}

.adm-appt-card {
    background: var(--sos-bg); border: 1px solid var(--sos-border); border-radius: .6rem;
    padding: .6rem .7rem; margin-bottom: .5rem; font-size: .85rem;
}
.adm-appt-card .adm-appt-time { font-weight: 700; color: var(--sos-primary); }
.adm-appt-col { min-height: 4rem; }
.adm-appt-col-header { font-weight: 700; display: flex; align-items: center; gap: .4rem; margin-bottom: .6rem; }
.adm-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }

.adm-status-badge { font-size: .7rem; font-weight: 700; padding: .1rem .5rem; border-radius: 1rem; display: inline-block; }
.adm-status-booked, .adm-status-confirmed { background: color-mix(in srgb, var(--sos-accent) 18%, transparent); color: var(--sos-accent); }
.adm-status-completed { background: color-mix(in srgb, var(--sos-success) 18%, transparent); color: var(--sos-success); }
.adm-status-cancelled, .adm-status-no_show { background: color-mix(in srgb, #E11D48 18%, transparent); color: #E11D48; }

/* Milestone 24 — a client's own profile photo, shown wherever the salon
   looks up a specific customer (admin/clients.php's list + detail,
   admin/appointment.php, staff/appointment.php) and on the client's own
   book/account.php. A generic person icon stands in when no photo has
   been uploaded yet, rather than an initial-letter avatar — clients
   (unlike staff) have no assigned colour to draw one from. */
.adm-client-avatar { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.adm-client-avatar-fallback {
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--sos-bg); border: 1px solid var(--sos-border);
    color: var(--sos-muted); font-size: 1.2rem;
}
.adm-client-avatar-lg { width: 64px; height: 64px; font-size: 1.8rem; }

/* Milestone 18 — admin/services.php and admin/staff.php were both switched
   from cramped side-by-side columns to full-width stacked panels, so their
   tables/lists now have real room to breathe. These two classes give every
   row a bit more vertical padding and a subtle divider so the extra width
   reads as "spacious," not just "wide." */
.adm-table-spaced > thead > tr > th,
.adm-table-spaced > tbody > tr > td {
    padding: .9rem 1rem;
}
.adm-table-spaced > tbody > tr:not(:last-child) > td {
    border-bottom: 1px solid var(--sos-border);
}
.adm-list-spaced .list-group-item {
    padding: .85rem .25rem;
}

/* Milestone 18 — a small role pill next to "Hi, {name}" in both the admin
   top strip (admin/partials/header.php, always "Owner") and the staff
   portal's own nav (staff/partials/header.php, the logged-in staff
   member's real role — Manager/Front Desk/Stylist). Sits in the same
   identity strip as the name/logout link on both desktop and mobile,
   since neither .adm-topbar nor .pub-nav is hidden at any breakpoint. */
.adm-role-pill {
    font-size: .7rem;
    font-weight: 700;
    padding: .2rem .65rem;
    border-radius: 1rem;
    background: color-mix(in srgb, var(--sos-primary) 16%, transparent);
    color: var(--sos-primary);
    display: inline-block;
    text-transform: uppercase;
    letter-spacing: .02em;
}

/* Milestone 25 — the client account area (book/account.php "My bookings",
   book/account-photo.php "My photo", book/account-privacy.php "Privacy &
   data") gained a proper sidebar: a vertical .acct-sidebar column, sticky,
   desktop-only (>=992px). Scoped to its own .acct-* classes rather than
   reusing .adm-*, since this sits inside the public site's .pub-shell
   (1080px), not the admin area's wider .adm-shell. Milestone 36 — the
   <992px half of this (a horizontal .acct-nav-links-mobile bar, always
   visible) is gone; mobile now shares the guest nav's burger + off-canvas
   .pub-nav-dropdown panel instead (header.php switches its contents on
   $accountNav) — this sidebar is the only piece left here. */
.acct-sidebar { display: none; }
.acct-main { min-width: 0; }

@media (min-width: 992px) {
    .acct-shell { display: flex; align-items: flex-start; gap: 2rem; }
    .acct-sidebar {
        display: flex; flex-direction: column; gap: .35rem;
        width: 180px; flex: 0 0 180px;
        position: sticky; top: 1.5rem;
    }
    .acct-sidebar a {
        padding: .5rem .75rem; border-radius: .5rem;
        color: var(--sos-text); text-decoration: none; font-weight: 500; font-size: .92rem;
    }
    .acct-sidebar a:hover { background: var(--sos-bg); color: var(--sos-primary); }
    .acct-sidebar a.is-active { background: var(--sos-bg); color: var(--sos-primary); font-weight: 700; }

    .acct-main { flex: 1 1 auto; }
}

/* Milestone 12 (revised) — the staff portal (staff/index.php "My day"/
   "Team calendar", staff/profile.php "My profile") gained the same
   sidebar treatment as the admin area and the client account area
   above: one shared $navItems array (see staff/partials/header.php)
   rendered twice — a horizontal .staff-nav-links row (mobile, <992px)
   and a vertical .staff-sidebar column (desktop, >=992px, sticky) —
   only one of which is ever visible at a given width. The top strip
   (brand + "Staff Portal" label, "Hi, name", role pill, log out, theme
   toggle) stays global identity/actions and is always visible, same
   split as the admin area. Scoped to its own .staff-* classes rather
   than reusing .adm-*/.acct-*, since this sits inside the public
   site's .pub-shell, same reasoning as .acct-* above. */
.staff-nav-links { display: flex; gap: 1.1rem; align-items: center; flex-wrap: wrap; padding-bottom: 1rem; }
.staff-nav-links a { color: var(--sos-text); text-decoration: none; font-weight: 500; font-size: .9rem; }
.staff-nav-links a:hover, .staff-nav-links a.is-active { color: var(--sos-primary); }
.staff-nav-links a.is-active { font-weight: 700; }

.staff-sidebar { display: none; }
.staff-main { min-width: 0; }

@media (min-width: 992px) {
    .staff-nav-links-mobile { display: none; }

    .staff-shell { display: flex; align-items: flex-start; gap: 2rem; }
    .staff-sidebar {
        display: flex; flex-direction: column; gap: .35rem;
        width: 180px; flex: 0 0 180px;
        position: sticky; top: 1.5rem;
    }
    .staff-sidebar a {
        padding: .5rem .75rem; border-radius: .5rem;
        color: var(--sos-text); text-decoration: none; font-weight: 500; font-size: .92rem;
    }
    .staff-sidebar a:hover { background: var(--sos-bg); color: var(--sos-primary); }
    .staff-sidebar a.is-active { background: var(--sos-bg); color: var(--sos-primary); font-weight: 700; }

    .staff-main { flex: 1 1 auto; }
}
