/* Merchant dashboard (/manage) — the platform admin console's design language, ported.

   Two constraints shape every line below.

   1. SCOPED, NOT GLOBAL. These pages live in the same app as the public booking portal, whose
      app.css already owns `.card`, `.alert`, `.eyebrow` and the `--portal-*` token names. Every
      rule here is prefixed `.manage-shell` or `.manage-login-wrap`, which both wins the
      specificity tie (0,2,0 over 0,1,0) and guarantees a customer-facing page can never pick up
      a dashboard style by accident.
   2. SAME LANGUAGE AS THE CONSOLE. The tokens are the console's black/mint values verbatim, and
      the component names (panel · card/card-head/card-body/card-foot · data-table · pill · chip ·
      stack · btn-primary/ghost/danger · callout-warn) are its names, so a change made in one
      surface is obvious to make in the other. This is a management tool for the person who runs
      the salon — dense tables and quiet panels — not the mobile-first funnel its neighbours are. */

.manage-shell,
.manage-login-wrap {
    --portal-bg: #000000;
    --portal-panel: #10161a;
    --portal-surface: #131a1e;
    --portal-item: #131a1e;
    --portal-well: #0a0e0f;
    --portal-thead: #0d1214;
    --portal-border: #263136;
    --portal-border-card: #263136;
    --portal-hairline: #1c2427;
    --portal-text: #f2f5f6;
    --portal-text-body: #d2dadd;
    --portal-text-secondary: #8a9499;
    --portal-text-muted: #8a9499;
    --portal-text-faint: #5a6469;
    --portal-accent: #56d3ac;
    --portal-accent-text: #56d3ac;
    --portal-accent-contrast: #062018;
    --portal-accent-wash: rgba(86, 211, 172, 0.14);
    --portal-accent-wash-soft: rgba(86, 211, 172, 0.08);
    --portal-success: #56d3ac;
    --portal-success-bg: rgba(86, 211, 172, 0.14);
    --portal-success-border: rgba(86, 211, 172, 0.3);
    --portal-error: #e57373;
    --portal-error-bg: #3a1a1a;
    --portal-error-border: #5a2a2a;
    --portal-info: #96bcc4;
    --portal-info-bg: #1d2b2e;
    --portal-info-border: #2d4147;
    --portal-warn: #e8c080;
    --portal-warn-text: #d8c5a0;
    --portal-warn-bg: rgba(232, 192, 128, 0.08);
    --portal-warn-border: rgba(232, 192, 128, 0.25);
    --portal-price: #e8c37e;
    --portal-pink: #e59ab9;
    --portal-purple: #b48ee0;
    --portal-radius: 12px;
    --portal-radius-sm: 10px;
    --portal-ease: cubic-bezier(.4, 0, .2, 1);
    --portal-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

    /* Dark-only, and told to the browser so the parts it paints itself (number spinner, date
       picker, select list, scrollbars) render dark rather than as white boxes in a dark field. */
    color-scheme: dark;
    background: var(--portal-bg);
    color: var(--portal-text-body);
    font-size: 14px;
    line-height: 1.5;
    min-height: 100vh;
}

.manage-shell { display: flex; flex-direction: column; }
.manage-shell *, .manage-login-wrap * { box-sizing: border-box; }

.manage-shell a, .manage-login-wrap a { color: var(--portal-accent-text); text-decoration: none; }
.manage-shell a:hover, .manage-login-wrap a:hover { text-decoration: underline; }
.manage-shell button, .manage-login-wrap button { font-family: inherit; cursor: pointer; }

.manage-shell h1, .manage-login-wrap h1 {
    font-size: 28px; font-weight: 700; letter-spacing: -0.7px; line-height: 1.15;
    margin: 0 0 4px; color: var(--portal-text);
}
.manage-shell h2 { font-size: 18px; font-weight: 700; margin: 0 0 8px; color: var(--portal-text); }
.manage-shell h3 { color: var(--portal-text); }

.manage-shell .muted, .manage-login-wrap .muted { color: var(--portal-text-muted); }
.manage-shell .small, .manage-login-wrap .small { font-size: 12px; }
.manage-shell .mono { font-family: var(--portal-mono); font-size: 13px; }
.manage-shell .value-warn { color: var(--portal-warn); }
.manage-shell .value-good { color: var(--portal-accent-text); }

/* ── Header ──────────────────────────────────────────────────
   Sticky like the console's, but two rows: the dashboard's nav is nine items wide and a salon
   owner opens this on a laptop, so the links get their own line rather than being crushed in
   beside the shop switcher. */
.manage-shell .manage-header {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--portal-well);
    border-bottom: 1px solid var(--portal-hairline);
}

.manage-shell .manage-header-inner {
    max-width: 1180px;
    min-height: 56px;
    margin: 0 auto;
    padding: 8px 20px;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.manage-shell .manage-brand {
    color: var(--portal-text); font-weight: 700; font-size: 15px;
    display: inline-flex; align-items: center; gap: 0.6rem;
}
.manage-shell .manage-brand:hover { text-decoration: none; }
.manage-shell .manage-brand .brand-mark { width: 26px; height: 26px; display: block; border-radius: 7px; }

/* The shop chip is this surface's environment badge: the one thing the person must never be
   unsure of is which salon's takings are on screen. */
.manage-shell .shop-chip {
    display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 14px;
    border-radius: 999px; background: var(--portal-accent-wash);
    color: var(--portal-accent-text); font-size: 13px; font-weight: 600;
}
.manage-shell .shop-chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.manage-shell .shop-switcher { display: inline-flex; gap: 8px; align-items: center; }
.manage-shell .shop-switcher select { height: 32px; font-size: 13px; padding: 0 10px; max-width: 300px; }

.manage-shell .manage-user {
    display: flex; align-items: center; gap: 8px; font-size: 13.5px;
    margin-left: auto; padding-left: 18px;
    border-left: 1px solid var(--portal-hairline);
    min-height: 32px;
}
.manage-shell .manage-user .muted { color: var(--portal-text-body); }
.manage-shell .manage-user .btn-link { color: var(--portal-text-secondary); font-size: 13.5px; }
.manage-shell .manage-user .btn-link:hover { color: var(--portal-text); text-decoration: none; }

.manage-shell .avatar-initial {
    flex: none; width: 24px; height: 24px; border-radius: 50%;
    display: grid; place-items: center;
    font-size: 11px; font-weight: 700; text-transform: uppercase;
    background: var(--portal-accent-wash); color: var(--portal-accent-text);
}
.manage-shell .avatar-initial-lg { width: 34px; height: 34px; font-size: 13px; }

/* Nav row: the console's pill links, on their own line, scrolling sideways on a phone rather
   than wrapping into a block that pushes the page down. */
.manage-shell .manage-nav-row { border-top: 1px solid var(--portal-hairline); }
.manage-shell .manage-nav {
    max-width: 1180px; margin: 0 auto; padding: 6px 20px;
    display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none;
}
.manage-shell .manage-nav::-webkit-scrollbar { display: none; }
.manage-shell .manage-nav a {
    display: inline-flex; align-items: center; height: 32px; padding: 0 14px;
    border-radius: 8px; font-size: 14px; font-weight: 600; white-space: nowrap;
    color: var(--portal-text-secondary);
    transition: color 0.15s var(--portal-ease), background 0.15s var(--portal-ease);
}
.manage-shell .manage-nav a:hover { color: var(--portal-text); text-decoration: none; }
.manage-shell .manage-nav a.active { color: var(--portal-accent-text); background: var(--portal-accent-wash); }

.manage-shell .manage-main { flex: 1; max-width: 1180px; width: 100%; margin: 0 auto; padding: 32px 20px 56px; }

.manage-shell .manage-footer {
    border-top: 1px solid var(--portal-hairline);
    padding: 14px 20px; text-align: center;
    font-size: 12px; color: var(--portal-text-faint);
}

/* ── Page head ───────────────────────────────────────────── */
.manage-shell .page-head { margin-bottom: 22px; }
.manage-shell .page-eyebrow {
    display: block; font-size: 11px; font-weight: 700; letter-spacing: 1.2px;
    text-transform: uppercase; color: var(--portal-text-faint); margin-bottom: 8px;
}
.manage-shell .page-title-row { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.manage-shell .page-title-row h1 { margin: 0; }
.manage-shell .page-count { font-size: 13.5px; color: var(--portal-text-secondary); }
.manage-shell .page-lead { margin: 10px 0 0; max-width: 78ch; color: var(--portal-text-secondary); }

/* ── Panels and cards ────────────────────────────────────── */
.manage-shell .panel {
    background: var(--portal-panel); border: 1px solid var(--portal-border);
    border-radius: var(--portal-radius); padding: 20px; margin-bottom: 20px;
}
.manage-shell .panel.narrow { max-width: 520px; }

.manage-shell .card {
    background: var(--portal-panel); border: 1px solid var(--portal-border);
    border-radius: var(--portal-radius); margin-bottom: 20px; overflow: hidden;
}
.manage-shell .card-head {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
    padding: 18px 22px; border-bottom: 1px solid var(--portal-hairline);
}
.manage-shell .card-head .eyebrow {
    display: block; margin-bottom: 6px;
    font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--portal-text-secondary);
}
.manage-shell .card-head h2 { margin: 0; }
.manage-shell .card-body { padding: 22px; }
.manage-shell .card-body > :first-child { margin-top: 0; }
.manage-shell .card-body > p { margin: 0 0 18px; line-height: 1.55; max-width: 78ch; }
.manage-shell .card-body > p:last-child { margin-bottom: 0; }
.manage-shell .card-body p strong { color: var(--portal-text); }
.manage-shell .card-foot {
    display: flex; justify-content: flex-end; align-items: center; gap: 12px;
    padding: 16px 22px; background: var(--portal-surface);
    border-top: 1px solid var(--portal-hairline);
}
.manage-shell .card-foot-split { justify-content: space-between; }
.manage-shell .card-foot .btn-primary { align-self: auto; }

/* The "how to read this" strip under a table or a form — where the rule that is not obvious from
   the screen gets said, in the console's own voice. */
.manage-shell .card-info {
    display: flex; gap: 12px; align-items: flex-start;
    padding: 16px 22px; background: var(--portal-well);
    border-top: 1px solid var(--portal-hairline);
    font-size: 12.5px; line-height: 1.55; color: var(--portal-text-secondary);
}
.manage-shell .card-info p { margin: 0; max-width: 88ch; }
.manage-shell .card-info p + p { margin-top: 8px; }
.manage-shell .card .table-scroll { border: none; border-radius: 0; background: transparent; }
/* A card that is nothing but an explanation strip: its own border already draws the top edge, so
   the strip must not draw a second hairline a pixel below it. */
.manage-shell .card > .card-info:first-child { border-top: none; }

.manage-shell .glyph {
    flex: none; width: 18px; height: 18px; margin-top: 1px; border-radius: 50%;
    display: grid; place-items: center;
    font-size: 11px; font-weight: 700; line-height: 1;
    border: 1px solid currentColor;
    font-family: Georgia, "Times New Roman", serif;
}
.manage-shell .glyph-info { color: var(--portal-accent-text); }
.manage-shell .glyph-warn { color: var(--portal-warn); }

.manage-shell .callout-warn {
    display: flex; gap: 12px; align-items: flex-start;
    padding: 16px 18px; margin-bottom: 20px;
    border-radius: var(--portal-radius-sm);
    background: var(--portal-warn-bg); border: 1px solid var(--portal-warn-border);
    color: var(--portal-warn-text); font-size: 13px; line-height: 1.6;
}
.manage-shell .callout-warn p { margin: 0; color: inherit; max-width: 82ch; }
.manage-shell .callout-warn p + p { margin-top: 8px; }
.manage-shell .callout-warn strong { color: var(--portal-warn); }
.manage-shell .card-body > .callout-warn:last-child { margin-bottom: 0; }

/* Two columns that collapse early — this is a laptop screen, and a panel squeezed to 200px is
   worse than the same panel below the thing it describes. */
.manage-shell .col-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; align-items: start; }
@media (max-width: 900px) { .manage-shell .col-2 { grid-template-columns: minmax(0, 1fr); } }

/* ── Alerts ──────────────────────────────────────────────── */
.manage-shell .alert, .manage-login-wrap .alert {
    border-radius: var(--portal-radius-sm); padding: 12px 14px; margin: 0 0 16px;
    font-size: 13.5px; line-height: 1.5; border: 1px solid;
}
.manage-shell .alert-error, .manage-login-wrap .alert-error {
    background: var(--portal-error-bg); border-color: var(--portal-error-border); color: var(--portal-error);
}
.manage-shell .alert-success, .manage-login-wrap .alert-success {
    background: var(--portal-success-bg); border-color: var(--portal-success-border); color: var(--portal-success);
}
.manage-shell .alert-info, .manage-login-wrap .alert-info {
    background: var(--portal-info-bg); border-color: var(--portal-info-border); color: var(--portal-info);
}
.manage-shell .alert-warn {
    background: var(--portal-warn-bg); border-color: var(--portal-warn-border); color: var(--portal-warn);
}
.manage-shell .alert a, .manage-login-wrap .alert a { color: inherit; text-decoration: underline; }
/* A sign-out button inside an alert sentence (the stale-session banner) reads as part of it. */
.manage-shell .alert .inline-form { display: inline; }
.manage-shell .alert .inline-form .btn-link { color: inherit; text-decoration: underline; font-size: inherit; padding: 0; }

/* ── Add someone who works elsewhere (Staff) ─────────────── */
.manage-shell .add-existing-row {
    display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
    padding: 10px 0; border-top: 1px solid var(--portal-hairline);
}
.manage-shell .add-existing-row:first-of-type { border-top: 0; }
.manage-shell .add-existing-row .person { flex: 0 0 220px; display: flex; align-items: center; gap: 8px; }
.manage-shell .add-existing-row .muted { flex: 1 1 160px; }
.manage-shell .add-existing-row select { width: auto; }
.manage-shell .add-existing-find { align-items: flex-end; }
.manage-shell .add-existing-find label { display: flex; flex-direction: column; gap: 4px; flex: 1 1 260px; }
.manage-shell .find-refusal { color: var(--portal-error); font-size: 13px; margin: 8px 0 0; }

/* ── Stat cards ──────────────────────────────────────────── */
.manage-shell .stat-cards {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 12px; margin-bottom: 20px;
}
.manage-shell .stat-card {
    display: flex; flex-direction: column; gap: 3px; padding: 16px 18px;
    border: 1px solid var(--portal-border); border-radius: var(--portal-radius-sm);
    background: var(--portal-panel);
}
.manage-shell .stat-label {
    font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--portal-text-secondary);
}
.manage-shell .stat-value {
    font-size: 1.7rem; line-height: 1.15; font-weight: 600;
    font-variant-numeric: tabular-nums; color: var(--portal-text);
}
.manage-shell .stat-sub { font-size: 12.5px; color: var(--portal-text-faint); }
.manage-shell .stat-card-accent .stat-value { color: var(--portal-accent-text); }

/* ── Tables ──────────────────────────────────────────────── */
.manage-shell .table-scroll {
    overflow-x: auto; border: 1px solid var(--portal-border);
    border-radius: var(--portal-radius); background: var(--portal-panel);
    margin-bottom: 20px;
}
.manage-shell .card .table-scroll { margin-bottom: 0; }

.manage-shell .data-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.manage-shell .data-table th, .manage-shell .data-table td {
    text-align: left; padding: 13px 20px;
    border-bottom: 1px solid var(--portal-hairline);
    vertical-align: middle; white-space: nowrap;
}
.manage-shell .data-table thead th {
    font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--portal-text-secondary); background: var(--portal-thead);
}
.manage-shell .data-table tbody tr:last-child td { border-bottom: none; }

/* Sortable headings (admin.js marks them): a pointer, a hover, and an arrow for the sorted one. */
.manage-shell .data-table thead th[data-sortable] { cursor: pointer; user-select: none; }
.manage-shell .data-table thead th[data-sortable]:hover, .manage-shell .data-table thead th[data-sortable]:focus-visible { color: var(--portal-text); outline: none; }
.manage-shell .data-table thead th[data-sortable]::after { content: "↕"; margin-left: 6px; opacity: 0.35; font-size: 10px; }
.manage-shell .data-table thead th[aria-sort="ascending"]::after { content: "↑"; opacity: 1; color: var(--portal-accent-text); }
.manage-shell .data-table thead th[aria-sort="descending"]::after { content: "↓"; opacity: 1; color: var(--portal-accent-text); }
.manage-shell .data-table thead th[aria-sort] { color: var(--portal-text); }
.manage-shell .data-table tbody tr:hover { background: var(--portal-item); }
.manage-shell .data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.manage-shell .data-table .shop-lines { list-style: none; margin: 0; padding: 0; }
.manage-shell .data-table .shop-lines li { white-space: nowrap; line-height: 1.5; }
.manage-shell .data-table .money { font-variant-numeric: tabular-nums; color: var(--portal-text); }
.manage-shell .data-table td.mono { font-size: 13.5px; }
/* A cancelled or no-showed booking is grey, not red: it is a normal state of the day. */
.manage-shell .row-muted td { opacity: 0.55; }
/* The import review's "Importing would…" column: the one cell a person READS, so it wraps
   instead of running off the right edge behind the scroll. Wide enough for a refusal sentence. */
.manage-shell .data-table td.verdict { white-space: normal; min-width: 260px; max-width: 440px; line-height: 1.45; }
.manage-shell .data-table td.verdict .pill { margin-bottom: 4px; }
.manage-shell .table-caption {
    font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--portal-text-secondary); padding: 16px 20px 6px; margin: 0;
}
.manage-shell .table-caption + .data-table thead th { border-top: 1px solid var(--portal-hairline); }

.manage-shell .person { display: flex; align-items: center; gap: 11px; }
.manage-shell .person-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 0.92rem; color: var(--portal-text); }

/* ── Pills ───────────────────────────────────────────────── */
.manage-shell .pill {
    display: inline-block; font-size: 0.7rem; letter-spacing: 0.04em; text-transform: uppercase;
    padding: 2px 7px; border-radius: 999px;
    border: 1px solid var(--portal-border-card); color: var(--portal-text-muted);
}
.manage-shell .pill-live, .manage-shell .pill-active {
    border-color: var(--portal-success-border); background: var(--portal-success-bg); color: var(--portal-success);
}
.manage-shell .pill-off { border-color: var(--portal-border-card); color: var(--portal-text-muted); }
.manage-shell .pill-warn { border-color: var(--portal-warn-border); background: var(--portal-warn-bg); color: var(--portal-warn); }
.manage-shell .pill-danger { border-color: var(--portal-error-border); background: var(--portal-error-bg); color: var(--portal-error); }
/* Role colours match the console's exactly, so a level reads the same in both tools. */
.manage-shell .pill-owner { border-color: var(--portal-success-border); color: var(--portal-success); }
.manage-shell .pill-manager { border-color: var(--portal-info-border); color: var(--portal-info); }
.manage-shell .pill-technician { border-color: #5a4a2a; color: var(--portal-warn); }
.manage-shell .pill-viewer { border-color: var(--portal-border-card); color: var(--portal-text-muted); }
.manage-shell .pill-role { border-color: var(--portal-info-border); color: var(--portal-info); }

.manage-shell .pill-status {
    display: inline-flex; align-items: center; gap: 7px; height: 24px; padding: 0 10px;
    border-radius: 999px; font-size: 12.5px; font-weight: 600;
    background: var(--portal-accent-wash); color: var(--portal-accent-text);
}
.manage-shell .pill-status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.manage-shell .pill-status-off { background: var(--portal-hairline); color: var(--portal-text-secondary); }
.manage-shell .pill-status-warn { background: var(--portal-warn-bg); color: var(--portal-warn); }

/* ── Chips ───────────────────────────────────────────────── */
.manage-shell .chip-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.manage-shell .chip {
    display: inline-flex; align-items: baseline; gap: 6px;
    font-size: 0.82rem; padding: 6px 12px; border-radius: 999px;
    border: 1px solid var(--portal-border-card); background: var(--portal-item);
    color: var(--portal-text-muted);
}
.manage-shell .chip strong { color: var(--portal-text); font-variant-numeric: tabular-nums; }
.manage-shell .chip-btn { color: var(--portal-text-body); }
.manage-shell .chip-btn:hover { border-color: var(--portal-text-muted); text-decoration: none; }
.manage-shell .chip-on { border-color: var(--portal-accent); color: var(--portal-accent-text); background: transparent; }

/* ── Forms ───────────────────────────────────────────────── */
.manage-shell .stack, .manage-login-wrap .stack { display: flex; flex-direction: column; gap: 20px; }
.manage-shell .card-body .stack { margin-top: 0; }
.manage-shell .stack label, .manage-login-wrap .stack label {
    display: flex; flex-direction: column; gap: 8px;
    font-size: 12.5px; font-weight: 600; color: var(--portal-text-secondary);
}
.manage-shell .stack label > span, .manage-login-wrap .stack label > span { color: var(--portal-text-secondary); }
.manage-shell .stack hr { border: 0; border-top: 1px solid var(--portal-hairline); margin: 0; }

.manage-shell .stack h3 {
    font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--portal-text-muted);
    border-top: 1px solid var(--portal-border);
    padding-top: 14px; margin: 6px 0 -4px;
}
.manage-shell .stack h3.section-first { border-top: 0; padding-top: 0; margin-top: 0; }

/* Two fields side by side, stacking when narrow. */
.manage-shell .field-row { display: flex; gap: 16px; flex-wrap: wrap; }
.manage-shell .field-row > label { flex: 1 1 220px; }
.manage-shell .field-narrow input { max-width: 180px; }
/* The staff record's "Shown as Tina Nguyen" line beside the Preferred name box — sits on the input's baseline, never a full-width paragraph. */
.manage-shell .display-name-preview { flex: 1 1 220px; align-self: flex-end; margin: 0 0 10px; }

.manage-shell input:not([type]), .manage-shell input[type="text"], .manage-shell input[type="password"],
.manage-shell input[type="email"], .manage-shell input[type="tel"], .manage-shell input[type="url"],
.manage-shell input[type="number"], .manage-shell input[type="date"], .manage-shell input[type="search"],
.manage-shell select,
.manage-login-wrap input:not([type]), .manage-login-wrap input[type="text"], .manage-login-wrap input[type="password"] {
    font-family: inherit; font-size: 14.5px; height: 46px; padding: 0 14px;
    border-radius: var(--portal-radius-sm); border: 1px solid var(--portal-border-card);
    background: var(--portal-surface); color: var(--portal-text); width: 100%;
    transition: border-color 0.15s var(--portal-ease);
    /* Mobile Safari paints its own inset textfield chrome inside our border unless told not to —
       on an iPad every field read as two borders. Selects opt back in below (keeps the arrow). */
    -webkit-appearance: none; appearance: none;
}
.manage-shell select { appearance: auto; padding: 0 12px; }
/* iOS collapses a date field to nothing under appearance:none; it keeps the native picker. */
.manage-shell input[type="date"] { -webkit-appearance: auto; appearance: auto; }
.manage-shell input:focus-visible, .manage-shell select:focus-visible,
.manage-login-wrap input:focus-visible { outline: none; border-color: var(--portal-accent); }
.manage-shell input[type="date"]::-webkit-calendar-picker-indicator { cursor: pointer; }
.manage-shell input[type="checkbox"], .manage-shell input[type="radio"] {
    width: 16px; height: 16px; accent-color: var(--portal-accent);
}
.manage-shell input:disabled { opacity: 0.55; }

.manage-shell textarea {
    font-family: inherit; font-size: 14.5px; line-height: 1.5; padding: 12px 14px;
    border-radius: var(--portal-radius-sm); border: 1px solid var(--portal-border-card);
    background: var(--portal-surface); color: var(--portal-text); width: 100%; resize: vertical;
    transition: border-color 0.15s var(--portal-ease);
}
.manage-shell textarea:focus-visible { outline: none; border-color: var(--portal-accent); }
.manage-shell textarea::placeholder { color: var(--portal-text-faint); }
.manage-shell textarea.mono-area { font-family: var(--portal-mono); font-size: 12.5px; white-space: pre; overflow-x: auto; }

/* A file picker that looks like the rest of the form: the zone is the field, the browser's own
   button is restyled through ::file-selector-button. The input stays a plain input — no JS, the
   form posts multipart exactly as before. */
.manage-shell .file-drop-zone {
    display: flex; flex-direction: column; gap: 8px;
    padding: 18px; border-radius: var(--portal-radius-sm);
    border: 1px dashed var(--portal-border-card); background: var(--portal-surface);
    transition: border-color 0.15s var(--portal-ease);
}
.manage-shell .file-drop-zone:focus-within { border-color: var(--portal-accent); }
.manage-shell .file-drop-zone input[type="file"] { color: var(--portal-text-body); font-size: 13.5px; font-family: inherit; }
.manage-shell .file-drop-zone input[type="file"]::file-selector-button {
    font: inherit; font-weight: 600; font-size: 13px; cursor: pointer;
    height: 34px; padding: 0 14px; margin-right: 12px;
    border-radius: 999px; border: 1px solid var(--portal-border-card);
    background: var(--portal-panel); color: var(--portal-text);
}
.manage-shell .file-drop-zone input[type="file"]::file-selector-button:hover { border-color: var(--portal-accent); color: var(--portal-accent-text); }
.manage-shell .file-drop-hint { font-size: 12px; color: var(--portal-text-faint); font-weight: 400; }

/* "or" between two ways of doing the same thing. */
.manage-shell .or-rule {
    display: flex; align-items: center; gap: 12px;
    font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--portal-text-faint);
}
.manage-shell .or-rule::before, .manage-shell .or-rule::after { content: ""; flex: 1; border-top: 1px solid var(--portal-hairline); }

/* Radio cards: one choice among a few, each explained where it is chosen rather than in a
   paragraph underneath. The dot stays visible, so the cards read without :has() support. */
.manage-shell .choice-set { border: 0; padding: 0; margin: 0; min-width: 0; }
.manage-shell .choice-set legend {
    padding: 0; margin-bottom: 10px;
    font-size: 12.5px; font-weight: 600; color: var(--portal-text-secondary);
}
.manage-shell .choice-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; }
.manage-shell .choice-card, .manage-shell .stack label.choice-card {
    display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: start;
    padding: 14px 16px; border-radius: var(--portal-radius-sm);
    border: 1px solid var(--portal-border-card); background: var(--portal-surface);
    cursor: pointer; font-weight: 400;
    transition: border-color 0.15s var(--portal-ease), background 0.15s var(--portal-ease);
}
.manage-shell .choice-card:hover { border-color: var(--portal-text-faint); }
.manage-shell .choice-card:has(input:checked) { border-color: var(--portal-accent); background: var(--portal-accent-wash-soft); }
.manage-shell .choice-card:has(input:focus-visible) { outline: 2px solid var(--portal-accent); outline-offset: 2px; }
.manage-shell .choice-card input[type="radio"] { margin-top: 3px; }
.manage-shell .choice-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.manage-shell .choice-title { font-size: 14.5px; font-weight: 600; color: var(--portal-text); }
.manage-shell .choice-desc { font-size: 12.5px; line-height: 1.45; color: var(--portal-text-secondary); }
.manage-shell .choice-sample {
    margin-top: 4px; font-family: var(--portal-mono); font-size: 11.5px;
    color: var(--portal-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* The explanatory line under a field. Not a title attribute — the reason a setting exists is the
   part somebody needs while reading it, not on hover. */
.manage-shell .hint { color: var(--portal-text-faint); font-size: 12px; font-weight: 400; line-height: 1.45; }
.manage-shell .stack > p.hint { margin: 0; max-width: 66ch; }

.manage-shell label.check {
    display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 4px 9px;
    font-size: 13.5px; font-weight: 400;
}
.manage-shell label.check > span { color: var(--portal-text); font-weight: 500; }
.manage-shell label.check .hint { grid-column: 2; }
/* A checkbox sitting inside a button row (the no-show confirm's "text them a rebook link"). */
.manage-shell label.check-inline { display: inline-flex; align-items: center; gap: 6px; margin-right: 8px; }

.manage-shell .req { color: var(--portal-error); font-weight: 600; }

/* A filter/search row: everything on it matches the input's 46px so the row reads as one piece. */
.manage-shell .searchbar { display: flex; gap: 10px; align-items: flex-end; margin: 0 0 20px; flex-wrap: wrap; }
/* Same label dress as a field inside a .stack — the bar is not one, so it has to say it itself,
   or "Day" renders as bare body text beside inputs that are clearly labelled everywhere else. */
.manage-shell .searchbar label {
    flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px;
    font-size: 12.5px; font-weight: 600; color: var(--portal-text-secondary);
}
.manage-shell .searchbar input { max-width: 220px; }
.manage-shell .searchbar .btn-primary, .manage-shell .searchbar .btn-ghost { height: 46px; }

.manage-shell .form-actions {
    display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.manage-shell .btn-row { display: flex; gap: 10px; align-items: center; }

/* ── Buttons ─────────────────────────────────────────────── */
.manage-shell .btn-primary, .manage-login-wrap .btn-primary {
    align-self: flex-start; display: inline-flex; align-items: center; justify-content: center;
    height: 40px; font-size: 13.5px; font-weight: 700; padding: 0 18px;
    border: none; border-radius: var(--portal-radius-sm);
    background: var(--portal-accent); color: var(--portal-accent-contrast);
    transition: opacity 0.15s var(--portal-ease);
}
.manage-shell .btn-primary:hover, .manage-login-wrap .btn-primary:hover { opacity: 0.85; }
/* Disabled is the state manage.js puts a save button in when nothing has been edited. It must
   still read as a button, not as broken. */
.manage-shell .btn-primary:disabled { background: var(--portal-hairline); color: var(--portal-text-faint); cursor: default; opacity: 1; }

.manage-shell .btn-ghost {
    display: inline-flex; align-items: center; justify-content: center;
    height: 40px; font-size: 13.5px; font-weight: 700; padding: 0 16px;
    border: 1px solid var(--portal-border-card); border-radius: var(--portal-radius-sm);
    background: var(--portal-surface); color: var(--portal-text);
    transition: opacity 0.15s var(--portal-ease), border-color 0.15s var(--portal-ease);
}
.manage-shell .btn-ghost:hover { border-color: var(--portal-text-secondary); text-decoration: none; opacity: 0.85; }

.manage-shell .btn-danger {
    font-family: inherit; display: inline-flex; align-items: center; justify-content: center;
    height: 40px; font-size: 13.5px; font-weight: 700; padding: 0 16px;
    border: 1px solid var(--portal-error-border); border-radius: var(--portal-radius-sm);
    background: var(--portal-error-bg); color: var(--portal-error);
}
.manage-shell .btn-danger:hover { filter: brightness(1.15); text-decoration: none; }

.manage-shell .btn-sm { height: 32px; font-size: 0.8rem; padding: 0 12px; }

.manage-shell .btn-link, .manage-login-wrap .btn-link {
    background: none; border: none; padding: 0;
    font-size: 13.5px; color: var(--portal-accent-text); text-decoration: none;
}
.manage-shell .btn-link:hover, .manage-login-wrap .btn-link:hover { text-decoration: underline; }

.manage-shell .cell-actions { text-align: right; white-space: nowrap; }
.manage-shell .row-actions { white-space: nowrap; }
.manage-shell .row-actions form { display: inline; }
.manage-shell .row-actions > * + * { margin-left: 10px; }
.manage-shell .inline-confirm { display: inline-flex; gap: 8px; align-items: center; }

/* ── Key/value list ──────────────────────────────────────── */
.manage-shell .kv { margin: 0; }
.manage-shell .kv-row {
    display: flex; justify-content: space-between; gap: 16px;
    padding: 11px 0; border-bottom: 1px solid var(--portal-hairline); font-size: 0.9rem;
}
.manage-shell .kv-row:first-child { padding-top: 0; }
.manage-shell .kv-row:last-child { border-bottom: none; padding-bottom: 0; }
.manage-shell .kv dt { color: var(--portal-text-muted); }
.manage-shell .kv dd { margin: 0; text-align: right; overflow-wrap: anywhere; color: var(--portal-text); }
.manage-shell .kv .num { font-variant-numeric: tabular-nums; font-weight: 600; }

/* ── Day navigation (bookings) ───────────────────────────── */
.manage-shell .day-nav { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 20px; }
.manage-shell .day-nav .day-label { font-size: 15px; font-weight: 600; color: var(--portal-text); margin: 0 4px; }
.manage-shell .day-nav form { display: flex; gap: 8px; align-items: center; }
.manage-shell .day-nav input[type="date"] { height: 32px; font-size: 13px; padding: 0 10px; width: auto; }

/* ── Row-level editing (the brands table) ────────────────── */
.manage-shell .rows-editable td { vertical-align: middle; }
.manage-shell .rows-editable input:not([type="checkbox"]) { width: 100%; min-width: 90px; height: 34px; padding: 0 10px; font-size: 13px; }
.manage-shell .rows-editable .colour-input { width: 7em; min-width: 6em; }
.manage-shell .rows-editable label.check { font-size: 12.5px; }
.manage-shell .rows-editable select { height: 34px; font-size: 13px; padding: 0 8px; min-width: 110px; }
.manage-shell .rows-editable .w-num { width: 5.5em; min-width: 4.5em; text-align: right; }
.manage-shell .rows-editable .w-money { width: 6.5em; min-width: 5.5em; text-align: right; }
.manage-shell .rows-editable .w-wide { min-width: 160px; }
.manage-shell .rows-editable td.cell-stock { white-space: nowrap; }
.manage-shell .rows-editable td.cell-stock form { display: inline-flex; gap: 6px; align-items: center; }
.manage-shell .rows-editable td.cell-stock .current { font-variant-numeric: tabular-nums; margin-right: 6px; }
.manage-shell .rows-editable td.cell-stock .current.value-warn { font-weight: 600; }
.manage-shell .card-head .btn-ghost { align-self: center; }

/* ── Skills card (staff record) — tick all / by category / by service ── */
.manage-shell .skill-all { padding: 0 0 12px; margin: 0 0 14px; border-bottom: 1px solid var(--portal-border); }
.manage-shell .skill-groups { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.manage-shell fieldset.skill-group { border: 1px solid var(--portal-border); border-radius: 10px; padding: 10px 14px 12px; margin: 0; min-width: 0; }
.manage-shell fieldset.skill-group legend { padding: 0 6px; }
.manage-shell fieldset.skill-group legend label.check > span { font-weight: 600; }
.manage-shell .skill-services { display: flex; flex-direction: column; gap: 6px; padding-left: 24px; }
.manage-shell .skill-services label.check { font-size: 13.5px; }
.manage-shell .skill-services label.check > span { font-weight: 400; }
.manage-shell .skill-readonly { margin: 0; padding-left: 18px; font-size: 13.5px; }
.manage-shell .skill-readonly li + li { margin-top: 4px; }
.manage-shell .colour-chip {
    display: inline-block; width: 14px; height: 14px; border-radius: 4px;
    border: 1px solid var(--portal-border); vertical-align: -2px; margin-right: 8px;
}

/* ── Login ───────────────────────────────────────────────── */
.manage-login-wrap { display: flex; align-items: center; justify-content: center; padding: 6vh 20px; }
.manage-login-panel {
    width: 100%; max-width: 440px; padding: 28px;
    background: var(--portal-panel); border: 1px solid var(--portal-border);
    border-radius: var(--portal-radius);
}
.manage-login-panel h1 { font-size: 24px; }
.manage-login-panel > p { color: var(--portal-text-secondary); line-height: 1.55; }
.manage-login-panel .stack { margin-top: 18px; }
.manage-login-panel .btn-primary { align-self: stretch; }
.manage-login-panel .small-print {
    margin: 20px 0 0; padding-top: 18px; border-top: 1px solid var(--portal-hairline);
    font-size: 12.5px; line-height: 1.6; color: var(--portal-text-faint);
}
.manage-login-panel .small-print strong { color: var(--portal-text-secondary); }

/* Static-SSR focus ring after enhanced navigation — same reasoning as the console's app.css:
   FocusOnNavigate moves focus to the new page's heading so a screen reader announces where it
   landed. Keep the focus, drop the paint nobody can Tab to. */
.manage-shell [tabindex="-1"]:focus, .manage-login-wrap [tabindex="-1"]:focus { outline: none; }

/* ── Roster grid (/manage/roster) ──────────────────────────── */
/* Sized so the whole week — Sunday included — fits the shared 1180px column with no
   horizontal scroll: person column + 7 day columns of ~120px compact chips. */
.manage-shell .roster-grid th, .manage-shell .roster-grid td { padding: 8px 5px; vertical-align: top; }
.manage-shell .roster-grid th:first-child, .manage-shell .roster-grid td:first-child { padding-left: 16px; }
.manage-shell .roster-grid th:last-child, .manage-shell .roster-grid td:last-child { padding-right: 16px; }
.manage-shell .roster-grid th.is-today, .manage-shell .roster-grid td.is-today { background: var(--portal-accent-wash-soft); }
.manage-shell .roster-grid th.is-today { color: var(--portal-accent-text); }
.manage-shell .roster-cell { min-width: 118px; }
.manage-shell .roster-cell .shift-chip {
    display: flex; align-items: center; justify-content: space-between; gap: 6px;
    margin-bottom: 6px; padding: 6px 9px; border-radius: 8px; white-space: nowrap;
    border: 1px solid var(--portal-success-border); background: var(--portal-accent-wash-soft);
    color: var(--portal-text); font-size: 12.5px; font-variant-numeric: tabular-nums;
}
.manage-shell .roster-cell .shift-chip:hover { border-color: var(--portal-accent); text-decoration: none; }
.manage-shell .roster-cell .shift-chip.is-open { border-color: var(--portal-accent); background: var(--portal-accent-wash); }
.manage-shell .roster-cell .shift-pen { color: var(--portal-accent-text); font-size: 0.7rem; }
.manage-shell .roster-cell .shift-add-link {
    display: block; padding: 6px 9px; border-radius: 8px; text-align: center;
    border: 1px dashed var(--portal-border); color: var(--portal-text-muted); font-size: 12.5px;
}
.manage-shell .roster-cell .shift-add-link:hover { border-color: var(--portal-text-secondary); color: var(--portal-text-body); text-decoration: none; }
.manage-shell .btn-xs { height: 28px; min-width: 28px; padding: 0 8px; font-size: 0.8rem; }

/* The shift editor — the panel a tapped shift (or + Add) opens above the grid. Every chip is a
   link that re-renders the page with the new selection, so the whole editor works with no JS. */
.manage-shell .shift-panel { margin-bottom: 20px; }
.manage-shell .shift-panel-head {
    display: flex; justify-content: space-between; align-items: flex-start; gap: 16px;
    padding: 16px 20px 12px; border-bottom: 1px solid var(--portal-hairline);
}
.manage-shell .shift-panel-head h2 { margin: 4px 0 0; font-size: 1.15rem; }
.manage-shell .shift-panel-times { font-size: 1.35rem; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.manage-shell .shift-panel-times .muted { font-size: 0.85rem; font-weight: 400; }
.manage-shell .shift-panel-body { padding: 4px 20px 16px; }
.manage-shell .shift-chip-label { margin: 14px 0 8px; font-size: 0.85rem; color: var(--portal-text-secondary); }
.manage-shell .time-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.manage-shell .time-chip {
    display: inline-flex; align-items: baseline; gap: 8px; padding: 8px 13px; border-radius: 999px;
    border: 1px solid var(--portal-border-card); background: var(--portal-item);
    color: var(--portal-text-body); font-size: 0.85rem; font-variant-numeric: tabular-nums;
}
.manage-shell a.time-chip:hover { border-color: var(--portal-text-muted); text-decoration: none; }
.manage-shell .time-chip.is-picked { border-color: var(--portal-accent); color: var(--portal-accent-text); background: var(--portal-accent-wash-soft); }
.manage-shell .time-chip.is-off { color: var(--portal-text-faint); border-color: var(--portal-hairline); }
.manage-shell .preset-chip span { color: var(--portal-text-muted); }
.manage-shell .preset-chip.is-picked span { color: var(--portal-accent-text); }
.manage-shell .shift-panel-foot {
    display: flex; justify-content: space-between; align-items: center; gap: 12px;
    padding: 12px 20px 16px; border-top: 1px solid var(--portal-hairline);
}
.manage-shell .shift-panel-foot form.inline { display: inline; }
.manage-shell .shift-panel-actions { display: flex; gap: 10px; align-items: center; }
.manage-shell .btn-link-danger {
    background: none; border: none; padding: 0; cursor: pointer;
    color: var(--portal-error); font-size: 0.9rem;
}
.manage-shell .btn-link-danger:hover { text-decoration: underline; }

/* Sales & promotions: item lists several columns wide, and the detail row under a sale. */
.manage-shell .cols { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 4px 16px; }
.manage-shell ul.cols { list-style: none; padding: 0; margin: 8px 0 0; }
.manage-shell tr.row-detail td { padding-top: 0; border-top: 0; }

/* Menu rows: the sale price with its first/last day underneath. */
/* ── Sales & promotions (Menu page) ───────────────────────────────────────────── */
.manage-shell .sale-card .card-head { align-items: center; }
.manage-shell .sale-form { padding: 14px 20px 16px; border-bottom: 1px solid var(--portal-hairline); display: grid; gap: 14px; }
.manage-shell .field-label { display: block; font-size: 0.85rem; color: var(--portal-text-secondary); margin-bottom: 8px; }
.manage-shell .chips { display: flex; flex-wrap: wrap; gap: 8px; }
.manage-shell .scope-chip { position: relative; display: inline-flex; align-items: center; cursor: pointer; }
.manage-shell .scope-chip input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.manage-shell .scope-chip span { display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px; border-radius: 999px; border: 1px solid var(--portal-border-card); color: var(--portal-text-secondary); font-size: 0.9rem; line-height: 1; transition: border-color .15s, color .15s, background .15s; }
.manage-shell .scope-chip span::before { content: "+"; font-weight: 600; opacity: .7; }
.manage-shell .scope-chip input:checked + span { border-color: var(--portal-success-border); background: var(--portal-success-bg, rgba(74, 222, 128, .08)); color: var(--portal-success); }
.manage-shell .scope-chip input:checked + span::before { content: "✓"; opacity: 1; }
.manage-shell .scope-chip input:focus-visible + span { outline: 2px solid var(--portal-info); outline-offset: 2px; }
/* The "Applies to" tree: services column, products column (absent when the shop sells none).
   Columns are capped so a services-only shop gets a snug well, not a stretched empty box. */
.manage-shell .sale-tree { display: grid; grid-template-columns: repeat(auto-fit, minmax(15em, 20em)); justify-content: start; gap: 12px 36px; max-height: 22em; overflow: auto; padding: 12px 14px; border: 1px solid var(--portal-hairline); border-radius: 10px; background: var(--portal-well); }
.manage-shell .tree-col { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.manage-shell .tree-node { display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: 6px; font-size: 0.9rem; color: var(--portal-text); cursor: pointer; line-height: 1.2; }
.manage-shell .tree-node:hover { background: var(--portal-hairline); }
.manage-shell .tree-node input { margin: 0; width: 16px; height: 16px; flex: 0 0 16px; accent-color: var(--portal-success); }
.manage-shell .tree-node span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.manage-shell .tree-node em { font-style: normal; font-size: 0.8rem; color: var(--portal-text-secondary); font-variant-numeric: tabular-nums; }
.manage-shell .tree-node.lvl-0 { font-weight: 600; }
.manage-shell .tree-node.lvl-1 { font-weight: 600; margin-top: 2px; }
.manage-shell .tree-node.lvl-2 { margin-left: 22px; font-weight: 500; margin-top: 4px; }

.manage-shell .tree-col:nth-child(2) .tree-node.lvl-1 { margin-left: 0; }
.manage-shell .menu-table .sale-pick { width: 1%; text-align: center; padding-left: 10px; padding-right: 4px; }
.manage-shell .menu-table td.sale-pick input { width: 16px; height: 16px; margin: 0; accent-color: var(--portal-success); cursor: pointer; }
.manage-shell .sale-scopes > .small { display: block; margin-top: 8px; }
.manage-shell .sale-fields { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; }
.manage-shell .sale-fields label { display: flex; flex-direction: column; gap: 6px; font-size: 0.85rem; color: var(--portal-text-secondary); }
.manage-shell .sale-fields label.grow { flex: 1 1 14em; }
.manage-shell .sale-fields .w-num { width: 6em; }
.manage-shell .sale-fields .btn-primary { align-self: flex-end; height: 46px; margin: 0; }
/* When each sale runs, on one date axis. Bars are SVG rects (the CSP allows no inline style). */
.manage-shell .undo-bar { margin: 0 0 12px; }
.manage-shell .sale-timeline { display: grid; grid-template-columns: minmax(8em, 14em) 1fr; gap: 0 14px; padding: 12px 20px 4px; align-items: start; }
.manage-shell .tl-names { display: flex; flex-direction: column; }
.manage-shell .tl-names span { height: 22px; line-height: 22px; font-size: 0.82rem; color: var(--portal-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.manage-shell .tl-chart svg { display: block; width: 100%; background: var(--portal-hairline); border-radius: 6px; }
.manage-shell .tl-bar.tl-running { fill: var(--portal-warn, #d9a441); }
.manage-shell .tl-bar.tl-scheduled { fill: var(--portal-text-muted); opacity: .55; }
.manage-shell .tl-today { fill: var(--portal-success); opacity: .9; }
.manage-shell .tl-axis { display: flex; justify-content: space-between; margin-top: 2px; }
.manage-shell .tl-key { color: var(--portal-success); }
.manage-shell .sale-list { list-style: none; margin: 0; padding: 10px 20px 14px; display: grid; gap: 8px; }
.manage-shell .sale-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; padding: 10px 14px; border-radius: 10px; background: var(--portal-item); border: 1px solid var(--portal-hairline); }
.manage-shell .sale-list .sale-end { margin-left: auto; }
.manage-shell .pill-sale { border-color: transparent; background: rgba(245, 158, 11, .18); color: #f4b84a; font-weight: 600; }
.manage-shell .btn-link { background: none; border: 0; padding: 0; color: var(--portal-info); cursor: pointer; font: inherit; }
.manage-shell .btn-link.danger { color: var(--portal-error, #f87171); }
.manage-shell .btn-link:hover { text-decoration: underline; }

/* Menu rows */
.manage-shell .menu-table .group-row td { padding: 9px 16px 8px; font-size: 0.72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--portal-success); background: var(--portal-thead); border-bottom: 1px solid var(--portal-hairline); }
.manage-shell .rows-editable .sale-cell { white-space: nowrap; }
.manage-shell .rows-editable .sale-cell > * { vertical-align: middle; margin-right: 5px; }
.manage-shell .rows-editable .sale-cell .w-pct { width: 3.4em; min-width: 0; text-align: right; padding: 6px 6px; }
.manage-shell .rows-editable .sale-cell .sale-now { color: var(--portal-success); font-weight: 600; font-variant-numeric: tabular-nums; }
.manage-shell .btn-x { background: none; border: 0; color: var(--portal-text-muted); cursor: pointer; font-size: 0.85rem; padding: 2px 4px; border-radius: 4px; }
.manage-shell .btn-x:hover { color: var(--portal-error, #f87171); background: var(--portal-hairline); }
.manage-shell .rows-editable .sale-window { white-space: nowrap; }
.manage-shell .rows-editable .sale-window input[type="date"] { display: block; width: 9.5em; min-width: 0; font-size: 0.8rem; padding: 4px 6px; }
.manage-shell .rows-editable .sale-window input[type="date"] + input[type="date"] { margin-top: 4px; }
.manage-shell .money-in { display: inline-flex; align-items: center; gap: 4px; }
.manage-shell .money-in .cur { color: var(--portal-text-muted); font-size: 0.85rem; }
.manage-shell .menu-table { table-layout: auto; }
/* Every page shares the one 1180px column, so the row editor earns its width by being compact:
   tighter cell padding, 30px controls, and no repeat of the ordinary price in the sale cell. */
.manage-shell .menu-table th, .manage-shell .menu-table td { padding: 10px 6px; }
.manage-shell .menu-table th:first-child, .manage-shell .menu-table td:first-child { padding-left: 16px; }
.manage-shell .menu-table th:last-child, .manage-shell .menu-table td:last-child { padding-right: 16px; }
.manage-shell .menu-table input:not([type="checkbox"]), .manage-shell .menu-table select { height: 30px; font-size: 12.5px; }
.manage-shell .menu-table td:nth-child(2) { width: 99%; }
.manage-shell .menu-table td:nth-child(2) input[name="name"] { width: 100%; min-width: 8em; }
.manage-shell .menu-table select[name="category"] { max-width: 10.5em; min-width: 0; }
/* The services table has fewer columns, so its category select can afford a readable width;
   the products table (11 columns) sizes its own to the names it actually holds. */
.manage-shell #services .menu-table select[name="category"] { min-width: 9.5em; }
.manage-shell .menu-table th { white-space: nowrap; }
.manage-shell .menu-table .sale-window input[type="date"] { width: 8.8em; min-width: 8.8em; height: 28px; }
.manage-shell .menu-table .btn-ghost.btn-sm { height: 30px; padding: 0 10px; font-size: 12px; }
.manage-shell .menu-table .cell-stock .w-num { width: 4em; min-width: 4em; }
.manage-shell .menu-table .cell-actions .btn-ghost { white-space: nowrap; }
/* Min · Price · On-sale % share one width; the row rule's 90px floor does not apply here. */
.manage-shell .menu-table input.w-num, .manage-shell .menu-table input.w-money, .manage-shell .menu-table .sale-cell input.w-pct { width: 4.4em; min-width: 4.4em; max-width: 4.4em; padding: 0 7px; text-align: right; }
.manage-shell .menu-table input[type="number"].w-num { appearance: textfield; -moz-appearance: textfield; }
.manage-shell .menu-table input[type="number"].w-num::-webkit-inner-spin-button { display: none; }
.manage-shell .menu-table th.show-col, .manage-shell .menu-table td.show-col { width: 1%; white-space: nowrap; text-align: center; }

/* ── End of day (Reports) ─────────────────────────────────────────────────────
   The Z-report page: hero + tiles lead, payment bars, per-technician table,
   the trading-through-the-day chart and the top-services list. */

.manage-shell .report-status { display: flex; align-items: center; gap: 12px; margin-top: 8px; flex-wrap: wrap; }
.manage-shell .report-chip {
    display: inline-flex; align-items: center; gap: 7px; padding: 4px 12px;
    border: 1px solid var(--portal-success-border); border-radius: 999px;
    background: var(--portal-success-bg); color: var(--portal-accent-text); font-size: 12.5px;
}
.manage-shell .report-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--portal-accent); }
.manage-shell .report-status-text { font-size: 13px; color: var(--portal-text-secondary); }

.manage-shell .report-toolbar { display: flex; align-items: center; gap: 8px; margin: 0 0 20px; flex-wrap: wrap; }
.manage-shell .report-toolbar-gap { flex: 1; }
.manage-shell .report-datebox { display: flex; gap: 8px; align-items: center; }
.manage-shell .report-datebox input[type="date"] { height: 38px; width: auto; }
.manage-shell .report-toolbar .btn-ghost, .manage-shell .report-toolbar .btn-primary { height: 38px; padding: 0 14px; display: inline-flex; align-items: center; }
/* display:inline-flex above would defeat the hidden attribute (the no-JS Print button). */
.manage-shell .report-toolbar [hidden] { display: none; }
.manage-shell .report-toolbar .btn-icon { padding: 0 13px; font-size: 17px; }

.manage-shell .report-lead { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: 20px; align-items: start; margin-bottom: 20px; }
@media (max-width: 1000px) { .manage-shell .report-lead { grid-template-columns: minmax(0, 1fr); } }
.manage-shell .report-hero { padding: 20px 22px; margin-bottom: 0; }
.manage-shell .report-hero-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 2px 0; }
.manage-shell .report-hero-value {
    font-size: 2.6rem; font-weight: 650; line-height: 1.1; letter-spacing: -0.01em;
    color: var(--portal-accent-text); font-variant-numeric: tabular-nums;
}
.manage-shell .report-hero-sub { font-size: 13px; color: var(--portal-text-secondary); }
.manage-shell .delta-badge {
    padding: 4px 11px; border-radius: 999px; white-space: nowrap; font-size: 12.5px;
    background: var(--portal-success-bg); border: 1px solid var(--portal-success-border); color: var(--portal-accent-text);
}
.manage-shell .delta-badge.is-down { background: var(--portal-warn-bg); border-color: var(--portal-warn-border); color: var(--portal-warn); }

.manage-shell .report-ledger { margin: 18px 0 0; }
.manage-shell .report-ledger > div { display: flex; justify-content: space-between; gap: 16px; padding: 9px 0; border-bottom: 1px solid var(--portal-hairline); }
.manage-shell .report-ledger dt { color: var(--portal-text-body); font-size: 14px; }
.manage-shell .report-ledger dd { margin: 0; font-size: 14px; font-variant-numeric: tabular-nums; color: var(--portal-text); }
.manage-shell .report-ledger dd.is-neg { color: var(--portal-pink); }
.manage-shell .report-ledger dd.is-tip { color: var(--portal-price); }
.manage-shell .report-ledger > .report-ledger-total { border-bottom: none; padding-top: 12px; }
.manage-shell .report-ledger-total dt { color: var(--portal-text); font-weight: 600; }
.manage-shell .report-ledger-total dd { font-weight: 650; }

.manage-shell .report-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; }
.manage-shell .report-tiles .stat-card { min-width: 0; }
.manage-shell .stat-pink { color: var(--portal-pink); }
.manage-shell .stat-tip { color: var(--portal-price); }

.manage-shell .card-aside { font-size: 12.5px; color: var(--portal-text-faint); text-align: right; }

.manage-shell .pay-list { display: flex; flex-direction: column; gap: 16px; }
.manage-shell .pay-line { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; }
.manage-shell .pay-name { font-weight: 600; font-size: 14px; color: var(--portal-text); }
.manage-shell .pay-meta { font-size: 13px; color: var(--portal-text-secondary); white-space: nowrap; }
.manage-shell .pay-meta strong { color: var(--portal-text); font-variant-numeric: tabular-nums; margin-left: 6px; }
.manage-shell .pay-bar { height: 6px; border-radius: 999px; background: var(--portal-well); margin-top: 8px; overflow: hidden; }
.manage-shell .pay-fill { display: block; height: 100%; border-radius: 999px; }
.manage-shell .pay-card { background: var(--portal-accent); }
.manage-shell .pay-cash { background: var(--portal-text-faint); }
.manage-shell .pay-gift { background: var(--portal-purple); }
.manage-shell .pay-voucher { background: var(--portal-price); }

.manage-shell .top-services { list-style: none; margin: 0; padding: 4px 0; }
.manage-shell .top-services li { display: flex; align-items: baseline; gap: 12px; padding: 12px 22px 12px 26px; border-bottom: 1px solid var(--portal-hairline); position: relative; }
.manage-shell .top-services li::before {
    content: ""; position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
    width: 3px; height: 16px; border-radius: 2px; background: var(--portal-price);
}
.manage-shell .top-services li:last-child { border-bottom: none; }
.manage-shell .ts-name { flex: 1; min-width: 0; font-weight: 600; font-size: 14px; color: var(--portal-text); }
.manage-shell .ts-meta { font-size: 12.5px; color: var(--portal-text-faint); white-space: nowrap; }
.manage-shell .ts-amt { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--portal-text); white-space: nowrap; }

.manage-shell .tech-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 50%; margin-right: 10px;
    background: var(--portal-accent-wash); color: var(--portal-accent-text);
    font-size: 12px; font-weight: 700;
}
.manage-shell .data-table .tip-amt { color: var(--portal-price); font-variant-numeric: tabular-nums; }
.manage-shell .data-table tfoot td { border-top: 1px solid var(--portal-border); background: var(--portal-thead); font-variant-numeric: tabular-nums; }
.manage-shell .data-table tfoot td:first-child {
    font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--portal-text-secondary);
}

.manage-shell .hour-chart { display: flex; gap: 10px; align-items: stretch; }
.manage-shell .hour-col { flex: 1 1 0; max-width: 72px; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.manage-shell .hour-amt { font-size: 11.5px; color: var(--portal-text-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* The empty-hour column has no $ label; the well keeps every bar on one baseline anyway. */
.manage-shell .hour-well { display: flex; align-items: flex-end; width: 100%; height: 130px; margin-top: auto; }
.manage-shell .hour-bar {
    width: 100%; min-height: 2px; border-radius: 6px 6px 3px 3px;
    background: var(--portal-accent-wash); border: 1px solid var(--portal-success-border);
}
.manage-shell .hour-bar.is-peak { background: var(--portal-accent); border-color: var(--portal-accent); }
.manage-shell .hour-lab { font-size: 11.5px; color: var(--portal-text-faint); }

/* Print = the Z-report on paper: the report alone, no chrome, no export card — and the
   tokens remapped light, because browsers print without background colours and pale text
   on assumed-dark panels would come out unreadable. */
@media print {
    .manage-shell .manage-header, .manage-shell .report-toolbar,
    .manage-shell #export, .manage-shell .card-info { display: none !important; }
    .manage-shell, .manage-login-wrap {
        --portal-bg: #ffffff; --portal-panel: #ffffff; --portal-surface: #ffffff; --portal-item: #ffffff;
        --portal-well: #f2f4f5; --portal-thead: #f2f4f5;
        --portal-border: #c6ced2; --portal-border-card: #c6ced2; --portal-hairline: #dde3e6;
        --portal-text: #101416; --portal-text-body: #232a2e; --portal-text-secondary: #545e63;
        --portal-text-muted: #545e63; --portal-text-faint: #74807f;
        --portal-accent: #0e8a62; --portal-accent-text: #0e8a62; --portal-accent-contrast: #ffffff;
        --portal-accent-wash: rgba(14, 138, 98, 0.16); --portal-accent-wash-soft: rgba(14, 138, 98, 0.08);
        --portal-success: #0e8a62; --portal-success-bg: rgba(14, 138, 98, 0.12); --portal-success-border: rgba(14, 138, 98, 0.4);
        --portal-warn: #8a6420; --portal-warn-text: #8a6420;
        --portal-price: #8a6420; --portal-pink: #b0426e; --portal-purple: #6a3fa0;
    }
}

/* Staff import review (1 Sep 2026): every cell is an input, so a name or a mobile is fixed on
   the spot and re-checked, rather than round-tripping the spreadsheet. Inputs have FIXED,
   border-box widths (the .rows-editable 100% rule would let them eat the row) and cells are
   tighter than the default table, so the "Importing would…" column — the one a person reads —
   keeps ~300px inside the 1140px shell on a laptop; narrower windows scroll in .table-scroll. */
.manage-shell .import-review .data-table { min-width: 1040px; }
.manage-shell .import-review .data-table th, .manage-shell .import-review .data-table td { padding-left: 8px; padding-right: 8px; }
.manage-shell .import-review .rows-editable input:not([type="checkbox"]),
.manage-shell .import-review .rows-editable select { box-sizing: border-box; min-width: 0; height: 32px; padding: 0 8px; font-size: 13px; }
.manage-shell .import-review .rows-editable .name-cell input { display: block; width: 9.5em; }
.manage-shell .import-review .rows-editable .name-cell input + input { margin-top: 4px; }
.manage-shell .import-review .rows-editable .name-cell input.pref { font-style: italic; }
.manage-shell .import-review .rows-editable .name-cell input.name-clash { border-color: var(--portal-warn); box-shadow: inset 0 0 0 1px var(--portal-warn); }
.manage-shell .import-review .rows-editable input[name^="phone"] { width: 9.6em; font-variant-numeric: tabular-nums; }
.manage-shell .import-review .rows-editable input[name^="email"] { width: 8.5em; }
.manage-shell .import-review .rows-editable select[name^="role"] { width: 7.5em; padding: 0 4px; }
/* Wide enough for "125.00" with the spinner gone — a number input keeps room for its spin buttons
   and clipped "0.00" at 4.5em (William, 1 Sep 2026). inputmode=decimal still brings the numeric keypad. */
.manage-shell .import-review .rows-editable td.num input[name^="rate"] { width: 6.5em; text-align: right; -moz-appearance: textfield; appearance: textfield; }
.manage-shell .import-review .rows-editable td.num input[name^="rate"]::-webkit-inner-spin-button,
.manage-shell .import-review .rows-editable td.num input[name^="rate"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.manage-shell .import-review td.verdict { min-width: 280px; max-width: none; width: 32%; }
.manage-shell .import-review td.verdict .note { margin-top: 4px; color: var(--portal-warn); }

/* ── Bookings: a visit is one row; its services are a plan, listed in order without times ── */
.manage-shell .visit-services { margin: 0; padding-left: 18px; }
.manage-shell .visit-services li { line-height: 1.4; }
.manage-shell .visit-more { display: block; margin-top: 6px; }
.manage-shell .visit-more > summary { cursor: pointer; color: var(--portal-text-muted); list-style: none; }
.manage-shell .visit-more > summary::before { content: "▸ "; }
.manage-shell .visit-more[open] > summary::before { content: "▾ "; }
.manage-shell .visit-rows { margin-top: 6px; border-collapse: collapse; font-size: 13px; }
.manage-shell .visit-rows td { padding: 4px 10px 4px 0; vertical-align: middle; white-space: normal; }
.manage-shell .visit-rows .row-actions { white-space: nowrap; }
