/* ============================================================
   artwork.inovaep.com — Main Stylesheet
   Palette: black & white, Georgia / system sans-serif (admin runs its
   own dark theme — see "Admin/staff dark theme" below; the public
   storefront runs its own dark theme too — see "Public site dark
   theme" further down, body.site-dark, fonts imported there).
   ============================================================ */

/* Fonts for the public site's dark theme (body.site-dark) — must be a
   real @import, and must come before any other rule per the CSS spec.
   Not used by admin, which keeps Georgia/Segoe UI. */
@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=Manrope:wght@400;500;600;700;800&family=Space+Mono:wght@400;700&display=swap');

/* ---- Reset & Base ----------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
    --black:       #0d0d0d;
    --near-black:  #1a1a1a;
    --dark-gray:   #2e2e2e;
    --mid-gray:    #666666;
    --light-gray:  #b0b0b0;
    --pale-gray:   #e8e8e8;
    --off-white:   #f5f5f3;
    --white:       #ffffff;

    --accent:      #1a1a1a;
    --accent-hover:#333333;
    --danger:      #c0392b;
    --success:     #1a7a3c;
    --warning:     #b07d00;

    --font-serif:  Georgia, 'Times New Roman', serif;
    --font-sans:   'Segoe UI', Calibri, system-ui, -apple-system, sans-serif;
    --font-mono:   'Courier New', monospace;

    --radius-sm:   4px;
    --radius-md:   8px;
    --radius-lg:   12px;

    --shadow-sm:   0 1px 3px rgba(0,0,0,0.12);
    --shadow-md:   0 4px 12px rgba(0,0,0,0.15);
    --shadow-lg:   0 8px 24px rgba(0,0,0,0.18);

    --nav-h:       60px;
    --sidebar-w:   280px;
    --transition:  0.2s ease;
}

html { font-size: 16px; scroll-behavior: smooth; }

body {
    font-family: var(--font-sans);
    background: var(--off-white);
    color: var(--near-black);
    line-height: 1.6;
    min-height: 100vh;
}

h1, h2, h3, h4 {
    font-family: var(--font-serif);
    font-weight: normal;
    line-height: 1.3;
}

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

img { max-width: 100%; display: block; }

/* ---- Clickable affordance (site-wide) ----------------------
   Browsers only give a hand cursor automatically to <a>/<button>/
   form controls/<label>. Anything else wired up with an onclick
   handler or a JS-driven data-href row (see admin/customer.php's
   order rows) needs it set explicitly, or hovering it looks and
   feels identical to hovering plain static text/content. */
[onclick]:not(button):not(a):not(input):not(select):not(textarea):not(label),
[data-href] {
    cursor: pointer;
}

/* ---- Typography ------------------------------------------- */
.text-serif  { font-family: var(--font-serif); }
.text-sans   { font-family: var(--font-sans); }
.text-sm     { font-size: 0.875rem; }
.text-xs     { font-size: 0.75rem; }
.text-muted  { color: var(--mid-gray); }
.text-center { text-align: center; }

/* ---- Layout Utilities ------------------------------------- */
.container { max-width: 1200px; margin: 0 auto; padding: 0 1.5rem; }
.flex       { display: flex; }
.flex-col   { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.5rem; }
.gap-2 { gap: 1rem; }
.gap-3 { gap: 1.5rem; }
.mt-1  { margin-top: 0.5rem; }
.mt-2  { margin-top: 1rem; }
.mt-3  { margin-top: 1.5rem; }
.mb-2  { margin-bottom: 1rem; }
.w-full { width: 100%; }
.hidden { display: none !important; }

/* ---- Buttons --------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.55rem 1.25rem;
    font-family: var(--font-sans);
    font-size: 0.9rem;
    font-weight: 500;
    border-radius: var(--radius-md);
    border: 1.5px solid transparent;
    cursor: pointer;
    transition: background var(--transition), color var(--transition), border-color var(--transition);
    text-decoration: none;
    white-space: nowrap;
    user-select: none;
}

.btn-primary {
    background: var(--near-black);
    color: var(--white);
    border-color: var(--near-black);
}
.btn-primary:hover {
    background: var(--dark-gray);
    border-color: var(--dark-gray);
    text-decoration: none;
}

.btn-outline {
    background: transparent;
    color: var(--near-black);
    border-color: var(--near-black);
}
.btn-outline:hover {
    background: var(--near-black);
    color: var(--white);
    text-decoration: none;
}

.btn-ghost {
    background: transparent;
    color: var(--mid-gray);
    border-color: transparent;
}
.btn-ghost:hover {
    background: var(--pale-gray);
    color: var(--near-black);
    text-decoration: none;
}

.btn-danger {
    background: transparent;
    color: var(--danger);
    border-color: var(--danger);
}
.btn-danger:hover {
    background: var(--danger);
    color: var(--white);
    text-decoration: none;
}

.btn-sm { padding: 0.35rem 0.85rem; font-size: 0.8rem; }
.btn-lg { padding: 0.75rem 2rem; font-size: 1rem; }

/* ---- Forms ------------------------------------------------ */
.form-group { margin-bottom: 1.25rem; }

label {
    display: block;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--dark-gray);
    margin-bottom: 0.4rem;
    font-family: var(--font-sans);
}

/* Field-name labels ("Name", "SKU", "Description", etc.) specifically —
   slightly bigger than the base label size above for readability, without
   affecting the many plain checkbox/inline labels elsewhere that share
   the base `label` rule but aren't classed .form-label. */
.form-label {
    font-size: 0.95rem;
}

input[type="text"],
input[type="email"],
input[type="password"],
select,
textarea {
    display: block;
    width: 100%;
    padding: 0.6rem 0.9rem;
    font-family: var(--font-sans);
    font-size: 0.95rem;
    border: 1.5px solid var(--pale-gray);
    border-radius: var(--radius-md);
    background: var(--white);
    color: var(--near-black);
    transition: border-color var(--transition), box-shadow var(--transition);
    appearance: none;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--near-black);
    box-shadow: 0 0 0 3px rgba(0,0,0,0.08);
}

input::placeholder { color: var(--light-gray); }

.form-error {
    font-size: 0.8rem;
    color: var(--danger);
    margin-top: 0.3rem;
}

/* ---- Alerts ----------------------------------------------- */
.alert {
    padding: 0.75rem 1rem;
    border-radius: var(--radius-md);
    font-size: 0.9rem;
    border-left: 3px solid;
    margin-bottom: 1rem;
}
.alert-error   { background: #fdf0f0; border-color: var(--danger);  color: var(--danger); }
.alert-success { background: #f0fdf4; border-color: var(--success); color: var(--success); }
.alert-info    { background: #f5f5f3; border-color: var(--mid-gray);color: var(--dark-gray); }

/* ---- Top Navigation --------------------------------------- */
.topnav {
    position: sticky;
    top: 0;
    z-index: 100;
    height: var(--nav-h);
    background: var(--white);
    border-bottom: 1px solid var(--pale-gray);
    display: flex;
    align-items: center;
    padding: 0 1.5rem;
    gap: 1rem;
    box-shadow: var(--shadow-sm);
}

.topnav__logo {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
}
.topnav__logo img {
    height: 36px;
    width: auto;
}
.topnav__logo-text {
    font-family: var(--font-serif);
    font-size: 1.1rem;
    color: var(--near-black);
}

.topnav__spacer { flex: 1; }

.topnav__user {
    font-size: 0.85rem;
    color: var(--mid-gray);
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

/* ---- Login Page ------------------------------------------- */
.login-page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
    background: var(--off-white);
}

.login-card {
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    padding: 2.5rem 2rem;
    width: 100%;
    max-width: 420px;
    box-shadow: var(--shadow-md);
}

.login-card__logo {
    text-align: center;
    margin-bottom: 2rem;
}
.login-card__logo img {
    height: 64px;
    margin: 0 auto 0.75rem;
}
.login-card__logo h1 {
    font-size: 1.4rem;
    color: var(--near-black);
}
.login-card__logo p {
    font-size: 0.85rem;
    color: var(--mid-gray);
    margin-top: 0.25rem;
    font-family: var(--font-sans);
}

.login-divider {
    text-align: center;
    margin: 2rem 0 1rem;
    font-size: 0.75rem;
    color: var(--light-gray);
    font-family: var(--font-sans);
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

/* ---- Dashboard -------------------------------------------- */
.dashboard-layout {
    display: flex;
    min-height: calc(100vh - var(--nav-h));
}

.sidebar {
    width: var(--sidebar-w);
    background: var(--white);
    border-right: 1px solid var(--pale-gray);
    padding: 1.5rem 0;
    flex-shrink: 0;
    overflow-y: auto;
    position: sticky;
    top: var(--nav-h);
    height: calc(100vh - var(--nav-h));
}

.sidebar__section-title {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--light-gray);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 0 1.25rem;
    margin-bottom: 0.5rem;
    font-family: var(--font-sans);
}

.sidebar__file-list { list-style: none; }

.sidebar__file-item a {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 1.25rem;
    font-size: 0.85rem;
    color: var(--dark-gray);
    border-left: 2px solid transparent;
    transition: background var(--transition), border-color var(--transition);
    text-decoration: none;
    word-break: break-word;
}
.sidebar__file-item a:hover {
    background: var(--off-white);
    border-left-color: var(--mid-gray);
}
.sidebar__file-item a.active {
    background: var(--off-white);
    border-left-color: var(--near-black);
    font-weight: 500;
    color: var(--near-black);
}

.file-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    opacity: 0.6;
}

.main-content {
    flex: 1;
    padding: 2rem;
    overflow-y: auto;
    min-width: 0;
}

/* ---- File Grid (dashboard cards) -------------------------- */
.file-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 1.25rem;
}

.file-card {
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    padding: 1.25rem 1rem 1rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    cursor: pointer;
    transition: box-shadow var(--transition), border-color var(--transition), transform var(--transition);
    text-decoration: none;
    color: var(--near-black);
}
.file-card:hover {
    box-shadow: var(--shadow-md);
    border-color: var(--near-black);
    transform: translateY(-2px);
    text-decoration: none;
}

.file-card__icon {
    width: 56px;
    height: 56px;
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.75rem;
    background: var(--off-white);
}
.file-card__icon--stl { background: #f0f0ee; }
.file-card__icon--pdf { background: #fdf0f0; }
.file-card__icon--txt { background: #f5f5f3; }
.file-card__icon--xls { background: #f0fdf4; }
.file-card__icon--other { background: var(--pale-gray); }

.file-card__name {
    font-size: 0.82rem;
    text-align: center;
    word-break: break-word;
    line-height: 1.4;
    font-family: var(--font-sans);
}

.file-card__meta {
    font-size: 0.73rem;
    color: var(--light-gray);
    font-family: var(--font-sans);
}

/* ---- Viewer Page ------------------------------------------ */
.viewer-layout {
    display: grid;
    grid-template-columns: 320px 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas:
        "sidebar toolbar"
        "sidebar canvas";
    height: calc(100vh - var(--nav-h));
}

.viewer-sidebar {
    grid-area: sidebar;
    width: 320px;
    background: var(--white);
    border-right: 1px solid var(--pale-gray);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

.viewer-sidebar__header {
    padding: 1.75rem 1.5rem 1.5rem;
    border-bottom: 1px solid var(--pale-gray);
}
.viewer-sidebar__header .btn {
    width: auto;
    display: inline-flex;
}
.viewer-sidebar__logo {
    height: 38px;
    width: auto;
    margin-bottom: 1.25rem;
}
.viewer-sidebar__header h3 {
    font-size: 1rem;
    font-family: var(--font-serif);
    color: var(--near-black);
    line-height: 1.3;
    word-break: break-word;
}

.viewer-toolbar {
    grid-area: toolbar;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    background: #1c1c1c;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    flex-wrap: wrap;
}

.viewer-toolbar__title {
    font-size: 0.85rem;
    color: rgba(255,255,255,0.7);
    font-family: var(--font-sans);
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.viewer-btn {
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    background: rgba(0,0,0,0.45);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: var(--radius-sm);
    color: rgba(255,255,255,0.85);
    cursor: pointer;
    transition: background var(--transition);
    font-family: var(--font-sans);
    white-space: nowrap;
}
.viewer-btn:hover { background: rgba(0,0,0,0.65); }
.viewer-btn.active { background: rgba(0,0,0,0.7); border-color: rgba(255,255,255,0.35); }

/* ---- Viewer filename overlay ------------------------------ */
.viewer-file-label {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    background: rgba(0, 0, 0, 0.5);
    color: rgba(255, 255, 255, 0.88);
    font-size: 0.72rem;
    font-family: var(--font-sans);
    padding: 0.2rem 0.6rem;
    border-radius: var(--radius-sm);
    max-width: 55%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    z-index: 5;
}

#stl-canvas-container {
    grid-area: canvas;
    position: relative;
    overflow: hidden;
    background: #1a1a1a;
}

#stl-canvas {
    display: block;
    width: 100% !important;
    height: 100% !important;
    touch-action: none;
}

.viewer-loading {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #1a1a1a;
    color: rgba(255,255,255,0.6);
    font-family: var(--font-sans);
    font-size: 0.9rem;
    gap: 1rem;
    z-index: 10;
}

.spinner {
    width: 36px;
    height: 36px;
    border: 2.5px solid rgba(255,255,255,0.15);
    border-top-color: rgba(255,255,255,0.7);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.viewer-hint {
    position: absolute;
    bottom: 1rem;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.75rem;
    color: rgba(255,255,255,0.3);
    font-family: var(--font-sans);
    pointer-events: none;
    white-space: nowrap;
    z-index: 4;
}

/* ---- Viewer Color Swatches -------------------------------- */
.color-swatch {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    cursor: pointer;
    border: 2px solid rgba(255,255,255,0.15);
    flex-shrink: 0;
    transition: border-color var(--transition), transform var(--transition);
}
.color-swatch:hover  { border-color: rgba(255,255,255,0.5);  transform: scale(1.15); }
.color-swatch.active { border-color: rgba(255,255,255,0.9);  transform: scale(1.1); }

/* ---- Viewer Sidebar Sections ------------------------------ */
.viewer-sidebar__section {
    padding: 1.5rem 1.5rem;
    border-bottom: 1px solid var(--pale-gray);
    flex-shrink: 0;
}

.viewer-sidebar__section-title {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--light-gray);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    margin-bottom: 0.75rem;
    font-family: var(--font-sans);
}

.viewer-stats {
    width: 100%;
    border-collapse: collapse;
}
.viewer-stats td {
    padding: 0.28rem 0;
    border-bottom: none;
    vertical-align: middle;
}
.viewer-stats tr:hover td { background: transparent; }
.viewer-stats__label {
    font-family: var(--font-sans);
    font-size: 0.82rem;
    color: var(--mid-gray);
    width: 45%;
}
.viewer-stats__val {
    font-family: var(--font-mono);
    font-size: 0.85rem;
    color: var(--near-black);
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* ---- Model Stats dark section ----------------------------- */
.viewer-stats-section {
    background: #1e1e1e;
}
.viewer-stats-section .viewer-sidebar__section-title {
    color: rgba(255,255,255,0.45);
}
.viewer-stats-section .viewer-stats__label {
    color: rgba(255,255,255,0.6);
}
.viewer-stats-section .viewer-stats__val {
    color: rgba(255,255,255,0.95);
    font-weight: 600;
}

.viewer-share {
    background: var(--off-white);
}
.viewer-share__input {
    font-size: 0.8rem !important;
    color: var(--mid-gray) !important;
    background: var(--white) !important;
}

.viewer-cta__brand {
    margin-top: 1rem;
    font-size: 0.72rem;
    color: var(--light-gray);
    text-align: center;
    font-family: var(--font-sans);
}
.viewer-cta__brand a { color: var(--mid-gray); }
.viewer-cta__brand a:hover { color: var(--near-black); text-decoration: underline; }

/* ---- Viewer Colour Picker --------------------------------- */
.viewer-color-picker {
    -webkit-appearance: none;
    appearance: none;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 2px solid rgba(255,255,255,0.15);
    border-radius: var(--radius-sm);
    background: none;
    cursor: pointer;
    flex-shrink: 0;
}
.viewer-color-picker:hover { border-color: rgba(255,255,255,0.5); }
.viewer-color-picker::-webkit-color-swatch-wrapper { padding: 0; }
.viewer-color-picker::-webkit-color-swatch { border: none; border-radius: 2px; }
.viewer-color-picker::-moz-color-swatch { border: none; border-radius: 2px; }

/* ---- Admin Panel ------------------------------------------ */
.admin-layout {
    display: flex;
    min-height: calc(100vh - var(--nav-h));
}

.admin-sidebar {
    width: 220px;
    background: var(--near-black);
    padding: 1.5rem 0;
    flex-shrink: 0;
    /* Sticks below the sticky site header and stays put while .admin-main
       scrolls beside it — same pattern already proven on .sidebar (the
       client dashboard's sidebar), mirrored here rather than invented. */
    align-self: flex-start;
    position: sticky;
    top: var(--nav-h);
    height: calc(100vh - var(--nav-h));
    overflow-y: auto;
}

.admin-sidebar__title {
    font-family: var(--font-serif);
    font-size: 0.95rem;
    color: var(--light-gray);
    padding: 0 1.25rem 1rem;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    margin-bottom: 0.75rem;
}

/* ---- Admin nav: collapsible accordion sections ------------- */
.admin-nav-accordion { list-style: none; }

.admin-nav-group { border-bottom: 1px solid rgba(255,255,255,0.06); }
.admin-nav-group:last-child { border-bottom: none; }

.admin-nav-group__heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-sans);
    font-size: 0.92em;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255,255,255,0.55);
    padding: 0.8rem 1.25rem;
    transition: color var(--transition), background var(--transition);
}
.admin-nav-group__heading:hover { color: var(--white); background: rgba(255,255,255,0.04); }
.admin-nav-group.open > .admin-nav-group__heading { color: var(--white); }

/* Per-group accent color (set via --group-accent on .admin-nav-group in
   includes/admin-sidebar.php) — a small, restrained way to tell sections
   apart at a glance: the heading icon is muted gray at rest and only
   "wakes up" to its accent on hover/open, and the active link's left
   border uses it instead of a flat white. Never applied to running text,
   so readability never depends on the color choice. */
.admin-nav-group__label { display: flex; align-items: center; gap: 0.6rem; }
.admin-nav-group__label .nav-icon {
    width: 16px; height: 16px; flex-shrink: 0;
    color: rgba(255,255,255,0.38);
    transition: color var(--transition);
}
.admin-nav-group__heading:hover .nav-icon,
.admin-nav-group.open > .admin-nav-group__heading .nav-icon {
    color: var(--group-accent, var(--white));
}

.admin-nav-group__chevron {
    width: 10px;
    height: 10px;
    flex-shrink: 0;
    color: rgba(255,255,255,0.5);
    transition: transform var(--transition), color var(--transition);
}
.admin-nav-group.open > .admin-nav-group__heading .admin-nav-group__chevron {
    transform: rotate(90deg);
    color: var(--white);
}

.admin-nav-group__list {
    list-style: none;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease;
}
.admin-nav-group.open .admin-nav-group__list { max-height: 32rem; }

.admin-nav-group__list a {
    display: block;
    padding: 0.55rem 1.25rem 0.55rem 1.75rem;
    font-size: 0.88rem;
    color: rgba(255,255,255,0.65);
    transition: background var(--transition), color var(--transition);
    text-decoration: none;
    font-family: var(--font-sans);
    border-left: 2px solid transparent;
}
.admin-nav-group__list a:hover, .admin-nav-group__list a.active {
    background: rgba(255,255,255,0.08);
    color: var(--white);
    text-decoration: none;
}
.admin-nav-group__list a.active { border-left-color: var(--group-accent, var(--white)); }

.admin-nav-group__soon {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.55rem 1.25rem 0.55rem 1.75rem;
    font-size: 0.88rem;
    color: rgba(255,255,255,0.3);
    font-family: var(--font-sans);
    cursor: default;
}
.admin-nav-group__soon em {
    font-style: normal;
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: rgba(255,255,255,0.35);
    border: 1px solid rgba(255,255,255,0.2);
    border-radius: 999px;
    padding: 0.1rem 0.45rem;
}

.admin-nav-footer {
    list-style: none;
    margin-top: 0.5rem;
    padding-top: 0.75rem;
    border-top: 1px solid rgba(255,255,255,0.08);
}
.admin-nav-footer a {
    display: block;
    padding: 0.5rem 1.25rem;
    font-size: 0.82rem;
    color: rgba(255,255,255,0.42);
    text-decoration: none;
    font-family: var(--font-sans);
    transition: color var(--transition);
}
.admin-nav-footer a:hover { color: var(--white); }
.admin-nav-footer button.admin-theme-toggle {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.5rem 1.25rem;
    font-size: 0.82rem;
    color: rgba(255,255,255,0.42);
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-sans);
    transition: color var(--transition);
}
.admin-nav-footer button.admin-theme-toggle:hover { color: var(--white); }

.admin-main { flex: 1; padding: 2rem; overflow-y: auto; }
.admin-main h2 {
    font-size: 1.4rem;
    margin-bottom: 1.5rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--pale-gray);
}

/* ---- Tables ----------------------------------------------- */
.table-wrap { overflow-x: auto; }

table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
    font-family: var(--font-sans);
}

th {
    text-align: left;
    padding: 0.65rem 1rem;
    background: var(--off-white);
    color: var(--mid-gray);
    font-weight: 500;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border-bottom: 1px solid var(--pale-gray);
}

td {
    padding: 0.7rem 1rem;
    border-bottom: 1px solid var(--pale-gray);
    vertical-align: middle;
}

tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--off-white); }

/* ---- Stat Cards (admin dashboard) ------------------------- */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
}

.stat-card {
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    padding: 1.25rem;
}

.stat-card__value {
    font-family: var(--font-serif);
    font-size: 2rem;
    color: var(--near-black);
    line-height: 1;
    margin-bottom: 0.3rem;
}

.stat-card__label {
    font-size: 0.78rem;
    color: var(--mid-gray);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-family: var(--font-sans);
}

/* ---- Modal ------------------------------------------------ */
.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.45);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.modal {
    background: var(--white);
    border-radius: var(--radius-lg);
    padding: 2rem;
    width: 100%;
    max-width: 480px;
    box-shadow: var(--shadow-lg);
}

.modal__title {
    font-size: 1.2rem;
    margin-bottom: 1.5rem;
    font-family: var(--font-serif);
}

.modal__actions {
    display: flex;
    gap: 0.75rem;
    justify-content: flex-end;
    margin-top: 1.5rem;
}

/* ---- Badge ------------------------------------------------ */
.badge {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 500;
    font-family: var(--font-sans);
    letter-spacing: 0.02em;
}
.badge-active   { background: #eaf7ee; color: var(--success); }
.badge-inactive { background: var(--pale-gray); color: var(--mid-gray); }

/* ---- Page Header ------------------------------------------ */
.page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1.5rem;
    gap: 1rem;
    flex-wrap: wrap;
}
.page-header h2 { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }

/* ---- Empty State ------------------------------------------ */
.empty-state {
    text-align: center;
    padding: 4rem 2rem;
    color: var(--mid-gray);
}
.empty-state__icon { font-size: 3rem; margin-bottom: 1rem; opacity: 0.4; }
.empty-state h3 { font-size: 1.1rem; margin-bottom: 0.5rem; color: var(--dark-gray); }
.empty-state p { font-size: 0.9rem; }

/* ---- Footer ----------------------------------------------- */
.footer {
    text-align: center;
    padding: 1.5rem;
    font-size: 0.78rem;
    color: var(--light-gray);
    font-family: var(--font-sans);
    border-top: 1px solid var(--pale-gray);
    margin-top: auto;
}

/* ---- Mobile Sidebar Toggle -------------------------------- */
.sidebar-toggle {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.4rem;
    color: var(--near-black);
}

/* ============================================================
   RESPONSIVE — Mobile
   ============================================================ */
@media (max-width: 768px) {

    .sidebar-toggle { display: flex; align-items: center; }

    /* Dashboard sidebar becomes a slide-in drawer */
    .sidebar {
        position: fixed;
        top: var(--nav-h);
        left: -100%;
        height: calc(100vh - var(--nav-h));
        z-index: 50;
        transition: left var(--transition);
        box-shadow: var(--shadow-lg);
    }
    .sidebar.open { left: 0; }

    .main-content { padding: 1rem; }

    /* Viewer: flex column stack — toolbar → canvas → sidebar */
    .viewer-layout {
        display: flex;
        flex-direction: column;
        height: auto;
    }
    .viewer-toolbar {
        width: 100%;
        padding: 0.5rem 0.75rem;
        gap: 6px;
        flex-shrink: 0;
    }
    .viewer-btn {
        padding: 0.28rem 0.6rem;
        font-size: 0.75rem;
    }
    .viewer-toolbar__title {
        font-size: 0.8rem;
        flex-basis: 100%;
        order: -1;
    }
    #stl-canvas-container {
        width: 100%;
        height: 45vh;
        min-height: 280px;
        flex-shrink: 0;
    }
    .viewer-hint {
        display: none;
    }
    .viewer-sidebar {
        width: 100%;
        border-right: none;
        border-top: 1px solid var(--pale-gray);
        overflow: visible;
        flex-shrink: 0;
    }

    /* Mobile sidebar typography */
    .viewer-sidebar__header { padding: 1.1rem 1.1rem 0.9rem; }
    .viewer-sidebar__logo { height: 26px; margin-bottom: 0.65rem; }
    .viewer-sidebar__section { padding: 1rem 1.1rem; }
    .viewer-stats__label { font-size: 0.78rem; }
    .viewer-stats__val { font-size: 0.8rem; }

    /* Admin: sidebar becomes a flat scrollable top bar — accordion collapsing
       doesn't make sense in a horizontal strip, so show everything at once. */
    .admin-layout { flex-direction: column; }
    .admin-sidebar {
        width: 100%; padding: 0;
        /* Reset the desktop sticky-column sizing — a horizontal strip
           should keep its own natural height, not stretch to fill the
           viewport. It stays sticky (a pinned top bar reads fine here too),
           just no longer height:100vh. */
        height: auto;
    }
    .admin-sidebar__title { display: none; }
    .admin-nav-accordion { display: flex; align-items: center; overflow-x: auto; }
    .admin-nav-group { display: flex; align-items: center; flex-shrink: 0; border-bottom: none; }
    .admin-nav-group__heading {
        pointer-events: none;
        padding: 0.75rem 0.6rem 0.75rem 1rem;
        font-size: 0.68rem;
        white-space: nowrap;
    }
    .admin-nav-group__chevron { display: none; }
    .admin-nav-group__list { display: flex; max-height: none; overflow: visible; }
    .admin-nav-group__list a { padding: 0.75rem 1rem; white-space: nowrap; border-left: none; }
    .admin-nav-footer { display: flex; overflow-x: auto; margin-top: 0; padding-top: 0; border-top: none; }
    .admin-nav-footer a { padding: 0.75rem 1rem; white-space: nowrap; }
    .admin-main { padding: 1rem; }

    .file-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 0.75rem; }

    .login-card { padding: 2rem 1.25rem; }

    .topnav__logo-text { display: none; }
}

@media (max-width: 480px) {
    .file-grid { grid-template-columns: repeat(2, 1fr); }
    .stat-grid { grid-template-columns: repeat(2, 1fr); }
    .page-header { flex-direction: column; align-items: flex-start; }
}

/* ============================================================
   Shared Site Header (includes/header.php)
   ============================================================ */

.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    height: var(--nav-h);
    background: var(--white);
    border-bottom: 1px solid var(--pale-gray);
    box-shadow: var(--shadow-sm);
    display: flex;
    align-items: center;
    padding: 0 1.5rem;
    gap: 1rem;
}

.site-header__logo {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
    color: var(--near-black);
    flex-shrink: 0;
}
.site-header__logo:hover { text-decoration: none; }
.site-header__logo img { height: 36px; width: auto; }
.site-header__logo-text { font-family: var(--font-serif); font-size: 1.1rem; }

.site-nav {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.site-nav a {
    font-family: var(--font-serif);
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--near-black);
    padding: 0.4rem 1.15rem;
    border-radius: var(--radius-sm);
    text-decoration: none;
    transition: background var(--transition), color var(--transition);
    white-space: nowrap;
}
.site-nav a:hover { background: var(--off-white); text-decoration: none; }
.site-nav a.active { color: var(--near-black); text-decoration: underline; text-underline-offset: 4px; }

.site-nav__item { position: relative; display: flex; align-items: center; }
.site-nav__sub {
    position: absolute;
    top: 100%;
    left: 50%;
    /* Sits flush against the parent (no margin-top gap) so the mouse never
       crosses empty, un-hoverable space while moving from the "Products"
       link down into the menu — that gap was the actual bug: crossing it
       dropped :hover on .site-nav__item--has-sub before the cursor ever
       reached the submenu, so it vanished mid-move. The breathing room
       above the menu items is extra top padding instead, which IS part of
       this element's own hoverable box. */
    transform: translate(-50%, -4px);
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 0.85rem 0.5rem 0.5rem;
    min-width: 175px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.2rem;
    z-index: 10;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
}
.site-nav__sub::before {
    content: '';
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    width: 12px;
    height: 12px;
    background: var(--white);
    border-left: 1px solid var(--pale-gray);
    border-top: 1px solid var(--pale-gray);
    border-radius: 3px 0 0 0;
    transform: translateX(-50%) rotate(45deg);
    margin-bottom: -7px;
}
/* Desktop-only: hover/focus-within reveal of the absolutely-positioned
   popover. Scoped to min-width:769px specifically because it's more
   specific than the mobile .site-nav__sub reset below — unscoped, it
   also fired the moment the mobile accordion's own toggle *button*
   received focus (a button inside .site-nav__item--has-sub triggers
   :focus-within on it too), silently winning the cascade and shoving
   the mobile accordion's content off-screen via this rule's leftover
   translate(-50%, 0) even though .site-nav__sub was position:static
   there. */
@media (min-width: 769px) {
    .site-nav__item--has-sub:hover .site-nav__sub,
    .site-nav__item--has-sub:focus-within .site-nav__sub {
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        transform: translate(-50%, 0);
    }
}
.site-nav__sub a {
    font-family: var(--font-sans);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-align: center;
    padding: 0.55rem 1.1rem;
    border-radius: var(--radius-md);
    white-space: nowrap;
    transition: background var(--transition), color var(--transition);
}
.site-nav__sub a:hover {
    background: var(--near-black);
    color: var(--white);
    text-decoration: none;
}

.site-header__right {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    margin-left: auto;
    flex-shrink: 0;
}

/* Mobile menu toggle (hamburger) — hidden on desktop, shown at the
   @media (max-width: 768px) breakpoint below, where .site-nav becomes
   a hidden-by-default dropdown panel instead of always-visible links. */
.site-nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--near-black);
    cursor: pointer;
    flex-shrink: 0;
}
.site-nav-toggle:hover { background: var(--off-white); }

/* Wraps a has-sub link with its accordion toggle button so the link
   itself still navigates while the caret is the only thing that
   expands/collapses the submenu — both are needed on a touch device,
   which has no hover. Desktop leaves the caret hidden and keeps using
   plain :hover/:focus-within on .site-nav__item--has-sub (unchanged). */
.site-nav__item-row { display: flex; align-items: center; width: 100%; }
.site-nav__sub-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin-left: auto;
    border: none;
    background: transparent;
    color: var(--mid-gray);
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: transform 0.2s ease;
    flex-shrink: 0;
}
.site-nav__item--has-sub.open .site-nav__sub-toggle { transform: rotate(180deg); }

.site-header__signout {
    font-size: 0.78rem;
    color: var(--mid-gray);
    font-family: var(--font-sans);
    white-space: nowrap;
    text-decoration: none;
}
.site-header__signout:hover { color: var(--near-black); text-decoration: underline; }

.site-header__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--near-black);
    color: var(--white);
    font-family: var(--font-serif);
    font-size: 0.95rem;
    font-weight: 700;
    text-decoration: none;
    flex-shrink: 0;
    transition: background var(--transition), transform var(--transition);
}
.site-header__avatar:hover { background: var(--accent-hover); text-decoration: none; transform: scale(1.06); }
.site-header__avatar--guest { background: var(--white); color: var(--near-black); border: 1.5px solid var(--near-black); }
.site-header__avatar--guest:hover { background: var(--near-black); color: var(--white); }

/* Back link used on model.php */
.model-back-link {
    display: inline-block;
    font-size: 0.82rem;
    color: var(--mid-gray);
    text-decoration: none;
    margin-bottom: 0.65rem;
    font-family: var(--font-sans);
    transition: color var(--transition);
}
.model-back-link:hover { color: var(--near-black); text-decoration: none; }

@media (max-width: 768px) {
    .site-header {
        display: flex;
        flex-wrap: wrap;
        height: auto;
        padding: 0;
        gap: 0;
        align-items: stretch;
    }

    /* Row 1: logo + right actions */
    .site-header__logo {
        flex: 1;
        height: 56px;
        padding: 0 1rem;
    }
    .site-header__logo img { height: 28px; }
    .site-header__logo-text { font-size: 0.95rem; }

    .site-header__right {
        height: 56px;
        padding: 0 1rem;
        gap: 0.5rem;
    }

    .site-nav-toggle { display: flex; }

    /* .site-nav is a hidden-by-default dropdown panel (position:fixed,
       so it overlays page content instead of pushing a layout row down)
       rather than the old always-visible horizontal-scrolling pill
       strip — that broke down as soon as a top-level item's submenu
       grew past one entry, since everything unrolled into one flat,
       overflowing row with no visual distinction between a page and a
       submenu item. Toggled open via #siteNavToggle in header.php. */
    .site-nav {
        position: fixed;
        top: 56px;
        left: 0;
        right: 0;
        max-height: calc(100vh - 56px);
        overflow-y: auto;
        flex-direction: column;
        align-items: stretch;
        gap: 0.15rem;
        background: var(--white);
        border-top: 1px solid var(--pale-gray);
        border-bottom: 1px solid var(--pale-gray);
        box-shadow: var(--shadow-lg);
        padding: 0.5rem;
        transform: translateY(-8px);
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
        z-index: 99;
    }
    .site-nav.open {
        transform: translateY(0);
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
    }

    .site-nav a {
        width: 100%;
        font-size: 1rem;
        padding: 0.75rem 0.9rem;
        border-radius: var(--radius-sm);
        background: transparent;
        border: none;
        color: var(--near-black);
        white-space: normal;
    }
    .site-nav a:hover,
    .site-nav a.active {
        background: var(--off-white);
        color: var(--near-black);
    }

    .site-nav__item { flex-direction: column; align-items: stretch; width: 100%; }
    .site-nav__sub-toggle { display: flex; }

    /* Collapsed by default; .site-nav__item--has-sub.open (toggled by
       the caret button, independent of the parent panel's own .open)
       reveals it as an indented list under the parent link — this is
       the part that scales to more than one submenu item, unlike the
       old flat pill strip. */
    .site-nav__sub {
        position: static;
        display: none;
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        transform: none;
        flex-direction: column;
        background: transparent;
        border: none;
        box-shadow: none;
        padding: 0 0 0.25rem 1rem;
        margin-top: 0;
        min-width: 0;
        gap: 0;
    }
    .site-nav__item--has-sub.open .site-nav__sub { display: flex; }
    .site-nav__sub::before { display: none; }
    .site-nav__sub a {
        font-size: 0.92rem;
        font-weight: 500;
        padding: 0.6rem 0.9rem;
        text-align: left;
        color: var(--mid-gray);
    }
    .site-nav__sub a:hover,
    .site-nav__sub a.active { background: var(--off-white); color: var(--near-black); }

    .site-header__signout { font-size: 0.72rem; }
    .site-header__avatar { width: 32px; height: 32px; }

    /* The admin dark-theme override below still applies at every width
       (it re-themes the shared public header when shown above an admin
       page) and separately re-declares .site-nav__sub's desktop-popover
       background/border. Reset those specifically at mobile width so the
       accordion list stays a flat, transparent, indented list instead of
       inheriting a stray boxed-popover look it was never designed for. */
    body:has(.admin-layout):not(.theme-light) .site-nav__sub { background: transparent; border: none; box-shadow: none; }
}

/* ============================================================
   Model Product Page (model.php)
   ============================================================ */

.model-header {
    height: var(--nav-h);
    background: var(--white);
    border-bottom: 1px solid var(--pale-gray);
    display: flex;
    align-items: center;
    padding: 0 2rem;
    box-shadow: var(--shadow-sm);
}

.model-header__logo {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    text-decoration: none;
    color: var(--near-black);
}
.model-header__logo:hover { text-decoration: none; }
.model-header__logo img { height: 34px; width: auto; }
.model-header__logo-text { font-family: var(--font-serif); font-size: 1.1rem; }

.model-main {
    max-width: 1240px;
    margin: 0 auto;
    padding: 1.5rem 1.5rem 4rem;
}

.model-back-wrap { margin-bottom: 1rem; }

.model-layout {
    display: grid;
    grid-template-columns: 1fr 340px;
    gap: 2rem;
    align-items: start;
}

.model-viewer-col { min-width: 0; }

.model-viewer-wrap {
    background: #1a1a1a;
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-lg);
}

.model-viewer-toolbar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.65rem 1rem;
    background: #1c1c1c;
    border-bottom: 1px solid rgba(255,255,255,0.08);
    flex-wrap: wrap;
}

.model-viewer-wrap #stl-canvas-container {
    height: 72vh;
    min-height: 460px;
}

.model-sidebar {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    position: sticky;
    top: calc(var(--nav-h) + 1rem);
}

.model-title {
    font-size: 1.65rem;
    font-weight: normal;
    color: var(--near-black);
    line-height: 1.25;
    font-family: var(--font-serif);
    margin: 0;
}

.model-section {
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
}

.model-section__title {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--light-gray);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-family: var(--font-sans);
    margin-bottom: 0.9rem;
}

.model-cta-text {
    font-size: 0.9rem;
    color: var(--dark-gray);
    line-height: 1.65;
    margin-bottom: 1.1rem;
    font-family: var(--font-sans);
}

.model-attribution-text {
    font-size: 0.875rem;
    color: var(--dark-gray);
    line-height: 1.65;
    font-family: var(--font-sans);
}
.model-attribution-text a { color: var(--mid-gray); text-decoration: underline; }
.model-attribution-text a:hover { color: var(--near-black); }

/* Public "Design & License" provenance block (product_licensing) — same
   restrained model-section treatment, just the link row is its own thing. */
.pdp-license__links { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }

/* Promotions/Offers strip (includes/promotions.php) — global default,
   picked up by any body.site-dark page (products.php, product.php).
   index.php uses its own richer --hp-* token override instead (its own
   <style> block, own theme system, see includes/promotions.php's
   render function for the shared markup both rely on). */
.promo-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }
.promo-card { background: var(--white); border: 1px solid var(--pale-gray); border-radius: var(--radius-lg); padding: 1.3rem 1.4rem; }
.promo-card__title { font-family: var(--font-serif); font-weight: 600; font-size: 1.05rem; color: var(--near-black); margin-bottom: 0.35rem; }
.promo-card__msg { font-size: 0.86rem; line-height: 1.55; color: var(--mid-gray); margin-bottom: 0.7rem; }
.promo-card__cta { display: inline-block; }

.model-share-row {
    display: flex;
    gap: 0.5rem;
}
.model-share-row input {
    flex: 1;
    min-width: 0;
    font-size: 0.82rem !important;
    color: var(--mid-gray) !important;
}

@media (max-width: 900px) {
    .model-main { padding: 0 0 3rem; }
    .model-back-wrap { padding: 1rem 1rem 0; }
    .model-layout { grid-template-columns: 1fr; gap: 0; }
    .model-viewer-col { order: 1; }
    .model-sidebar { order: 2; padding: 1rem; position: static; gap: 0.75rem; }
    .model-viewer-wrap { border-radius: 0; box-shadow: none; }
    .model-viewer-wrap #stl-canvas-container { height: 50vh; min-height: 280px; }
    .model-viewer-toolbar { padding: 0.5rem 0.75rem; gap: 5px; }
    .model-title { font-size: 1.45rem; }
    .model-share-row { flex-direction: column; }
    .model-share-row .btn { width: 100%; }
}

/* ============================================================
   Site Footer (includes/footer.php)
   ============================================================ */

.site-footer {
    margin-top: 4rem;
    border-top: 1px solid var(--pale-gray);
    background: var(--off-white);
    padding: 1.25rem 2rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    font-family: var(--font-sans);
    font-size: 0.82rem;
    color: var(--light-gray);
}

.site-footer__copy {
    white-space: nowrap;
    flex-shrink: 0;
}

.site-footer__links {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
}

.site-footer a {
    color: var(--mid-gray);
    text-decoration: none;
    transition: color var(--transition);
}
.site-footer a:hover { color: var(--near-black); text-decoration: none; }

@media (max-width: 600px) {
    .site-footer {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.75rem;
        padding: 1.25rem 1rem;
    }
    .site-footer__links {
        flex-direction: column;
        align-items: flex-start;
        gap: 0;
        width: 100%;
    }
    .site-footer__links a {
        display: block;
        padding: 0.55rem 0;
        border-bottom: 1px solid var(--pale-gray);
        width: 100%;
    }
    .site-footer__links a:last-child { border-bottom: none; }
}

/* ============================================================
   Static Content Pages (privacy.php, terms.php, contact.php)
   ============================================================ */

.content-page {
    max-width: 720px;
    margin: 0 auto;
    padding: 3rem 1.5rem 5rem;
}

.content-page h1 {
    font-weight: normal;
    font-size: 2rem;
    margin-bottom: 0.4rem;
    font-family: var(--font-serif);
}

.content-page h2 {
    font-size: 1rem;
    font-weight: 600;
    margin: 2rem 0 0.5rem;
    font-family: var(--font-sans);
    color: var(--near-black);
}

.content-page p {
    font-size: 0.9rem;
    line-height: 1.7;
    color: var(--dark-gray);
    margin-bottom: 0.6rem;
}

.content-page section {
    border-bottom: 1px solid var(--pale-gray);
    padding-bottom: 1.5rem;
    margin-bottom: 0.5rem;
}

/* ============================================================
   Ops Dashboard
   ============================================================ */

/* Snapshot bar */
.ops-snap {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 1.5rem;
}
.ops-snap-card {
    flex: 1;
    min-width: 110px;
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    padding: 1rem 1rem 0.9rem;
    text-align: center;
}
.ops-snap-card__value {
    font-size: 1.8rem;
    font-weight: 700;
    line-height: 1;
    color: var(--near-black);
    font-variant-numeric: tabular-nums;
}
.ops-snap-card__label {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--mid-gray);
    margin-top: 0.35rem;
    font-weight: 600;
}
.ops-snap-card--alert .ops-snap-card__value { color: #dc2626; }
.ops-snap-card--warn  .ops-snap-card__value { color: #d97706; }
.ops-snap-card--ok    .ops-snap-card__value { color: #16a34a; }

/* Section container */
.ops-section {
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    margin-bottom: 1.25rem;
    overflow: hidden;
}
.ops-section__header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.7rem 1.25rem;
    border-bottom: 1px solid var(--pale-gray);
    background: var(--off-white);
}
.ops-section__title {
    font-size: 0.94rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--near-black);
    margin: 0;
}
.ops-section__count {
    font-size: 0.72rem;
    background: var(--pale-gray);
    color: var(--mid-gray);
    border-radius: 10px;
    padding: 0.1rem 0.5rem;
    font-weight: 600;
}
.ops-section__count--alert { background: #fee2e2; color: #991b1b; }
.ops-section__count--warn  { background: #fef3c7; color: #92400e; }
.ops-section__action {
    margin-left: auto;
    font-size: 0.8rem;
    color: var(--mid-gray);
    text-decoration: none;
    white-space: nowrap;
}
.ops-section__action:hover { color: var(--near-black); text-decoration: underline; }

/* Orders Board — the shop's own custom-order grid, deliberately the most
   prominent thing on the page (replaces the old embedded Google Sheet) */
.ops-board-section {
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    margin-bottom: 1.5rem;
    overflow: hidden;
}
.ops-board-section__hd {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.7rem 1.25rem;
    border-bottom: 1px solid var(--pale-gray);
    background: var(--off-white);
    flex-wrap: wrap;
}
.ops-board-section__hd .ops-section__title { margin-right: auto; }
.ob-master-search { padding: 0.6rem 1.25rem; display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.ob-master-search input {
    flex: 1 1 320px;
    max-width: 420px;
    padding: 0.4rem 0.75rem;
    font-size: 0.85rem;
}
.ob-master-search select {
    flex: 0 0 auto;
    width: auto;
    max-width: 220px;
    padding: 0.4rem 0.6rem;
    font-size: 0.85rem;
}
/* Column View buttons + Assigned filter — deliberately separate from the
   search/customer filter to their left (two different concepts: WHAT
   columns show, and WHO it's assigned to — neither is WHICH orders show,
   that's the customer filter and the workflow tabs below). Pushed into the
   unused right-hand space via margin-left:auto on the first of the two;
   Assigned just follows it in normal flex order, so both hug the right
   edge as one group. Wraps to its own line on narrow viewports like the
   rest of .ob-master-search — the whole row stays horizontal at normal
   desktop widths, which is what there's room for. */
.ob-view-control {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.3rem;
    flex-wrap: wrap;
}
.ob-view-btn { white-space: nowrap; }
#obViewAddBtn, #obViewEditBtn { padding: 0.2rem 0.5rem; font-size: 0.85rem; }
.ob-assigned-control {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.ob-assigned-control label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--mid-gray);
    white-space: nowrap;
}
.ob-assigned-control select { max-width: 260px; }

/* View modal — create/edit one of this user's Orders Board views. */
.ob-cv-modal {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,.5);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.ob-cv-modal.hidden { display: none; }
.ob-cv-modal__box {
    background: var(--white);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    width: 100%;
    max-width: 420px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 8px 32px rgba(0,0,0,.18);
}
.ob-cv-modal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.9rem;
}
.ob-cv-modal__head h3 { margin: 0; font-size: 1rem; font-family: var(--font-serif); }
.ob-cv-modal__close {
    background: none;
    border: none;
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
    color: var(--mid-gray);
    padding: 0.2rem 0.45rem;
}
.ob-cv-modal__close:hover { color: var(--near-black); }
.ob-cv-modal__label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--mid-gray);
    margin-bottom: 0.4rem;
}
.ob-cv-modal__columns {
    overflow-y: auto;
    max-height: 40vh;
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    padding: 0.5rem 0.75rem;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.3rem 0.6rem;
}
.ob-cv-modal__col {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.83rem;
    cursor: pointer;
    padding: 0.1rem 0;
}
.ob-cv-modal__col input { margin: 0; cursor: pointer; flex-shrink: 0; }
.ob-cv-modal__default-check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.83rem;
    font-weight: normal;
    color: var(--dark-gray);
    cursor: pointer;
    margin-top: 0.85rem;
}
.ob-cv-modal__default-check input { margin: 0; cursor: pointer; flex-shrink: 0; }
.ob-cv-modal__actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 1rem;
}
.ob-cv-modal__status {
    font-size: 0.78rem;
    color: var(--danger);
    min-height: 1em;
    margin-top: 0.4rem;
}
@media (max-width: 480px) {
    .ob-cv-modal__columns { grid-template-columns: 1fr; }
}

/* Assigned cell — a compact button, not a wide always-open control, so a
   multi-person order doesn't need a taller row to stay readable. */
.ob-assign-trigger {
    display: block;
    width: 100%;
    max-width: 150px;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    padding: 0.15rem 0.3rem;
    font: inherit;
    font-size: 0.85rem;
    color: var(--near-black);
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}
.ob-assign-trigger:hover { background: var(--off-white); border-color: var(--pale-gray); }
.ob-assign-bubble { width: 230px; }
.ob-assign-bubble__list {
    max-height: 220px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.ob-assign-bubble__item {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.85rem;
    cursor: pointer;
    padding: 0.15rem 0;
}
.ob-assign-bubble__item input { margin: 0; cursor: pointer; flex-shrink: 0; }
.ob-assign-bubble__actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 0.6rem;
    gap: 0.5rem;
}
.ops-board-tabs {
    display: flex;
    gap: 0.35rem;
    flex-wrap: wrap;
    padding: 0.6rem 1.25rem;
    border-bottom: 1px solid var(--pale-gray);
}
.ops-board-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.8rem;
    font-size: 0.8rem;
    font-weight: 500;
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    background: var(--white);
    color: var(--mid-gray);
    text-decoration: none;
    transition: background .12s, border-color .12s, color .12s;
}
.ops-board-tab:hover  { border-color: #bbb; color: var(--near-black); }
.ops-board-tab.active { background: var(--near-black); border-color: var(--near-black); color: #fff; }
.ops-board-tab__count {
    font-size: 0.68rem;
    background: rgba(255,255,255,.18);
    border-radius: 10px;
    padding: 0.05rem 0.45rem;
}
.ops-board-tab:not(.active) .ops-board-tab__count { background: var(--pale-gray); color: var(--mid-gray); }
.ops-board-wrap {
    overflow: auto;
    max-height: 70vh;
}
.ops-board-wrap table.req-table thead th {
    position: sticky;
    top: 0;
    background: var(--white);
    z-index: 1;
}
.ops-board-empty {
    padding: 3rem 1.5rem;
    text-align: center;
    color: var(--mid-gray);
    font-size: 0.88rem;
}
.ob-sortable th.ob-sort { user-select: none; }
.ob-sortable th.ob-sort:hover { color: var(--dark-gray); }
.ob-sort--asc::after  { content: ' \25B2'; font-size: .6em; opacity: .7; }
.ob-sort--desc::after { content: ' \25BC'; font-size: .6em; opacity: .7; }

/* ── Clamped preview cells (Notes/Timeline/Print) — 2 lines max, click to
   expand into a bubble with the full text ────────────────────────────────── */
.ob-clamp-preview {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    width: 100%;
    max-width: 100%;
    overflow-wrap: anywhere;
    font-size: .8rem;
    line-height: 1.3;
    color: var(--dark-gray);
    cursor: pointer;
    border-radius: var(--radius-sm);
    padding: .1rem .2rem;
}
.ob-clamp-preview:hover  { background: var(--off-white); }
.ob-clamp-preview:empty::before { content: attr(data-placeholder); color: var(--light-gray); }

/* ── Row-color dot — compact trigger for the color popover ─────────────────── */
.ob-color-dot {
    width: 16px; height: 16px;
    border-radius: 50%;
    border: 1px solid var(--pale-gray);
    background: var(--white);
    cursor: pointer;
    padding: 0;
    display: block;
    margin: 0 auto;
}
.ob-color-dot--set { border-color: transparent; }
.ob-color-dot:hover { transform: scale(1.15); box-shadow: 0 0 0 2px var(--pale-gray); }

/* ── Shared popovers (text-edit bubble + color-swatch bubble) ──────────────── */
.ob-popover {
    position: absolute;
    z-index: 500;
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-md);
    box-shadow: 0 6px 24px rgba(0,0,0,.14);
    padding: .65rem;
    display: none;
}
.ob-popover.open { display: block; }
.ob-text-bubble { width: 280px; }
.ob-text-bubble__body {
    min-height: 3.5rem;
    max-height: 40vh;
    overflow-y: auto;
    font-size: .85rem;
    line-height: 1.45;
    color: var(--near-black);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    padding: .5rem .6rem;
    white-space: pre-wrap;
}
.ob-text-bubble__body:focus { outline: none; border-color: #aaa; }
.ob-text-bubble__actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: .5rem;
    font-size: .75rem;
    gap: .5rem;
}
.ob-text-bubble__right { display: flex; align-items: center; gap: .5rem; color: var(--mid-gray); }
.ob-color-bubble__grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: .4rem;
}
.ob-color-swatch {
    width: 22px; height: 22px;
    border-radius: 50%;
    border: 1px solid var(--pale-gray);
    cursor: pointer;
    padding: 0;
}
.ob-color-swatch--none {
    background: var(--white);
    color: var(--mid-gray);
    font-size: .7rem;
    line-height: 20px;
}
.ob-color-swatch:hover { transform: scale(1.12); }
.ops-board-editable {
    display: block;
    min-width: 3.5rem;
    padding: 0.08rem 0.25rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    cursor: text;
    font-size: .8rem;
    line-height: 1.3;
    color: var(--dark-gray);
}
.ops-board-editable:hover  { border-color: var(--pale-gray); background: var(--off-white); }
.ops-board-editable:empty::before { content: attr(data-placeholder); color: var(--light-gray); }
.ops-board-editable.saving { opacity: .5; }
/* Money fields sit after a literal "$" in the same cell (see orders-board.php)
   — block display drops them to their own line, stacking "$" over "0.00"
   instead of reading "$0.00". admin/request.php already works around this
   with an inline style; make it the rule for every money field instead. */
.ops-board-editable[data-field="price"],
.ops-board-editable[data-field="final_price"],
.ops-board-editable[data-field="deposit_amount"] { display: inline-block; }
.ops-board-editable.saved  { border-color: #22c55e; }
.ops-board-editable.error  { border-color: #ef4444; }
.ops-board-hold-toggle { cursor: pointer; }
@media (max-width: 620px) {
    .ops-board-wrap { max-height: 55vh; }
}

/* Row items (shared by Attention + Next Up) */
.ops-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 1.25rem;
    border-bottom: 1px solid var(--pale-gray);
    font-size: 0.855rem;
    text-decoration: none;
    color: inherit;
}
.ops-item:last-child { border-bottom: none; }
.ops-item:hover { background: var(--off-white); }

.ops-item__reason {
    flex-shrink: 0;
    min-width: 116px;
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: var(--radius-sm);
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    text-align: center;
    border: 1px solid transparent;
}
.ops-reason--bed      { background:#fff7ed; color:#c2410c; border-color:#fed7aa; }
.ops-reason--printing { background:#eff6ff; color:#1d4ed8; border-color:#bfdbfe; }
.ops-reason--postproc { background:#f5f3ff; color:#6d28d9; border-color:#ddd6fe; }
.ops-reason--payment  { background:#fef2f2; color:#991b1b; border-color:#fecaca; }
.ops-reason--overdue  { background:#fef2f2; color:#991b1b; border-color:#fecaca; }
.ops-reason--review   { background:#fffbeb; color:#92400e; border-color:#fde68a; }
.ops-reason--waiting  { background:#fef3c7; color:#92400e; border-color:#fde68a; }
.ops-reason--fulfillment { background:#ecfdf5; color:#047857; border-color:#a7f3d0; }

.ops-item__name {
    font-weight: 600;
    color: var(--near-black);
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ops-item__client {
    font-size: 0.77rem;
    color: var(--mid-gray);
    white-space: nowrap;
    flex-shrink: 0;
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ops-item__meta {
    font-size: 0.75rem;
    color: var(--mid-gray);
    flex-shrink: 0;
    white-space: nowrap;
}
.ops-item__id {
    font-size: 0.7rem;
    color: var(--light-gray);
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
    min-width: 32px;
    text-align: right;
}

/* Empty states */
.ops-empty {
    padding: 1.5rem 1.25rem;
    color: var(--mid-gray);
    font-size: 0.875rem;
    text-align: center;
}
.ops-empty--ok { color: #16a34a; }

/* Quick Intake buttons */
.ops-intake {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 1.25rem;
}
.ops-intake-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.6rem 1.1rem;
    background: var(--near-black);
    color: var(--white);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font-size: 0.855rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    font-family: inherit;
    transition: background var(--transition);
    white-space: nowrap;
}
.ops-intake-btn:hover { background: #2d2d2d; color: var(--white); text-decoration: none; }
.ops-intake-btn--ghost {
    background: var(--white);
    color: var(--near-black);
    border-color: var(--pale-gray);
}
.ops-intake-btn--ghost:hover { background: var(--off-white); color: var(--near-black); }

/* Task rows */
.ops-task-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.8rem 1.25rem;
    border-bottom: 1px solid var(--pale-gray);
}
.ops-task-item:last-child { border-bottom: none; }
.ops-task-item__title {
    flex: 1;
    font-weight: 500;
    font-size: 0.88rem;
    color: var(--near-black);
}
.ops-task-item__desc {
    font-size: 0.77rem;
    color: var(--mid-gray);
    margin-top: 0.15rem;
}
.ops-task-item__time {
    font-size: 0.77rem;
    color: var(--mid-gray);
    flex-shrink: 0;
    white-space: nowrap;
}
.ops-task-item__cat {
    font-size: 0.66rem;
    background: var(--off-white);
    border: 1px solid var(--pale-gray);
    color: var(--mid-gray);
    padding: 0.1rem 0.45rem;
    border-radius: var(--radius-sm);
    flex-shrink: 0;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}

/* Two-column layout for Needs Attention + Quick Intake side by side */
.ops-grid {
    display: grid;
    grid-template-columns: 1fr 300px;
    gap: 1.25rem;
    align-items: start;
}
@media (max-width: 960px) {
    .ops-grid { grid-template-columns: 1fr; }
}

.content-page section:last-child { border-bottom: none; }

/* About page — creator/collaboration callout. Noticeable but not
   dominant: a bordered, lightly-accented card rather than a full hero,
   staying inside .content-page's normal 720px reading width. */
.about-creator-callout__box {
    border: 1.5px solid var(--near-black);
    border-radius: var(--radius-lg);
    padding: 1.5rem 1.75rem;
}
.about-creator-callout__eyebrow {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 1.6rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--dark-gray);
    margin-bottom: 0.5rem;
}

/* ── Priority badges (shared admin pages) ───────────────────────────────────── */
.pri-badge          { display:inline-block; padding:.15rem .45rem; border-radius:var(--radius-sm);
                      font-size:.68rem; font-weight:700; text-transform:uppercase;
                      letter-spacing:.04em; white-space:nowrap; }
.pri-badge--rush    { background:#fee2e2; color:#991b1b; }
.pri-badge--high    { background:#fed7aa; color:#c2410c; }
.pri-badge--low     { background:#f9fafb; color:#9ca3af; }

/* ── Status badges (shared admin + client pages) ─────────────────────────────────
   Was previously copy-pasted into 4 separate <style> blocks (admin/requests.php,
   admin/order-history.php, client/index.php, + one missing entirely) and had
   already drifted — some copies had .req-badge--quoted, some didn't. Same root
   cause as the .nj-* and .card gaps found earlier — centralized here so it can't
   happen a third time. ────────────────────────────────────────────────────── */
.req-badge                       { display:inline-block; padding:.15rem .5rem; border-radius:var(--radius-sm);
                                   font-size:.68rem; font-weight:600; text-transform:uppercase; letter-spacing:.04em; white-space:nowrap; }
.req-badge--pending              { background:#f3f4f6; color:#6b7280; }
.req-badge--reviewed             { background:#dbeafe; color:#1d4ed8; }
.req-badge--quoted               { background:#e0e7ff; color:#4338ca; }
.req-badge--approved             { background:#d1fae5; color:#065f46; }
.req-badge--deposit_received     { background:#ccfbf1; color:#0f766e; }
.req-badge--in_progress          { background:#fed7aa; color:#c2410c; }
.req-badge--completed            { background:#dcfce7; color:#166534; }
.req-badge--cancelled            { background:#fee2e2; color:#991b1b; }

/* ── Waiting-on-customer badges ───────────────────────────────────────────────
   Orthogonal to status/job_status (same as the on_hold flag) — a job can be
   "Approved" or "In Progress" and *also* waiting on the customer for one of
   these. ─────────────────────────────────────────────────────────────────── */
.wait-badge                { display:inline-block; padding:.15rem .5rem; border-radius:var(--radius-sm);
                             font-size:.68rem; font-weight:600; text-transform:uppercase; letter-spacing:.04em; white-space:nowrap; }
.wait-badge--response      { background:#fef3c7; color:#92400e; }
.wait-badge--pictures      { background:#e0f2fe; color:#075985; }
.wait-badge--measurements  { background:#ede9fe; color:#6d28d9; }
.wait-badge--approval      { background:#fce7f3; color:#9d174d; }
.wait-badge--parts         { background:#dcfce7; color:#166534; }
.wait-badge--pickup_payment { background:#ffe4e6; color:#9f1239; }

/* ── Jobs filter tabs ────────────────────────────────────────────────────────── */
.req-filters           { display:flex; gap:.4rem; flex-wrap:wrap; margin-bottom:1rem; }
.req-filter-btn        { display:inline-block; padding:.3rem .85rem; font-size:.8rem; font-weight:500;
                         border:1px solid var(--pale-gray); border-radius:var(--radius-sm);
                         background:var(--white); color:var(--mid-gray); text-decoration:none;
                         transition:background .12s, border-color .12s, color .12s; }
.req-filter-btn:hover  { border-color:#bbb; color:var(--near-black); }
.req-filter-btn.active { background:var(--near-black); border-color:var(--near-black); color:#fff; }
.req-filter-btn__count { font-size:.68rem; margin-left:.3rem; opacity:.7; }

/* ── Jobs table ──────────────────────────────────────────────────────────────── */
.req-table               { width:100%; border-collapse:collapse; font-size:.83rem; table-layout:auto; line-height:1.3; }
.req-table th            { text-align:left; font-size:.68rem; font-weight:600; text-transform:uppercase;
                           letter-spacing:.05em; color:var(--mid-gray); padding:.4rem .65rem;
                           border-bottom:1px solid var(--pale-gray); white-space:nowrap; }
.req-table td            { padding:.4rem .65rem; border-bottom:1px solid var(--pale-gray);
                           color:var(--dark-gray); vertical-align:middle; }
.req-table tr:last-child td         { border-bottom:none; }
.req-table tr:hover td              { background:var(--off-white); }
.req-table tr[data-urgent] td       { background:#fff8f8; }
.req-table tr[data-bed-ready] td    { background:#fff7ed; }
.req-table tr[data-bed-ready]:hover td { background:#ffedd5; }
.req-table tr[data-bed-ready] > td:first-child { border-left:3px solid #f97316; }

/* ── Inline select ───────────────────────────────────────────────────────────── */
.req-select-inline        { font-size:.76rem; padding:.15rem .4rem; border:1px solid var(--pale-gray);
                            border-radius:var(--radius-sm); background:var(--white); cursor:pointer;
                            color:var(--dark-gray); font-family:inherit; transition:border-color .15s; }
.req-select-inline:focus  { outline:none; border-color:#aaa; }
.req-select-inline.saving { opacity:.5; pointer-events:none; }
.req-select-inline.saved  { border-color:#22c55e; }
.req-select-inline.error  { border-color:#ef4444; }

/* ── Job status badges ───────────────────────────────────────────────────────── */
.job-badge                           { display:inline-block; padding:.18rem .55rem; border-radius:var(--radius-sm);
                                       font-size:.68rem; font-weight:600; text-transform:uppercase;
                                       letter-spacing:.04em; white-space:nowrap; }
.job-badge--queued                   { background:#f3f4f6; color:#6b7280; }
.job-badge--ready-to-print           { background:#dbeafe; color:#1d4ed8; }
.job-badge--printing                 { background:#ffedd5; color:#c2410c; }
.job-badge--finished-on-bed          { background:#fef9c3; color:#854d0e; }
.job-badge--post-processing          { background:#f3e8ff; color:#7e22ce; }
.job-badge--ready-for-pickup-or-ship { background:#ccfbf1; color:#0f766e; }
.job-badge--completed                { background:#dcfce7; color:#166534; }

/* ── Print column (jobs.php) ─────────────────────────────────────────────────── */
.btn-start-print          { padding:.25rem .65rem; font-size:.78rem; font-weight:600;
                            background:var(--near-black); color:#fff; border:none;
                            border-radius:var(--radius-sm); cursor:pointer; font-family:inherit;
                            white-space:nowrap; transition:background .12s; }
.btn-start-print:hover    { background:#2d2d2d; }

.btn-remove-bed           { padding:.25rem .65rem; font-size:.78rem; font-weight:700;
                            background:#ea580c; color:#fff; border:none;
                            border-radius:var(--radius-sm); cursor:pointer; font-family:inherit;
                            white-space:nowrap; transition:background .12s;
                            animation:pulse-orange 1.6s ease-in-out infinite; }
.btn-remove-bed:hover     { background:#c2410c; animation:none; }
.btn-remove-bed:disabled  { opacity:.5; cursor:not-allowed; animation:none; }

@keyframes pulse-orange {
    0%, 100% { box-shadow:0 0 0 0 rgba(234,88,12,.4); }
    50%       { box-shadow:0 0 0 5px rgba(234,88,12,0); }
}

.bed-ready-badge  { display:inline-block; padding:.15rem .45rem; margin-bottom:.3rem;
                    background:#fff7ed; color:#c2410c; border:1px solid #fed7aa;
                    border-radius:var(--radius-sm); font-size:.65rem; font-weight:700;
                    text-transform:uppercase; letter-spacing:.05em; }

.print-countdown         { display:block; font-size:.78rem; color:var(--mid-gray); white-space:nowrap; }
.print-countdown.expired { color:#ea580c; font-weight:600; }
.print-started           { font-size:.72rem; color:var(--light-gray); margin-top:.1rem; }

/* ── Jobs table cells ────────────────────────────────────────────────────────── */
.jobs-id        { font-size:.75rem; color:var(--mid-gray); font-variant-numeric:tabular-nums; }
.jobs-client    { font-weight:600; font-size:.855rem; color:var(--near-black); }
.jobs-client a  { color:inherit; text-decoration:none; border-bottom:1px dotted var(--mid-gray); }
.jobs-client a:hover { border-bottom-style:solid; }
.jobs-email     { font-size:.73rem; color:var(--mid-gray); }
.jobs-phone     { font-size:.73rem; color:var(--mid-gray); }
.jobs-date      { font-size:.77rem; color:var(--mid-gray); white-space:nowrap; }
.jobs-qty       { font-variant-numeric:tabular-nums; text-align:center; }
.jobs-view      { font-size:.78rem; color:var(--mid-gray); text-decoration:none; white-space:nowrap; }
.jobs-view:hover { color:var(--near-black); text-decoration:underline; }
.admin-main     { overflow-x:auto; }

/* ── Start Print modal (shared) ──────────────────────────────────────────────── */
.sp-modal              { position:fixed; inset:0; background:rgba(0,0,0,.45);
                         display:none; align-items:center; justify-content:center; z-index:1000; }
.sp-modal.open         { display:flex; }
.sp-modal-box          { background:var(--white); border-radius:var(--radius-lg); padding:1.5rem;
                         max-width:380px; width:100%; margin:1rem;
                         box-shadow:0 8px 32px rgba(0,0,0,.15); }
.sp-modal-title        { font-size:1rem; font-weight:700; margin:0 0 .25rem; font-family:var(--font-serif); }
.sp-modal-job          { font-size:.83rem; color:var(--mid-gray); margin:0 0 1.25rem; }
.sp-duration           { display:flex; gap:1rem; align-items:flex-end; }
.sp-duration-field label { display:block; font-size:.72rem; font-weight:600;
                           text-transform:uppercase; letter-spacing:.05em;
                           color:var(--mid-gray); margin-bottom:.3rem; }
.sp-duration-field input { width:72px; padding:.35rem .5rem; font-size:1rem; font-weight:600;
                           border:1px solid var(--pale-gray); border-radius:var(--radius-sm);
                           font-family:inherit; text-align:center; }
.sp-duration-field input:focus { outline:none; border-color:#aaa; }
.sp-eta-preview        { margin-top:.9rem; font-size:.8rem; color:var(--mid-gray); }
.sp-eta-preview strong { color:var(--near-black); }
.sp-modal-actions      { display:flex; gap:.5rem; justify-content:flex-end; margin-top:1.25rem; }

/* ── Ops: Needs Bed Removal section ──────────────────────────────────────────── */
.ops-section--bed                             { border-color:#fbd0c0; margin-bottom:1.25rem; }
.ops-section--bed .ops-section__header        { background:#fff4ee; border-bottom-color:#fbd0c0; }
.ops-section--bed .ops-section__title         { color:#9a3412; }
.ops-section--bed .ops-section__count--alert  { background:#fbd0c0; color:#7c2d12; }
.ops-item--bed                                { background:#fff4ee; border-bottom-color:#fbd0c0; }
.ops-item--bed:hover                          { background:#ffe4d6; }

.ops-overdue-time { font-size:.73rem; color:#ea580c; font-weight:600; white-space:nowrap; flex-shrink:0; }

.ops-bed-btn          { flex-shrink:0; padding:.28rem .7rem; background:#ea580c; color:#fff; border:none;
                        border-radius:var(--radius-sm); font-size:.78rem; font-weight:700; cursor:pointer;
                        font-family:inherit; white-space:nowrap; transition:background .12s;
                        animation:pulse-ops 1.8s ease-in-out infinite; }
.ops-bed-btn:hover    { background:#c2410c; animation:none; }
.ops-bed-btn:disabled { opacity:.5; cursor:not-allowed; animation:none; }

@keyframes pulse-ops {
    0%, 100% { box-shadow:0 0 0 0 rgba(234,88,12,.35); }
    50%       { box-shadow:0 0 0 5px rgba(234,88,12,0); }
}

.ops-print-countdown              { font-size:.78rem; color:var(--mid-gray); white-space:nowrap; }
.ops-snap-card--bed-alert         { border-color:#fbd0c0; background:#fff4ee; }
.ops-snap-card--bed-alert .ops-snap-card__value { color:#dc2626; }

/* ── Ops: Printing Now section ───────────────────────────────────────────────── */
.ops-section--printing .ops-section__header { background:#fff8f0; }
.ops-section--printing .ops-section__title  { color:#9a3412; }

.ops-pi-item              { display:flex; align-items:center; gap:.6rem; flex-wrap:wrap;
                            padding:.8rem 1.25rem; border-bottom:1px solid var(--pale-gray); }
.ops-pi-item:last-child   { border-bottom:none; }
.ops-pi-name              { flex:1; font-weight:600; font-size:.88rem; color:var(--near-black); min-width:120px; }
.ops-pi-client            { font-size:.77rem; color:var(--mid-gray); flex-shrink:0; }
.ops-pi-qty               { font-size:.77rem; color:var(--mid-gray); flex-shrink:0; }
.ops-pi-timer             { font-size:.82rem; font-weight:600; color:var(--mid-gray);
                            white-space:nowrap; flex-shrink:0; }
.ops-pi-timer.expired     { color:#ea580c; }
.ops-pi-clock             { font-size:.73rem; color:var(--light-gray); white-space:nowrap; flex-shrink:0; }
.ops-pi-start             { font-size:.73rem; color:var(--light-gray); flex-shrink:0; }

/* ── Ops: audio toggle ───────────────────────────────────────────────────────── */
.ops-audio-toggle        { display:inline-flex; align-items:center; gap:.4rem; font-size:.77rem;
                           color:var(--mid-gray); cursor:pointer; user-select:none;
                           padding:.25rem .55rem; border:1px solid var(--pale-gray);
                           border-radius:var(--radius-sm); background:var(--white);
                           transition:border-color .12s, color .12s; }
.ops-audio-toggle:hover  { border-color:#aaa; color:var(--near-black); }
.ops-audio-toggle input  { margin:0; cursor:pointer; }

/* ── Phase 2: Overdue rows and badges ────────────────────────────────────────── */
.overdue-badge            { display:inline-block; padding:.1rem .35rem; border-radius:var(--radius-sm);
                            background:#fee2e2; color:#991b1b; font-size:.65rem; font-weight:700;
                            text-transform:uppercase; letter-spacing:.03em; vertical-align:middle;
                            margin-left:.25rem; }

tr[data-overdue="1"]      { background:#fff5f5 !important; }
tr[data-overdue="1"]:hover { background:#fee2e2 !important; }
tr[data-overdue="1"] td   { border-bottom-color:#fecaca; }

.ops-item--overdue        { background:#fff5f5; border-bottom-color:#fecaca; }
.ops-item--overdue:hover  { background:#fee2e2; }

/* ── Phase 2: Assignment select ──────────────────────────────────────────────── */
.job-assign-select        { max-width:140px; }

/* ── Up Next (Google Tasks note) ─────────────────────────────────────────────── */
.ops-section--upnext               { border-color:#fde68a; }
.ops-section--upnext .ops-section__header { background:#fffbeb; }
.ops-section--upnext .ops-section__title  { color:#92400e; }

.ops-upnext-list  { list-style:none; margin:0; padding:0; }
.ops-upnext-item  { padding:.65rem 1.25rem; border-bottom:1px solid var(--pale-gray);
                    font-size:.875rem; color:var(--near-black); }
.ops-upnext-item:last-child { border-bottom:none; }
.ops-upnext-item__notes { margin-top:.2rem; font-size:.78rem; color:var(--mid-gray); }

/* ── Phase 2: My Active Work section ─────────────────────────────────────────── */
.ops-section--mywork               { border-color:#dbeafe; }
.ops-section--mywork .ops-section__header { background:#eff6ff; }
.ops-section--mywork .ops-section__title  { color:#1e40af; }

.ops-mywork-item          { gap:.55rem; }
.ops-mywork-timer         { font-size:.8rem; font-weight:600; color:#1d4ed8; }
.ops-mywork-timer.expired { color:#ea580c; }

/* ── Phase 2: Task claim buttons ─────────────────────────────────────────────── */
.ops-task-claim-btn       { flex-shrink:0; padding:.25rem .65rem; background:#1d4ed8; color:#fff;
                            border:none; border-radius:var(--radius-sm); font-size:.77rem;
                            font-weight:600; cursor:pointer; font-family:inherit;
                            transition:background .12s; white-space:nowrap; }
.ops-task-claim-btn:hover    { background:#1e40af; }
.ops-task-claim-btn:disabled { opacity:.5; cursor:not-allowed; }

/* ── Phase 2: Task complete row ──────────────────────────────────────────────── */
.ops-mywork-task          { flex-wrap:wrap; }
.ops-task-complete-wrap   { display:flex; align-items:center; gap:.4rem; flex-shrink:0; }
.ops-task-note            { width:130px; padding:.22rem .45rem; font-size:.77rem;
                            border:1px solid var(--pale-gray); border-radius:var(--radius-sm);
                            font-family:inherit; color:var(--near-black); }
.ops-task-note:focus      { outline:none; border-color:#6366f1; box-shadow:0 0 0 2px rgba(99,102,241,.12); }
.ops-task-complete-btn    { flex-shrink:0; padding:.22rem .65rem; background:#059669; color:#fff;
                            border:none; border-radius:var(--radius-sm); font-size:.77rem;
                            font-weight:600; cursor:pointer; font-family:inherit;
                            transition:background .12s; white-space:nowrap; }
.ops-task-complete-btn:hover    { background:#047857; }
.ops-task-complete-btn:disabled { opacity:.5; cursor:not-allowed; }

/* ── Phase 2: Tasks admin page toggle buttons ────────────────────────────────── */
.tasks-toggle-btn         { padding:.2rem .5rem; border-radius:var(--radius-sm); border:1px solid;
                            font-size:.73rem; font-weight:600; cursor:pointer; font-family:inherit;
                            transition:background .12s, color .12s; }
.tasks-toggle-btn--on     { background:#d1fae5; color:#065f46; border-color:#6ee7b7; }
.tasks-toggle-btn--on:hover  { background:#a7f3d0; }
.tasks-toggle-btn--off    { background:#f3f4f6; color:#9ca3af; border-color:#d1d5db; }
.tasks-toggle-btn--off:hover { background:#e5e7eb; color:#374151; }

/* ── Phase 3: Request detail page ────────────────────────────────────────────── */
.req-detail-header           { display:flex; align-items:flex-start; gap:1rem; flex-wrap:wrap;
                               margin-bottom:1.25rem; padding-bottom:1rem;
                               border-bottom:1px solid var(--pale-gray); }
.req-detail-header__back     { display:flex; gap:.6rem; align-items:center; width:100%; }
.req-detail-back             { font-size:.8rem; color:var(--mid-gray); text-decoration:none;
                               padding:.2rem .5rem; border:1px solid var(--pale-gray);
                               border-radius:var(--radius-sm); transition:border-color .12s; }
.req-detail-back:hover       { border-color:#aaa; color:var(--near-black); }
.req-detail-header__main     { flex:1; min-width:0; }
.req-detail-title            { margin:0 0 .35rem; font-size:1.2rem; font-weight:700;
                               color:var(--near-black); line-height:1.3; }
.req-detail-badges           { display:flex; gap:.35rem; flex-wrap:wrap; align-items:center; }
.req-detail-header__id       { font-size:1.6rem; font-weight:700; color:var(--light-gray);
                               letter-spacing:-.03em; flex-shrink:0; }

/* Job-status badge colors */
.rdb                         { display:inline-block; padding:.18rem .5rem;
                               border-radius:var(--radius-sm); font-size:.72rem;
                               font-weight:600; border:1px solid transparent; }
.rdb--queued                 { background:#f3f4f6; color:#374151; border-color:#e5e7eb; }
.rdb--ready_to_print         { background:#dbeafe; color:#1e40af; border-color:#bfdbfe; }
.rdb--printing               { background:#ffedd5; color:#9a3412; border-color:#fed7aa; }
.rdb--finished_on_bed        { background:#fef9c3; color:#854d0e; border-color:#fde68a; }
.rdb--post_processing        { background:#ede9fe; color:#5b21b6; border-color:#ddd6fe; }
.rdb--ready_for_pickup_or_ship { background:#d1fae5; color:#065f46; border-color:#6ee7b7; }
.rdb--completed              { background:#f0fdf4; color:#166534; border-color:#bbf7d0; }
.rdb--status                 { background:#f9fafb; color:#6b7280; border-color:#e5e7eb; }

/* Detail grid */
.req-detail-grid             { display:grid; grid-template-columns:1fr 380px; gap:1.25rem;
                               align-items:start; }
@media (max-width:860px) {
    .req-detail-grid         { grid-template-columns:1fr; }
    .req-detail-right        { order:-1; }
}

.req-detail-card             { background:var(--white); border:1px solid var(--pale-gray);
                               border-radius:var(--radius-lg); padding:.85rem 1rem;
                               margin-bottom:.85rem; }
.req-detail-card:last-child  { margin-bottom:0; }
.req-detail-card--timeline   { padding-bottom:.65rem; }
.req-detail-card__title      { font-size:.92rem; font-weight:700; text-transform:uppercase;
                               letter-spacing:.04em; color:var(--mid-gray); margin-bottom:.55rem; }

.req-detail-field            { display:flex; gap:.6rem; align-items:baseline;
                               padding:.22rem 0; border-bottom:1px solid var(--off-white); }
.req-detail-field:last-child { border-bottom:none; }
.req-detail-field--block     { flex-direction:column; gap:.25rem; }
.req-detail-field__lbl       { font-size:.75rem; color:var(--mid-gray); min-width:90px;
                               flex-shrink:0; }
.req-detail-field__val       { font-size:.87rem; color:var(--near-black); }
.req-detail-paid             { color:#059669; font-weight:600; }

.req-detail-quick-form       { margin:0; }

/* ── Phase 3: Activity timeline ──────────────────────────────────────────────── */
.act-timeline                { list-style:none; margin:0 0 .75rem; padding:0; }

.act-entry                   { display:flex; gap:.7rem; padding:.55rem 0;
                               border-bottom:1px solid var(--off-white); }
.act-entry:last-child        { border-bottom:none; }

.act-entry__icon             { flex-shrink:0; width:1.5rem; height:1.5rem; border-radius:50%;
                               display:flex; align-items:center; justify-content:center;
                               font-size:.7rem; font-weight:700; margin-top:.1rem;
                               background:var(--pale-gray); color:var(--mid-gray); }

/* Icon colors by type */
.act-entry--created .act-entry__icon   { background:#dbeafe; color:#1e40af; }
.act-entry--ok .act-entry__icon        { background:#d1fae5; color:#059669; }
.act-entry--assigned .act-entry__icon  { background:#ede9fe; color:#7c3aed; }
.act-entry--print .act-entry__icon     { background:#ffedd5; color:#ea580c; }
.act-entry--invoice .act-entry__icon   { background:#e0f2fe; color:#0369a1; }
.act-entry--payment .act-entry__icon   { background:#d1fae5; color:#059669; }
.act-entry--note .act-entry__icon      { background:#fef9c3; color:#854d0e; }
.act-entry--neutral .act-entry__icon   { background:#f3f4f6; color:#6b7280; }
.act-entry--status .act-entry__icon    { background:#f3f4f6; color:#374151; }

.act-entry__body             { flex:1; min-width:0; }
.act-entry__header           { display:flex; align-items:baseline; gap:.45rem; flex-wrap:wrap;
                               margin-bottom:.15rem; }
.act-entry__type             { font-size:.72rem; font-weight:700; text-transform:uppercase;
                               letter-spacing:.04em; color:var(--mid-gray); }
.act-entry__actor            { font-size:.77rem; font-weight:600; color:var(--near-black); }
.act-entry__time             { font-size:.72rem; color:var(--light-gray); margin-left:auto;
                               white-space:nowrap; flex-shrink:0; }
.act-entry__msg              { font-size:.83rem; color:var(--near-black); line-height:1.45;
                               word-break:break-word; }

/* Note form */
.act-note-form               { margin-top:.5rem; border-top:1px solid var(--pale-gray);
                               padding-top:.65rem; }
.act-note-input              { width:100%; padding:.45rem .6rem; font-size:.83rem;
                               border:1px solid var(--pale-gray); border-radius:var(--radius-sm);
                               font-family:inherit; color:var(--near-black); resize:vertical;
                               box-sizing:border-box; }
.act-note-input:focus        { outline:none; border-color:#6366f1;
                               box-shadow:0 0 0 2px rgba(99,102,241,.12); }

/* ── Commerce Hub: Alert helpers ────────────────────────────────────────────── */
.alert-success               { background:#e8f5e9; border:1px solid #a5d6a7; color:#2e7d32;
                               border-radius:var(--radius-md); padding:.75rem 1rem;
                               font-size:.875rem; }
.alert-danger,
.alert-error                 { background:#fce4ec; border:1px solid #f48fb1; color:#c62828;
                               border-radius:var(--radius-md); padding:.75rem 1rem;
                               font-size:.875rem; }

/* ── Card ─────────────────────────────────────────────────────────────────────
   Used across ~14 pages (products, requests, users, leads, wix-listings,
   wix-contacts, portfolio, categories, account, forgot/reset-password, etc.)
   but was never actually defined anywhere, global or local — every one of
   those has been silently rendering as a bare unstyled div this whole time.
   ────────────────────────────────────────────────────────────────────────── */
.card {
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
}

/* ── Card title small ────────────────────────────────────────────────────────── */
.card-title-sm               { font-size:1rem; margin-bottom:1rem;
                               font-family:var(--font-serif); }

/* ── Button extra-small ──────────────────────────────────────────────────────── */
.btn-xs                      { padding:.15rem .45rem; font-size:.72rem; font-weight:600;
                               border-radius:var(--radius-sm); }

/* ═══════════════════════════════════════════════════════════════════════════════
   Commerce Hub: edit-product.php — ep-* layout
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Two-column product editor grid */
.ep-grid                     { display:grid; grid-template-columns:1fr 360px; gap:1.25rem;
                               align-items:start; }
@media (max-width:900px) {
    .ep-grid                 { grid-template-columns:1fr; }
    .ep-right                { order:-1; }
}

/* Section cards — an optional --section-accent (set inline per section,
   e.g. admin/edit-product.php) draws a colored left stripe so a page of
   otherwise-identical cards reads apart at a glance. Falls back to the
   plain pale-gray border when unset, so any .ep-section that doesn't
   opt in looks exactly as it always has. */
.ep-section                  { background:var(--white); border:1px solid var(--pale-gray);
                               border-left:3px solid var(--section-accent, var(--pale-gray));
                               border-radius:var(--radius-lg); margin-bottom:1rem;
                               overflow:hidden; }
.ep-section:last-child       { margin-bottom:0; }
.ep-section__title           { padding:.75rem 1.1rem; background:var(--off-white);
                               border-bottom:1px solid var(--pale-gray);
                               font-size:1.15rem; font-weight:700; text-transform:uppercase;
                               letter-spacing:.04em; color:var(--dark-gray); }
.ep-section__body            { padding:1rem 1.1rem; }

/* .ep-section cards are <details>/<summary> (collapsible, admin/edit-
   product.php) — the native disclosure marker is inconsistent across
   browsers and disappears entirely on any summary using inline
   display:flex (several titles pair a Save button with the label), so
   it's replaced with one consistent chevron on every card regardless. */
details.ep-section > summary.ep-section__title {
    cursor: pointer; user-select: none; list-style: none; position: relative;
    padding-right: 2.2rem;
}
details.ep-section > summary.ep-section__title::-webkit-details-marker { display: none; }
details.ep-section > summary.ep-section__title::after {
    content: "";
    position: absolute; right: 1.1rem; top: 50%;
    width: 0.5rem; height: 0.5rem;
    border-right: 2px solid var(--mid-gray); border-bottom: 2px solid var(--mid-gray);
    transform: translateY(-65%) rotate(45deg);
    transition: transform 0.15s ease;
}
details.ep-section[open] > summary.ep-section__title::after {
    transform: translateY(-35%) rotate(-135deg);
}

/* Tag chips */
.ep-tag-chip                 { display:inline-flex; align-items:center; gap:.3rem;
                               background:var(--off-white); border:1px solid var(--pale-gray);
                               border-radius:2rem; padding:.18rem .6rem;
                               font-size:.78rem; color:var(--near-black);
                               text-decoration:none; white-space:nowrap; }
.ep-tag-chip--sm             { font-size:.71rem; padding:.12rem .45rem; }
.ep-tag-chip:hover           { border-color:#aaa; background:var(--pale-gray); }
.ep-tag-chip__remove         { background:none; border:none; cursor:pointer;
                               color:var(--mid-gray); font-size:.75rem; padding:0;
                               line-height:1; margin-left:.1rem; }
.ep-tag-chip__remove:hover   { color:var(--danger); }
.ep-tags-wrap                { display:flex; flex-wrap:wrap; gap:.35rem; margin-bottom:.65rem; }

/* Variants compact table */
.variant-table               { width:100%; border-collapse:collapse; font-size:.82rem; }
.variant-table th            { font-size:.68rem; font-weight:700; text-transform:uppercase;
                               letter-spacing:.05em; color:var(--mid-gray);
                               padding:.3rem .5rem; border-bottom:2px solid var(--pale-gray);
                               text-align:left; }
.variant-table td            { padding:.38rem .5rem; border-bottom:1px solid var(--off-white);
                               vertical-align:middle; color:var(--near-black); }
.variant-table tr:last-child td { border-bottom:none; }

/* ═══════════════════════════════════════════════════════════════════════════════
   Commerce Hub: products.php — prd-* layout
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Page layout: sidebar + content */
.prd-layout                  { display:grid; grid-template-columns:280px 1fr; gap:1.5rem;
                               align-items:start; }
@media (max-width:820px) {
    .prd-layout              { grid-template-columns:1fr; }
    .prd-sidebar             { order:1; }
}

/* Filter bar */
.prd-filter-bar              { display:flex; flex-wrap:wrap; gap:.5rem; margin-bottom:.75rem;
                               align-items:center; }
.prd-filter-search           { flex:1; min-width:160px; padding:.38rem .6rem;
                               border:1px solid var(--pale-gray); border-radius:var(--radius-sm);
                               font-size:.85rem; font-family:inherit; box-sizing:border-box; }
.prd-filter-search:focus     { outline:none; border-color:#aaa; }
.prd-filter-select           { padding:.38rem .5rem; border:1px solid var(--pale-gray);
                               border-radius:var(--radius-sm); font-size:.82rem;
                               font-family:inherit; background:var(--white); color:var(--near-black); }
.prd-filter-select:focus     { outline:none; border-color:#aaa; }
.prd-filter-chk              { display:flex; align-items:center; gap:.3rem;
                               font-size:.82rem; cursor:pointer; color:var(--near-black);
                               white-space:nowrap; }

.prd-filter-chip             { display:inline-block; background:#eff6ff; color:#1d4ed8;
                               border:1px solid #bfdbfe; border-radius:2rem;
                               padding:.15rem .55rem; font-size:.72rem; font-weight:600; }

.prd-list-header             { display:flex; align-items:center; justify-content:space-between;
                               margin-bottom:.5rem; }

/* Product rows */
.prd-row                     { display:flex; align-items:flex-start; gap:1rem;
                               padding:.85rem 1.1rem; border-bottom:1px solid var(--pale-gray); }
.prd-row:last-child          { border-bottom:none; }
.prd-row--inactive           { opacity:.55; }
.prd-row--inactive:hover     { opacity:.8; }

.prd-row__main               { flex:1; min-width:0; }
.prd-row__name               { font-weight:600; font-size:.9rem; color:var(--near-black);
                               margin-bottom:.2rem; display:flex; align-items:center; gap:.3rem; }
.prd-row__name-link          { color:inherit; text-decoration:none; }
.prd-row__name-link:hover    { text-decoration:underline; }
.prd-row__meta               { display:flex; flex-wrap:wrap; align-items:center; gap:.4rem;
                               font-size:.74rem; color:var(--mid-gray); margin-bottom:.3rem; }
.prd-row__tags               { display:flex; flex-wrap:wrap; gap:.3rem; margin-top:.25rem; }

.prd-row__stats              { display:flex; flex-direction:column; align-items:flex-end;
                               gap:.3rem; flex-shrink:0; min-width:70px; }
.prd-row__actions            { display:flex; align-items:center; gap:.4rem; flex-shrink:0; }

/* Meta chips */
.prd-sku                     { background:var(--off-white); border:1px solid var(--pale-gray);
                               border-radius:var(--radius-sm); padding:.1rem .4rem;
                               font-size:.71rem; font-weight:700; font-family:var(--font-mono);
                               color:var(--near-black); letter-spacing:.03em; }
.prd-type-dot                { font-size:.74rem; }
.prd-type--printable         { color:#7c3aed; }
.prd-type--physical          { color:#b45309; }
.prd-type--service           { color:#0369a1; }
.prd-type--digital           { color:#059669; }
.prd-cat                     { color:var(--mid-gray); }
.prd-est                     { color:var(--mid-gray); }
.prd-model                   { color:var(--mid-gray); }
.prd-star                    { color:#d97706; font-size:.9rem; }
.prd-variants                { font-size:.75rem; }

/* Readiness badges */
.prd-badge                   { display:inline-block; border-radius:2rem;
                               padding:.15rem .55rem; font-size:.7rem; font-weight:700;
                               letter-spacing:.04em; white-space:nowrap; }
.prd-badge--draft            { background:#f3f4f6; color:#6b7280; border:1px solid #e5e7eb; }
.prd-badge--intake           { background:#fff7ed; color:#c2410c; border:1px solid #fed7aa; }
.prd-badge--media            { background:#ede9fe; color:#6d28d9; border:1px solid #ddd6fe; }
.prd-badge--ready            { background:#dbeafe; color:#1d4ed8; border:1px solid #bfdbfe; }
.prd-badge--listed           { background:#d1fae5; color:#065f46; border:1px solid #a7f3d0; }
.prd-badge--archived         { background:#fef3c7; color:#92400e; border:1px solid #fde68a; }

/* Business-unit badge — shared across Products/Inventory/wherever a row
   needs to show which business it belongs to (Grotto/Abstract Serenity/
   Vapolocity). Rendered via bu_badge_html() in config.php; color comes
   from business_units.color_hex per-instance, so no per-business CSS
   classes are needed. Mirrors admin/pos.php's own .pos-bu-badge exactly. */
.bu-badge                    { display:inline-block; font-size:.64rem; font-weight:700;
                               text-transform:uppercase; letter-spacing:.03em;
                               padding:.1rem .5rem; border-radius:999px;
                               background:var(--pale-gray); color:var(--dark-gray);
                               vertical-align:middle; white-space:nowrap; }

/* Completion indicators (SKU / IMG / $$$) */
.prd-indicators              { display:flex; flex-wrap:wrap; gap:.2rem; justify-content:flex-end; }
.prd-indicator               { display:inline-block; font-size:.62rem; font-weight:700;
                               letter-spacing:.04em; border-radius:var(--radius-sm);
                               padding:.1rem .35rem; white-space:nowrap; }
.prd-indicator--warn         { background:#fff1f2; color:#e11d48; border:1px solid #fecdd3; }
.prd-indicator--live         { background:#d1fae5; color:#065f46; border:1px solid #a7f3d0; }

/* ═══════════════════════════════════════════════════════════════════════════════
   Publishing Foundation: edit-product media section
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Media grid */
.ep-media-grid               { display:grid; grid-template-columns:repeat(auto-fill,minmax(90px,1fr));
                               gap:.5rem; margin-bottom:.75rem; }
.ep-media-item               { border:2px solid var(--pale-gray); border-radius:var(--radius-md);
                               overflow:hidden; position:relative; background:var(--off-white); }
.ep-media-item--primary      { border-color:#3b82f6; }
.ep-media-thumb              { width:100%; aspect-ratio:1; overflow:hidden; position:relative; }
.ep-media-thumb img          { width:100%; height:100%; object-fit:cover; display:block; }
.ep-media-primary-badge      { position:absolute; top:2px; left:2px; font-size:.6rem; font-weight:700;
                               background:#3b82f6; color:#fff; border-radius:2px;
                               padding:.05rem .3rem; pointer-events:none; }
.ep-media-meta               { padding:.2rem .35rem; font-size:.66rem; color:var(--mid-gray);
                               text-transform:capitalize; border-top:1px solid var(--pale-gray); }
.ep-media-actions            { display:flex; gap:.2rem; padding:.25rem .35rem;
                               border-top:1px solid var(--pale-gray); background:var(--white); }
.ep-media-empty              { font-size:.83rem; color:var(--mid-gray); margin-bottom:.65rem; }

/* Drop zone */
.ep-media-upload-wrap        { border-top:1px solid var(--pale-gray); padding-top:.75rem;
                               margin-top:.5rem; }
.ep-media-drop-zone          { border:2px dashed var(--pale-gray); border-radius:var(--radius-md);
                               padding:1.1rem .75rem; text-align:center; cursor:pointer;
                               transition:border-color .15s, background .15s; position:relative; }
.ep-media-drop-zone:hover,
.ep-media-drop-zone.dragover { border-color:#888; background:var(--off-white); }
.ep-drop-icon                { font-size:1.4rem; margin-bottom:.25rem; }
.ep-drop-label               { font-size:.8rem; color:var(--mid-gray); }
.ep-drop-hint                { font-size:.7rem; color:var(--light-gray); margin-top:.15rem; }

/* Upload progress */
.ep-upload-progress          { height:3px; background:var(--pale-gray);
                               border-radius:2px; margin-top:.4rem; overflow:hidden; }
.ep-upload-bar               { height:100%; background:#3b82f6;
                               width:0; transition:width .3s; }

/* Section header badge helpers */
.ep-warn-badge               { display:inline-block; background:#fff1f2; color:#e11d48;
                               border:1px solid #fecdd3; border-radius:2rem;
                               font-size:.62rem; font-weight:700; padding:.1rem .4rem;
                               margin-left:.4rem; vertical-align:middle;
                               text-transform:none; letter-spacing:0; }
.ep-ok-badge                 { display:inline-block; background:#d1fae5; color:#065f46;
                               border:1px solid #a7f3d0; border-radius:2rem;
                               font-size:.62rem; font-weight:700; padding:.1rem .4rem;
                               margin-left:.4rem; vertical-align:middle;
                               text-transform:none; letter-spacing:0; }

/* ── Marketplace readiness checklist ─────────────────────────────────────────── */
.ep-mp-checklist             { display:flex; flex-direction:column; gap:.25rem;
                               margin-bottom:.65rem; font-size:.79rem; }
.ep-mp-check                 { display:flex; align-items:center; gap:.4rem;
                               padding:.2rem 0; }
.ep-mp-check--ok             { color:#059669; }
.ep-mp-check--warn           { color:#dc2626; }
.ep-mp-check--neutral        { color:var(--mid-gray); }

.ep-mp-row                   { display:flex; align-items:center; gap:.55rem;
                               padding:.35rem 0; border-bottom:1px solid var(--pale-gray);
                               font-size:.82rem; }
.ep-mp-row:last-child        { border-bottom:none; }
.ep-mp-channel               { font-weight:700; font-size:.75rem; width:52px;
                               letter-spacing:.04em; color:var(--near-black); }
.ep-mp-status                { font-size:.72rem; font-weight:600; border-radius:2rem;
                               padding:.1rem .45rem; }
.ep-mp-status--synced        { background:#d1fae5; color:#065f46; }
.ep-mp-status--unsynced      { background:#f3f4f6; color:#6b7280; }
.ep-mp-status--needs_update  { background:#fff7ed; color:#c2410c; }
.ep-mp-status--error         { background:#fee2e2; color:#dc2626; }
.ep-mp-extlink               { color:#3b82f6; font-size:.78rem; text-decoration:none; }
.ep-mp-extlink:hover         { text-decoration:underline; }
.ep-mp-toggle                { margin-left:auto; font-size:.7rem; font-weight:700;
                               border-radius:2rem; padding:.1rem .45rem; }
.ep-mp-toggle--on            { background:#d1fae5; color:#065f46; }
.ep-mp-toggle--off           { background:#f3f4f6; color:#9ca3af; }
.ep-mp-none                  { font-size:.82rem; color:var(--mid-gray); margin:.25rem 0 0; }

/* ── Stat-card state modifiers ───────────────────────────────────────────────── */
.stat-card--warn             { border-color:#fed7aa; }
.stat-card--warn .stat-card__value  { color:#c2410c; }
.stat-card--alert            { border-color:#fecaca; }
.stat-card--alert .stat-card__value { color:#dc2626; }

/* ── Marketplaces dashboard (.ma-*) ──────────────────────────────────────────── */
.ma-grid                     { display:grid;
                               grid-template-columns:repeat(auto-fill, minmax(280px, 1fr));
                               gap:1rem; margin-bottom:1.5rem; }

.ma-card                     { background:var(--white); border:1px solid var(--pale-gray);
                               border-radius:var(--radius-md); padding:1.1rem 1.25rem;
                               display:flex; flex-direction:column; gap:.5rem; }
.ma-card--error              { border-color:#fecaca; }

.ma-card__header             { display:flex; align-items:center; gap:.55rem; }
.ma-card__icon               { font-size:1.3rem; line-height:1; flex-shrink:0; }
.ma-card__name               { font-weight:700; font-size:.9rem; }
.ma-card__desc               { font-size:.78rem; color:var(--mid-gray); margin:0; }
.ma-card__account-row        { font-size:.82rem; }
.ma-card__no-account         { font-size:.8rem; color:var(--light-gray); margin:0; }
.ma-card__actions            { display:flex; gap:.4rem; flex-wrap:wrap; align-items:center;
                               margin-top:.25rem; }

/* Token expiry text */
.ma-card__token              { font-size:.72rem; color:var(--light-gray); }
.ma-token--expired           { color:var(--danger); font-weight:600; }
.ma-token--expiring          { color:#c2410c; font-weight:600; }

/* Last sync line */
.ma-card__last-sync          { font-size:.72rem; color:var(--light-gray); }

/* Error message */
.ma-card__err-msg            { font-size:.73rem; color:var(--danger); background:#fff0f0;
                               border-radius:4px; padding:.3rem .5rem; word-break:break-all; }

/* Mini stats strip inside a channel card */
.ma-card__stats              { display:flex; gap:.75rem; flex-wrap:wrap;
                               padding:.5rem 0; border-top:1px solid var(--pale-gray); }
.ma-stat                     { display:flex; flex-direction:column; align-items:center;
                               min-width:40px; }
.ma-stat__val                { font-family:var(--font-serif); font-size:1.15rem;
                               font-weight:700; line-height:1; color:var(--near-black); }
.ma-stat__lbl                { font-size:.65rem; color:var(--mid-gray);
                               text-transform:uppercase; letter-spacing:.04em; margin-top:.1rem; }
.ma-stat--warn .ma-stat__val { color:#c2410c; }
.ma-stat--error .ma-stat__val{ color:#dc2626; }

/* Edit account details <details> element */
.ma-edit-details             { font-size:.8rem; border-top:1px solid var(--pale-gray);
                               padding-top:.5rem; }
.ma-edit-details summary     { cursor:pointer; color:var(--mid-gray); list-style:none;
                               font-size:.78rem; }
.ma-edit-details summary::-webkit-details-marker { display:none; }
.ma-edit-details summary::before { content:'▸ '; }
details[open].ma-edit-details summary::before { content:'▾ '; }
.ma-edit-form                { margin-top:.6rem; }
.ma-edit-form .form-group    { margin-bottom:.5rem; }
.ma-edit-form label          { font-size:.75rem; font-weight:600; display:block;
                               margin-bottom:.2rem; }
.ma-edit-form input          { font-size:.82rem; }

/* Status badges */
.ma-status                   { display:inline-block; border-radius:2rem; font-size:.68rem;
                               font-weight:700; padding:.15rem .55rem; margin-left:auto; }
.ma-status--connected        { background:#d1fae5; color:#065f46; }
.ma-status--expired          { background:#fff7ed; color:#c2410c; }
.ma-status--error            { background:#fee2e2; color:#dc2626; }
.ma-status--disconnected     { background:#f3f4f6; color:#9ca3af; }

/* ── Product publish page (.pp-*) ────────────────────────────────────────────── */
.pp-layout                   { display:grid; grid-template-columns:1fr 300px; gap:1.25rem;
                               align-items:start; }
@media (max-width: 860px)    { .pp-layout { grid-template-columns:1fr; } }
.pp-form                     { background:var(--white); border:1px solid var(--pale-gray);
                               border-radius:var(--radius-md); padding:1.25rem; }
.pp-preview                  { background:var(--white); border:1px solid var(--pale-gray);
                               border-radius:var(--radius-md); padding:1.1rem; position:sticky; top:1rem; }
.pp-field                    { margin-bottom:.85rem; }
.pp-field label              { display:block; font-size:.78rem; font-weight:600;
                               margin-bottom:.25rem; color:var(--near-black); }
.pp-chars                    { font-size:.68rem; color:var(--light-gray); float:right;
                               font-weight:400; }
.pp-meta-row                 { display:flex; gap:.6rem; }
.pp-meta-row .pp-field       { flex:1; min-width:0; }
.pp-action-bar               { display:flex; align-items:center; gap:.6rem; flex-wrap:wrap;
                               padding:.75rem 1rem; background:var(--white);
                               border:1px solid var(--pale-gray); border-radius:var(--radius-md);
                               margin-bottom:.75rem; }
.pp-status-pill              { display:inline-flex; align-items:center; gap:.3rem;
                               border-radius:2rem; font-size:.72rem; font-weight:700;
                               padding:.2rem .55rem; }
.pp-status-pill--synced      { background:#d1fae5; color:#065f46; }
.pp-status-pill--unsynced    { background:#f3f4f6; color:#6b7280; }
.pp-status-pill--needs_update{ background:#fff7ed; color:#c2410c; }
.pp-status-pill--error       { background:#fee2e2; color:#dc2626; }

/* ── Products list — new indicators (Phase G) ────────────────────────────────── */
.prd-indicator--sync         { background:#fff7ed; color:#c2410c; border:1px solid #fed7aa; }
.prd-indicator--block        { background:#fee2e2; color:#dc2626; border:1px solid #fecaca;
                               font-weight:800; }
.btn-danger-outline          { background:transparent; color:var(--danger);
                               border:1px solid var(--danger); }

/* ============================================================
   Print Farm (Printer Status Cards)
   ============================================================ */
.pf-section {
    margin-bottom: 1.5rem;
}

.pf-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 0.75rem;
}

.pf-card {
    background: var(--white);
    border: 1.5px solid var(--pale-gray);
    border-radius: var(--radius-md);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    transition: border-color 0.2s;
}

.pf-card--printing  { border-color: #86efac; }
.pf-card--paused    { border-color: #fcd34d; }
.pf-card--error     { border-color: #fca5a5; animation: pf-pulse 1.5s ease-in-out infinite; }
.pf-card--offline   { border-style: dashed; opacity: 0.65; }
.pf-card--attention { border-color: #fca5a5; }

@keyframes pf-pulse {
    0%, 100% { border-color: #fca5a5; }
    50%       { border-color: #ef4444; }
}

.pf-card__top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.4rem;
}

.pf-card__name {
    font-family: var(--font-serif);
    font-size: 1.05rem;
    color: var(--near-black);
    font-weight: normal;
    line-height: 1.2;
}

.pf-card__model {
    font-size: 0.7rem;
    color: var(--mid-gray);
    font-family: var(--font-sans);
    white-space: nowrap;
    padding-top: 0.15rem;
}

/* Status badges */
.pf-badge {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border-radius: var(--radius-sm);
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    white-space: nowrap;
}
.pf-badge--printing  { background: #dcfce7; color: #166534; }
.pf-badge--idle      { background: #f3f4f6; color: #6b7280; }
.pf-badge--done      { background: #e0f2fe; color: #0369a1; }
.pf-badge--paused    { background: #fef9c3; color: #854d0e; }
.pf-badge--error     { background: #fee2e2; color: #991b1b; }
.pf-badge--heating   { background: #eff6ff; color: #1d4ed8; }
.pf-badge--preparing { background: #eff6ff; color: #1d4ed8; }
.pf-badge--cooling   { background: #ecfeff; color: #0e7490; }
.pf-badge--offline   { background: #f9fafb; color: #9ca3af; }
.pf-badge--unknown   { background: #f3f4f6; color: #6b7280; }

/* Progress bar */
.pf-progress {
    height: 5px;
    background: var(--pale-gray);
    border-radius: 3px;
    overflow: hidden;
}
.pf-progress__fill {
    height: 100%;
    background: var(--near-black);
    border-radius: 3px;
    transition: width 0.6s ease;
}
.pf-card--printing .pf-progress__fill { background: #16a34a; }
.pf-card--error    .pf-progress__fill { background: #dc2626; }

.pf-progress-label {
    font-size: 0.72rem;
    color: var(--mid-gray);
    text-align: right;
    line-height: 1;
}

/* ETA / remaining time */
.pf-eta {
    font-size: 0.78rem;
    color: var(--dark-gray);
    font-family: var(--font-sans);
}

/* Temps */
.pf-temps {
    display: flex;
    gap: 0.75rem;
    font-size: 0.74rem;
    color: var(--mid-gray);
    font-family: var(--font-mono);
}
.pf-temps__item strong { color: var(--near-black); }

/* Current file label */
.pf-file {
    font-size: 0.7rem;
    color: var(--mid-gray);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Error / unavailable message */
.pf-unavailable {
    padding: 0.75rem 1rem;
    background: var(--off-white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-md);
    color: var(--mid-gray);
    font-size: 0.85rem;
    font-family: var(--font-sans);
}

/* Loading skeleton */
.pf-card--loading {
    animation: pf-shimmer 1.4s ease infinite;
}
@keyframes pf-shimmer {
    0%, 100% { opacity: 0.5; }
    50%       { opacity: 1; }
}

/* Last-updated timestamp */
.pf-updated {
    font-size: 0.68rem;
    color: var(--light-gray);
    text-align: right;
    margin-top: -0.25rem;
    font-family: var(--font-sans);
}

@media (max-width: 768px) {
    .pf-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 0.5rem;
    }
    .pf-card {
        padding: 0.75rem;
    }
}

/* ============================================================
   Room Lights
   ============================================================ */
.rl-section { margin-bottom: 1.5rem; }

.rl-master {
    display: flex;
    gap: 0.4rem;
    margin-left: auto;
}
.rl-master-btn {
    padding: 0.25rem 0.75rem;
    border-radius: var(--radius-sm);
    border: 1px solid var(--pale-gray);
    font-size: 0.75rem;
    cursor: pointer;
    font-family: var(--font-sans);
    transition: background 0.15s;
}
.rl-master-btn--on  { background: #dcfce7; color: #166534; border-color: #86efac; }
.rl-master-btn--off { background: #f3f4f6; color: #374151; }
.rl-master-btn:hover { filter: brightness(0.95); }

.rl-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.75rem;
}

.rl-card {
    background: var(--white);
    border: 1.5px solid var(--pale-gray);
    border-radius: var(--radius-md);
    padding: 0.85rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    transition: border-color 0.2s;
}
.rl-card--on {
    border-color: #fde68a;
    background: #fffdf0;
}

.rl-card__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}
.rl-card__row--dim { gap: 0.75rem; }

.rl-card__label {
    font-size: 0.85rem;
    color: var(--dark-gray);
    font-family: var(--font-sans);
}
.rl-card--on .rl-card__label { color: var(--near-black); font-weight: 600; }

.rl-card__pct {
    font-size: 0.72rem;
    color: var(--mid-gray);
    font-family: var(--font-mono);
    min-width: 2.5rem;
    text-align: right;
}

/* Toggle switch */
.rl-toggle {
    position: relative;
    width: 40px;
    height: 22px;
    background: #d1d5db;
    border: none;
    border-radius: 11px;
    cursor: pointer;
    transition: background 0.2s;
    flex-shrink: 0;
    padding: 0;
}
.rl-toggle--on { background: #f59e0b; }
.rl-toggle__knob {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 16px;
    height: 16px;
    background: #fff;
    border-radius: 50%;
    transition: transform 0.2s;
    display: block;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.rl-toggle--on .rl-toggle__knob { transform: translateX(18px); }

/* Brightness slider */
.rl-slider {
    -webkit-appearance: none;
    appearance: none;
    flex: 1;
    height: 4px;
    background: var(--pale-gray);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
}
.rl-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: #f59e0b;
    cursor: pointer;
    border: none;
}
.rl-slider:disabled { opacity: 0.35; cursor: not-allowed; }
.rl-slider:disabled::-webkit-slider-thumb { cursor: not-allowed; }

.rl-unavailable, .rl-loading {
    color: var(--mid-gray);
    font-size: 0.85rem;
    font-family: var(--font-sans);
    padding: 0.5rem 0;
}
.btn-danger-outline:hover    { background:var(--danger); color:var(--white); }

/* ============================================================
   Ops two-column layout
   ============================================================ */
.ops-layout {
    display: flex;
    gap: 1.25rem;
    align-items: flex-start;
}
.ops-main {
    flex: 1 1 0;
    min-width: 0;
}
.ops-aside {
    width: 272px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    position: sticky;
    top: 1rem;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
}

/* ── Aside cards ─────────────────────────────────────────────── */
.ops-aside-card {
    background: var(--white);
    border: 1px solid var(--border-gray);
    border-radius: var(--radius);
    padding: 0.75rem 0.875rem;
}
.ops-aside-card__hd {
    font-size: 0.88rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--mid-gray);
    margin-bottom: 0.55rem;
}
.ops-aside-card__hd--flex {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* Lights in aside — stack as single column, compact */
.rl-grid--aside {
    grid-template-columns: 1fr !important;
    gap: 0.5rem !important;
}
.rl-grid--aside .rl-card {
    padding: 0.45rem 0.6rem;
}

/* Quick intake in aside — stack buttons */
.ops-intake--aside {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.ops-intake--aside .ops-intake-btn {
    text-align: center;
    padding: 0.45rem 0.75rem;
    font-size: 0.83rem;
}

/* ============================================================
   Up Next widget
   ============================================================ */
.un-widget {
    width: 290px;
    flex-shrink: 0;
    background: var(--white);
    border: 1px solid var(--border-gray);
    border-radius: var(--radius);
    padding: 0.7rem 0.875rem 0.75rem;
    align-self: flex-start;
}
.un-widget__hd {
    font-size: 0.88rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--mid-gray);
    margin-bottom: 0.45rem;
}
.un-list {
    list-style: none;
    margin: 0 0 0.5rem;
    padding: 0;
    max-height: 220px;
    overflow-y: auto;
}
.un-empty {
    font-size: 0.8rem;
    color: var(--mid-gray);
    padding: 0.2rem 0;
    font-style: italic;
}
.un-item {
    display: flex;
    align-items: flex-start;
    gap: 0.25rem;
    padding: 0.3rem 0;
    border-bottom: 1px solid var(--border-gray);
}
.un-item:last-child { border-bottom: none; }
.un-item__text {
    flex: 1;
    font-size: 0.85rem;
    min-width: 0;
    word-break: break-word;
    line-height: 1.35;
    cursor: text;
    padding-top: 0.05rem;
}
.un-item__edit,
.un-item__del {
    flex-shrink: 0;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.1rem 0.25rem;
    border-radius: 3px;
    color: var(--mid-gray);
    font-size: 0.78rem;
    line-height: 1.5;
    margin-top: 0.05rem;
}
.un-item__edit:hover { color: var(--near-black); background: var(--light-gray); }
.un-item__del:hover  { color: #dc2626; background: #fee2e2; }
.un-item__input {
    flex: 1;
    font-size: 0.85rem;
    border: 1px solid #3b82f6;
    border-radius: 3px;
    padding: 0.1rem 0.35rem;
    outline: none;
    min-width: 0;
}
.un-add {
    display: flex;
    gap: 0.375rem;
}
.un-add__input {
    flex: 1;
    font-size: 0.82rem;
    border: 1px solid var(--border-gray);
    border-radius: var(--radius);
    padding: 0.3rem 0.5rem;
    outline: none;
    min-width: 0;
}
.un-add__input:focus { border-color: #3b82f6; }
.un-add__btn {
    background: #16a34a;
    color: #fff;
    border: none;
    border-radius: var(--radius);
    padding: 0.3rem 0.65rem;
    font-size: 0.95rem;
    font-weight: 700;
    cursor: pointer;
    line-height: 1;
    flex-shrink: 0;
}
.un-add__btn:hover { background: #15803d; }

/* ============================================================
   Light Confirmation Modal
   ============================================================ */
.light-confirm {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.55);
    z-index: 10000;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.light-confirm--open { display: flex; }

.light-confirm__box {
    background: var(--white);
    border-radius: var(--radius-md);
    padding: 1.75rem 1.5rem 1.25rem;
    max-width: 320px;
    width: 100%;
    text-align: center;
    box-shadow: 0 8px 32px rgba(0,0,0,0.22);
    animation: confirm-pop 0.15s ease;
}
@keyframes confirm-pop {
    from { transform: scale(0.92); opacity: 0; }
    to   { transform: scale(1);    opacity: 1; }
}

.light-confirm__icon {
    font-size: 2.25rem;
    line-height: 1;
    margin-bottom: 0.5rem;
}
.light-confirm__title {
    font-family: var(--font-sans);
    font-weight: 700;
    font-size: 1rem;
    color: var(--near-black);
    margin-bottom: 0.35rem;
}
.light-confirm__msg {
    font-family: var(--font-sans);
    font-size: 0.85rem;
    color: var(--dark-gray);
    margin-bottom: 1.25rem;
}
.light-confirm__btns {
    display: flex;
    gap: 0.6rem;
    justify-content: center;
}
.light-confirm__yes {
    background: var(--near-black);
    color: var(--white);
    border: none;
    border-radius: var(--radius-sm);
    padding: 0.5rem 1.25rem;
    font-family: var(--font-sans);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s;
}
.light-confirm__yes:hover { background: #374151; }
.light-confirm__no {
    background: none;
    color: var(--dark-gray);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    padding: 0.5rem 1.25rem;
    font-family: var(--font-sans);
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.15s;
}
.light-confirm__no:hover { background: var(--pale-gray); }

/* ============================================================
   Mobile Responsive — Ops Dashboard
   ============================================================ */
@media (max-width: 768px) {

    /* Two-column layout stacks on mobile */
    .ops-layout { flex-direction: column; }
    .ops-aside  { width: auto; position: static; max-height: none; overflow-y: visible; }

    /* Stat cards — 2 per row */
    .ops-snap {
        grid-template-columns: repeat(2, 1fr) !important;
    }

    /* Print Farm — 2 per row, tighter */
    .pf-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 0.5rem;
    }
    .pf-card { padding: 0.7rem; }
    .pf-card__name { font-size: 0.95rem; }

    /* Room Lights — 1 per row on small, 2 on medium */
    .rl-grid {
        grid-template-columns: 1fr;
    }

    /* Attention/Quick Intake grid — stack */
    .ops-grid {
        grid-template-columns: 1fr !important;
    }

    /* Sections */
    .ops-section { margin-bottom: 1rem; }
    .ops-section__header { flex-wrap: wrap; gap: 0.4rem; }

    /* Admin main padding */
    .admin-main { padding: 1rem; }

    /* Bed removal / printing now rows */
    .ops-job-row { flex-wrap: wrap; gap: 0.4rem; }

    /* Room lights master buttons */
    .rl-master { margin-left: 0; }
}

@media (max-width: 480px) {
    /* Stat cards — stacked on very small screens */
    .ops-snap {
        grid-template-columns: repeat(2, 1fr) !important;
    }
    .ops-snap-card__value { font-size: 1.6rem; }

    /* Print Farm — 1 per row on phones */
    .pf-grid { grid-template-columns: 1fr; }

    /* Section headers */
    .ops-section__title { font-size: 0.85rem; }
}

/* ============================================================
   Job/Client Intake Forms (admin/new-job.php, staff/new-intake.php)
   Was previously only defined inline in new-job.php's own <style>
   block — new-intake.php used the same classes but never got the CSS,
   so its client-search dropdown/layout rendered completely unstyled.
   Moved here so both pages (and any future one) share one definition.
   ============================================================ */
.nj-grid {
    display: grid;
    grid-template-columns: 1fr 340px;
    gap: 1.5rem;
    align-items: start;
}
@media (max-width: 860px) { .nj-grid { grid-template-columns: 1fr; } }

.nj-section {
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-lg);
    margin-bottom: 1rem;
    overflow: hidden;
}
.nj-section__header {
    padding: .75rem 1.25rem;
    border-bottom: 1px solid var(--pale-gray);
    background: var(--off-white);
    font-size: .9rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--mid-gray);
}
.nj-section__body { padding: 1.1rem 1.25rem; }

.nj-mode-tabs {
    display: flex;
    gap: .35rem;
    margin-bottom: 1rem;
}
.nj-mode-btn {
    padding: .28rem .75rem;
    font-size: .78rem;
    font-weight: 600;
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    background: var(--white);
    color: var(--mid-gray);
    cursor: pointer;
    font-family: inherit;
    transition: background .12s, border-color .12s, color .12s;
}
.nj-mode-btn.active {
    background: var(--near-black);
    border-color: var(--near-black);
    color: #fff;
}

.nj-search-wrap { position: relative; }
.nj-search-input {
    width: 100%;
    padding: .45rem .65rem;
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    font-size: .9rem;
    font-family: inherit;
    box-sizing: border-box;
}
.nj-search-input:focus { outline: none; border-color: #aaa; }

.nj-search-results {
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    background: var(--white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    box-shadow: 0 4px 16px rgba(0,0,0,.1);
    z-index: 100;
    max-height: 220px;
    overflow-y: auto;
    display: none;
}
.nj-search-results.open { display: block; }
.nj-result-item {
    padding: .55rem .75rem;
    cursor: pointer;
    border-bottom: 1px solid var(--pale-gray);
    font-size: .86rem;
}
.nj-result-item:last-child { border-bottom: none; }
.nj-result-item:hover { background: var(--off-white); }
.nj-result-name { font-weight: 600; color: var(--near-black); }
.nj-result-email { font-size: .75rem; color: var(--mid-gray); }
.nj-result-none { padding: .55rem .75rem; color: var(--mid-gray); font-size: .83rem; }

/* Existing/New mode toggle — used wherever a customer picker also offers a
   quick-create option (admin/request.php's Change Customer; mirrors the
   equivalent pattern already inline in admin/pos.php's own stylesheet). */
.pos-quick-toggle-mode { display: flex; gap: .5rem; margin-bottom: .5rem; }
.pos-quick-toggle-mode button { flex: 1; }
.pos-quick-toggle-mode button.active { background: var(--near-black); color: var(--white); }

.nj-selected-client {
    display: none;
    align-items: center;
    gap: .6rem;
    padding: .55rem .75rem;
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    border-radius: var(--radius-sm);
    font-size: .86rem;
    margin-top: .5rem;
}
.nj-selected-client.visible { display: flex; }
.nj-selected-name { font-weight: 600; color: var(--near-black); flex: 1; }
.nj-selected-email { font-size: .75rem; color: var(--mid-gray); }
.nj-clear-btn {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--mid-gray);
    font-size: .9rem;
    padding: 0 .1rem;
    line-height: 1;
}
.nj-clear-btn:hover { color: var(--near-black); }

.nj-upload-area {
    border: 2px dashed var(--pale-gray);
    border-radius: var(--radius-md);
    padding: 1.5rem 1rem;
    text-align: center;
    cursor: pointer;
    transition: border-color .15s, background .15s;
    position: relative;
}
.nj-upload-area:hover,
.nj-upload-area.dragover { border-color: #888; background: var(--off-white); }
.nj-upload-area input[type="file"] {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
    width: 100%;
    height: 100%;
}
.nj-upload-icon { font-size: 1.6rem; margin-bottom: .4rem; }
.nj-upload-label { font-size: .82rem; color: var(--mid-gray); }
.nj-upload-label strong { color: var(--near-black); }
.nj-upload-types { font-size: .72rem; color: var(--light-gray); margin-top: .2rem; }

.nj-file-info {
    display: none;
    align-items: center;
    gap: .6rem;
    padding: .5rem .7rem;
    background: var(--off-white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    margin-top: .6rem;
    font-size: .82rem;
}
.nj-file-info.visible { display: flex; }
.nj-file-name { font-weight: 600; flex: 1; color: var(--near-black); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nj-file-size { color: var(--mid-gray); flex-shrink: 0; }
.nj-file-clear { background: none; border: none; cursor: pointer; color: var(--mid-gray); font-size: .9rem; padding: 0; flex-shrink: 0; }
.nj-file-clear:hover { color: #c62828; }

.nj-toggle-row {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: .55rem;
    cursor: pointer;
    font-size: .86rem;
}
.nj-toggle-row input { cursor: pointer; }
.nj-toggle-label { color: var(--near-black); }
.nj-toggle-hint { font-size: .74rem; color: var(--mid-gray); }

#njResults {
    display: none;
    background: var(--white);
    border: 1px solid #bbf7d0;
    border-radius: var(--radius-lg);
    overflow: hidden;
}
#njResults.visible { display: block; }
.nj-result-header {
    background: #f0fdf4;
    border-bottom: 1px solid #bbf7d0;
    padding: 1rem 1.5rem;
    display: flex;
    align-items: center;
    gap: .75rem;
}
.nj-result-icon { font-size: 1.4rem; }
.nj-result-title { font-size: 1rem; font-weight: 700; color: #166534; margin: 0; font-family: var(--font-serif); }
.nj-result-sub { font-size: .83rem; color: #15803d; margin: .1rem 0 0; }
.nj-result-body { padding: 1.25rem 1.5rem; }
.nj-result-row {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .55rem 0;
    border-bottom: 1px solid var(--pale-gray);
    font-size: .86rem;
}
.nj-result-row:last-child { border-bottom: none; }
.nj-result-row-label { font-size: .72rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: var(--mid-gray); width: 100px; flex-shrink: 0; }
.nj-result-row-val { flex: 1; color: var(--near-black); font-weight: 500; word-break: break-all; }
.nj-copy-btn {
    padding: .2rem .55rem;
    font-size: .73rem;
    font-weight: 600;
    background: var(--off-white);
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    cursor: pointer;
    color: var(--mid-gray);
    font-family: inherit;
    flex-shrink: 0;
    transition: background .12s, border-color .12s;
}
.nj-copy-btn:hover { border-color: #aaa; color: var(--near-black); }
.nj-copy-btn.copied { background: #dcfce7; border-color: #86efac; color: #166534; }
.nj-result-actions {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
    margin-top: 1.1rem;
}

.nj-error {
    display: none;
    background: #fce4ec;
    border: 1px solid #f48fb1;
    color: #c62828;
    border-radius: var(--radius-md);
    padding: .75rem 1rem;
    margin-bottom: 1rem;
    font-size: .875rem;
}
.nj-error.visible { display: block; }

.nj-submit-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-top: 1.5rem;
}
.nj-submit-spinner { display: none; color: var(--mid-gray); font-size: .85rem; }
.nj-submit-spinner.visible { display: inline; }

.nj-form-group { margin-bottom: .9rem; }
.nj-form-group:last-child { margin-bottom: 0; }
.nj-form-group label {
    display: block;
    font-size: .75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--mid-gray);
    margin-bottom: .3rem;
}
.nj-form-group input,
.nj-form-group textarea,
.nj-form-group select {
    width: 100%;
    padding: .42rem .6rem;
    border: 1px solid var(--pale-gray);
    border-radius: var(--radius-sm);
    font-size: .9rem;
    font-family: inherit;
    box-sizing: border-box;
}
.nj-form-group input:focus,
.nj-form-group textarea:focus,
.nj-form-group select:focus { outline: none; border-color: #aaa; }
.nj-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; }
@media (max-width: 560px) { .nj-form-row { grid-template-columns: 1fr; } }

/* ═══════════════════════════════════════════════════════════════════════════════
   Public site dark theme (2026-09-13)
   Scoped to body.site-dark — every public/front-facing page (storefront,
   product/portfolio/tools/artists pages, login/register, etc.), added to
   each page's own <body> tag. Deliberately does NOT touch admin/staff pages
   (their own separate dark theme, below, keeps its own Georgia/Segoe UI
   typography) and does NOT touch logged-in client/artist portal dashboards
   (client/index.php, artist/my-jobs.php) — this is the public marketing/
   storefront surface specifically.

   Reuses the exact same token-flip values already proven out by the admin
   dark theme immediately below — same reasoning applies: the base
   stylesheet consistently pairs --near-black-bg with var(--white) text and
   vice versa, so flipping the shared tokens corrects most existing public
   pages automatically. Fonts (Fraunces/Manrope/Space Mono, imported at the
   top of this file) are swapped here too — this scope is the only place
   they apply; admin keeps its original fonts.

   This design started as index.php's own bespoke, self-contained dark
   pass (its own --hp-* tokens, its own <style> block) — promoted here so
   every other public page gets the same look via one shared class instead
   of copy-pasting index.php's approach 25+ times. index.php itself still
   carries its own --hp-* tokens/hero markup on top of this (its hero,
   viewer mockup, stat tiles, etc. are bespoke content, not something every
   page needs) — harmless duplication, not a conflict, since --hp-* and the
   base tokens are different custom properties.
   ═══════════════════════════════════════════════════════════════════════════════ */
body.site-dark {
    --near-black:  #e9e9eb;
    --white:       #232428;
    --off-white:   #17181b;
    --pale-gray:   #35373d;
    --mid-gray:    #a3a5ac;
    --light-gray:  #6f7178;
    --dark-gray:   #d3d4d8;
    --accent-hover:#ffffff;
    --danger:      #f2726c;
    --success:     #3ddc84;
    --warning:     #eab54e;
    --shadow-sm:   0 1px 3px rgba(0,0,0,0.4);
    --shadow-md:   0 4px 16px rgba(0,0,0,0.5);
    --shadow-lg:   0 10px 30px rgba(0,0,0,0.6);

    --font-serif:  'Fraunces', Georgia, 'Times New Roman', serif;
    --font-sans:   'Manrope', 'Segoe UI', Calibri, system-ui, -apple-system, sans-serif;
    --font-mono:   'Space Mono', 'Courier New', monospace;

    background:
        radial-gradient(1200px 560px at 12% -10%, rgba(255,255,255,0.05), transparent 60%),
        radial-gradient(900px 480px at 92% 4%, rgba(255,255,255,0.03), transparent 55%),
        linear-gradient(180deg, #100f0c 0%, #050504 45%, #000000 100%);
    background-attachment: fixed;
    color-scheme: dark;
}
body.site-dark { scrollbar-color: #45474e #050504; }
body.site-dark *::-webkit-scrollbar { width: 10px; height: 10px; }
body.site-dark *::-webkit-scrollbar-track { background: transparent; }
body.site-dark *::-webkit-scrollbar-thumb { background: #45474e; border-radius: 6px; }
body.site-dark *::-webkit-scrollbar-thumb:hover { background: #55575e; }

/* Same header/footer re-theme index.php already proved out, promoted
   here so every page gets it instead of re-declaring it per page. */
body.site-dark .site-header {
    background: rgba(3,3,2,0.8);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-bottom-color: var(--pale-gray);
}
body.site-dark .site-header__logo-text { color: var(--near-black); }
body.site-dark .site-nav a { color: var(--mid-gray); }
body.site-dark .site-nav a:hover { background: var(--off-white); color: var(--near-black); }
body.site-dark .site-nav a.active { color: var(--near-black); }
body.site-dark .site-nav__sub { background: var(--white); border-color: var(--pale-gray); }
body.site-dark .site-nav__sub::before { background: var(--white); border-color: var(--pale-gray); }
body.site-dark .site-nav__sub a { color: var(--mid-gray); }
body.site-dark .site-nav__sub a:hover { background: var(--off-white); color: var(--near-black); }
body.site-dark .site-header__signout { color: var(--light-gray); }
body.site-dark .site-header__signout:hover { color: var(--near-black); }
body.site-dark .site-nav-toggle { color: var(--near-black); }
body.site-dark .site-nav-toggle:hover { background: var(--off-white); }
body.site-dark .site-nav__sub-toggle { color: var(--mid-gray); }
body.site-dark .site-footer { background: transparent; border-top-color: var(--pale-gray); color: var(--light-gray); }
body.site-dark .site-footer a { color: var(--mid-gray); }
body.site-dark .site-footer a:hover { color: var(--near-black); }
@media (max-width: 768px) {
    body.site-dark .site-nav {
        background: var(--off-white); border-top-color: var(--pale-gray); border-bottom-color: var(--pale-gray);
    }
    body.site-dark .site-nav a { background: transparent; }
    body.site-dark .site-nav a:hover, body.site-dark .site-nav a.active { background: var(--white); }
    body.site-dark .site-nav__sub { background: transparent; border: none; box-shadow: none; }
}

/* Form focus ring is a subtle BLACK shadow (rgba(0,0,0,...)) — invisible
   against a dark page. Same fix already used for the admin dark theme. */
body.site-dark input:focus,
body.site-dark select:focus,
body.site-dark textarea:focus { box-shadow: 0 0 0 3px rgba(255,255,255,0.12); }

/* .btn-primary pairs background:var(--near-black) with color:var(--white)
   — under the flip that becomes light-bg/dark-text, which would look
   inconsistent with index.php's own hero buttons (its .btn-primary isn't
   touched by the flip at all, since the homepage uses its own separate
   --hp-* tokens instead of --near-black/--white). Pin it to the same
   literal dark-bg/white-text look everywhere else on the dark public site
   so buttons read identically whether you're on the homepage or not. */
body.site-dark .btn-primary { background: #1a1a1a; color: #ffffff; border-color: #1a1a1a; }
body.site-dark .btn-primary:hover { background: #333333; border-color: #333333; }

/* Same "glaring light patch on a dark page" fix already used for the
   admin dark theme — these two alert-message class pairs are hardcoded
   pastel hex (not tokens), so they don't auto-flip on their own. */
body.site-dark .alert-error,
body.site-dark .alert-danger  { background: rgba(242,114,108,0.12); border-color: rgba(242,114,108,0.4); color: #f2726c; }
body.site-dark .alert-success { background: rgba(61,220,132,0.12); border-color: rgba(61,220,132,0.4); color: #3ddc84; }
body.site-dark .alert-info    { background: rgba(255,255,255,0.06); border-color: var(--pale-gray); color: var(--mid-gray); }

/* ═══════════════════════════════════════════════════════════════════════════════
   Admin/staff dark theme (2026-08-23)
   Scoped to body:has(.admin-layout):not(.theme-light) — every page behind require_staff()/
   require_admin() that uses the shared admin-sidebar.php layout. Deliberately
   does NOT touch the public storefront (index.php, products.php, portfolio.php,
   client/artist portals) — that keeps its existing black-and-white branding.

   Approach: the base stylesheet consistently pairs --near-black-bg with
   var(--white) text and vice versa throughout (the "dark pill" / "light card"
   idiom used everywhere from buttons to nav states), so flipping the shared
   tokens corrects most of the app automatically rather than needing a
   component-by-component rewrite. The few spots that pair a token with a
   HARDCODED color instead of its natural partner (admin-sidebar's rgba(255,..)
   text, a handful of "active" pills using literal #fff) break under that flip
   and get explicit counter-overrides below. Colored status/priority badges
   (.req-badge--*, .rdb--*, .pri-badge--*, job-badge--*) are deliberately left
   alone — pastel chips on a dark backdrop is a normal, good-looking dark-mode
   pattern and there are dozens of them.
   ═══════════════════════════════════════════════════════════════════════════════ */
body:has(.admin-layout):not(.theme-light) {
    /* Shared tokens, flipped for dark surfaces. --near-black becomes the
       default (light) text color; --white becomes the default (dark) card
       surface; these two are used as a consistent pair throughout the base
       stylesheet, which is what makes this flip self-correct almost everything
       automatically instead of needing per-component rewrites.

       --mid-gray/--light-gray were initially flipped "correctly" by the same
       logic that makes faint text darker (closer to the background) on a
       dark surface — technically consistent with the light-mode hierarchy,
       but in practice too low-contrast to read comfortably against
       --off-white/--white. Brightened both directly per real usage feedback
       — readability wins over strict hierarchy-symmetry here. --pale-gray
       (borders) bumped too, since 1.5px borders at the old value were nearly
       invisible on form fields. */
    --near-black:  #e9e9eb;
    --white:       #232428;
    --off-white:   #17181b;
    --pale-gray:   #4a4d56;
    --mid-gray:    #c6c7cc;
    --light-gray:  #9a9ca3;
    --dark-gray:   #dde0e3;
    --accent-hover:#ffffff;
    --danger:      #f2726c;
    --success:     #3ddc84;
    --warning:     #eab54e;
    --shadow-sm:   0 1px 3px rgba(0,0,0,0.4);
    --shadow-md:   0 4px 16px rgba(0,0,0,0.5);
    --shadow-lg:   0 10px 30px rgba(0,0,0,0.6);

    background: var(--off-white);
    color-scheme: dark;
}

/* Scrollbars — dark to match, WebKit + Firefox */
body:has(.admin-layout):not(.theme-light) { scrollbar-color: #45474e #1a1b1e; }
body:has(.admin-layout):not(.theme-light) *::-webkit-scrollbar { width: 10px; height: 10px; }
body:has(.admin-layout):not(.theme-light) *::-webkit-scrollbar-track { background: transparent; }
body:has(.admin-layout):not(.theme-light) *::-webkit-scrollbar-thumb { background: #45474e; border-radius: 6px; }
body:has(.admin-layout):not(.theme-light) *::-webkit-scrollbar-thumb:hover { background: #55575e; }

/* Focus ring — the base rule's black-tinted glow is invisible on a dark
   surface; use a light-tinted one instead. */
body:has(.admin-layout):not(.theme-light) input:focus,
body:has(.admin-layout):not(.theme-light) select:focus,
body:has(.admin-layout):not(.theme-light) textarea:focus { box-shadow: 0 0 0 3px rgba(255,255,255,0.12); }

/* Form field borders specifically get an even stronger border than the
   general --pale-gray bump above — a field needs to visibly read as a
   field, not blend into its card. */
body:has(.admin-layout):not(.theme-light) input[type="text"],
body:has(.admin-layout):not(.theme-light) input[type="email"],
body:has(.admin-layout):not(.theme-light) input[type="password"],
body:has(.admin-layout):not(.theme-light) input[type="number"],
body:has(.admin-layout):not(.theme-light) input[type="tel"],
body:has(.admin-layout):not(.theme-light) input[type="date"],
body:has(.admin-layout):not(.theme-light) input[type="search"],
body:has(.admin-layout):not(.theme-light) select,
body:has(.admin-layout):not(.theme-light) textarea { border-color: #62656e; }

/* Sidebar nav labels use hardcoded rgba(255,255,255,X) rather than a
   token (the sidebar is "always dark," see comment above) — but those
   opacities were tuned for a light-mode reading and are dimmer than
   intended once the rest of the admin also goes dark. Brighten them to
   match. */
body:has(.admin-layout):not(.theme-light) .admin-sidebar__title { color: var(--mid-gray); }
body:has(.admin-layout):not(.theme-light) .admin-nav-group__heading { color: rgba(255,255,255,0.72); }
body:has(.admin-layout):not(.theme-light) .admin-nav-group__chevron { color: rgba(255,255,255,0.65); }
body:has(.admin-layout):not(.theme-light) .admin-nav-group__list a { color: rgba(255,255,255,0.8); }

/* Quill (assets/js/rich-editor.js) ships a light-only "snow" theme with
   hardcoded colors — re-theme it for the admin dark surface the same way
   everything else here gets re-themed, rather than leaving a bright white
   editor box floating in an otherwise dark page. */
body:has(.admin-layout):not(.theme-light) .ql-toolbar.ql-snow { background: var(--off-white); border-color: var(--pale-gray) !important; border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
body:has(.admin-layout):not(.theme-light) .ql-container.ql-snow { background: var(--white); border-color: var(--pale-gray) !important; border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
body:has(.admin-layout):not(.theme-light) .ql-editor { color: var(--near-black); min-height: 160px; }
body:has(.admin-layout):not(.theme-light) .ql-editor.ql-blank::before { color: var(--light-gray); font-style: normal; }
body:has(.admin-layout):not(.theme-light) .ql-snow .ql-stroke { stroke: var(--mid-gray); }
body:has(.admin-layout):not(.theme-light) .ql-snow .ql-fill { fill: var(--mid-gray); }
body:has(.admin-layout):not(.theme-light) .ql-snow .ql-picker { color: var(--mid-gray); }
body:has(.admin-layout):not(.theme-light) .ql-snow.ql-toolbar button:hover .ql-stroke,
body:has(.admin-layout):not(.theme-light) .ql-snow.ql-toolbar button.ql-active .ql-stroke { stroke: var(--near-black); }
body:has(.admin-layout):not(.theme-light) .ql-snow.ql-toolbar button:hover .ql-fill,
body:has(.admin-layout):not(.theme-light) .ql-snow.ql-toolbar button.ql-active .ql-fill { fill: var(--near-black); }
body:has(.admin-layout):not(.theme-light) .ql-snow .ql-picker-options { background: var(--white); border-color: var(--pale-gray) !important; }
body:has(.admin-layout):not(.theme-light) .ql-snow .ql-tooltip { background: var(--white); border-color: var(--pale-gray); color: var(--near-black); box-shadow: var(--shadow-md); }
body:has(.admin-layout):not(.theme-light) .ql-snow .ql-tooltip input[type=text] { background: var(--off-white); color: var(--near-black); border-color: var(--pale-gray); }

/* Sidebar was ALREADY dark by design (background:var(--near-black), with its
   own text at rgba(255,255,255,X) rather than var(--white)) — the token flip
   above would otherwise turn its background light while its text stays
   light too. Pin it back to a literal dark value, independent of the token. */
body:has(.admin-layout):not(.theme-light) .admin-sidebar { background: #121214; }
body:has(.admin-layout):not(.theme-light) .admin-nav-group__heading:hover,
body:has(.admin-layout):not(.theme-light) .admin-nav-group.open > .admin-nav-group__heading,
body:has(.admin-layout):not(.theme-light) .admin-nav-group.open > .admin-nav-group__heading .admin-nav-group__chevron,
body:has(.admin-layout):not(.theme-light) .admin-nav-group__list a:hover,
body:has(.admin-layout):not(.theme-light) .admin-nav-group__list a.active,
body:has(.admin-layout):not(.theme-light) .admin-nav-footer a:hover,
body:has(.admin-layout):not(.theme-light) .admin-nav-footer button.admin-theme-toggle:hover { color: #fff; }
body:has(.admin-layout):not(.theme-light) .admin-nav-group__list a.active { border-left-color: var(--group-accent, #fff); }

/* Public site-header is shared with the storefront (which stays light) but
   is also shown above every admin page — re-theme it only in that context. */
body:has(.admin-layout):not(.theme-light) .site-header { background: #121214; border-bottom-color: var(--pale-gray); }
body:has(.admin-layout):not(.theme-light) .site-header__logo,
body:has(.admin-layout):not(.theme-light) .site-nav a { color: var(--near-black); }
body:has(.admin-layout):not(.theme-light) .site-nav a:hover { background: var(--pale-gray); }
body:has(.admin-layout):not(.theme-light) .site-nav__sub { background: var(--white); border-color: var(--pale-gray); }
body:has(.admin-layout):not(.theme-light) .site-header__signout { color: var(--mid-gray); }
body:has(.admin-layout):not(.theme-light) .site-header__signout:hover { color: var(--near-black); }

/* A handful of "active pill" components pair background:var(--near-black)
   with a HARDCODED color:#fff rather than var(--white) — the token flip
   above makes their background light while the text stays hardcoded white,
   which breaks. Re-pin these specific ones to a literal mid-tone fill so
   white text keeps working. */
body:has(.admin-layout):not(.theme-light) .ops-board-tab.active,
body:has(.admin-layout):not(.theme-light) .req-filter-btn.active,
body:has(.admin-layout):not(.theme-light) .btn-start-print,
body:has(.admin-layout):not(.theme-light) .nj-mode-btn.active { background: #46484f !important; border-color: #46484f !important; }
body:has(.admin-layout):not(.theme-light) .btn-start-print:hover { background: #55575e !important; }

/* Alert boxes used near-white pastel fills that would read as glaring light
   patches on a dark page — tint them instead of a solid pastel. */
body:has(.admin-layout):not(.theme-light) .alert-error   { background: rgba(242,114,108,0.12); }
body:has(.admin-layout):not(.theme-light) .alert-success { background: rgba(61,220,132,0.12); }
body:has(.admin-layout):not(.theme-light) .alert-info    { background: rgba(255,255,255,0.06); color: var(--mid-gray); }

/* Same reasoning for the near-white row-highlight states on Jobs/Requests
   tables (urgent / bed-ready / overdue) — tint instead of solid pastel. */
body:has(.admin-layout):not(.theme-light) .req-table tr[data-urgent] td          { background: rgba(242,114,108,0.09); }
body:has(.admin-layout):not(.theme-light) .req-table tr[data-bed-ready] td       { background: rgba(234,88,12,0.14); }
body:has(.admin-layout):not(.theme-light) .req-table tr[data-bed-ready]:hover td { background: rgba(234,88,12,0.22); }
body:has(.admin-layout):not(.theme-light) tr[data-overdue="1"]       { background: rgba(242,114,108,0.14) !important; }
body:has(.admin-layout):not(.theme-light) tr[data-overdue="1"]:hover { background: rgba(242,114,108,0.22) !important; }
body:has(.admin-layout):not(.theme-light) tr[data-overdue="1"] td    { border-bottom-color: rgba(242,114,108,0.3); }

/* Customer-colored rows (Orders Board/Print Queue/Design Queue) now carry
   both background AND a contrasting color on the <tr> itself (see
   jobs_row_color_style()/dq_row_color_style()/orders-board.php), but several
   cell-level classes set their OWN explicit text color rather than
   inheriting — a direct rule on a descendant always wins over an ancestor's
   color regardless of where that ancestor's rule came from (inline or not),
   so the row's color was being silently ignored by exactly the elements
   carrying the customer's name/email/phone/notes. Force those specific
   classes back to inherit whenever they're inside a row that has a custom
   background — [style*="background:#"] matches only rows where PHP actually
   set one from row_color_palette(), not the plain (uncolored) majority. */
body:has(.admin-layout):not(.theme-light) tr[style*="background:#"] td,
body:has(.admin-layout):not(.theme-light) tr[style*="background:#"] td a,
body:has(.admin-layout):not(.theme-light) tr[style*="background:#"] .jobs-client,
body:has(.admin-layout):not(.theme-light) tr[style*="background:#"] .jobs-client a,
body:has(.admin-layout):not(.theme-light) tr[style*="background:#"] .jobs-email,
body:has(.admin-layout):not(.theme-light) tr[style*="background:#"] .jobs-phone,
body:has(.admin-layout):not(.theme-light) tr[style*="background:#"] .ob-clamp-preview,
body:has(.admin-layout):not(.theme-light) tr[style*="background:#"] .ops-board-editable {
    color: inherit !important;
}

/* Table row hover used var(--off-white), which is the darkest tone in this
   theme (page background) rather than a lighter "highlight" tone — hovering
   a row made it go noticeably darker instead of lighter, and on a colored
   row it fully painted over the pastel background with dark navy while the
   row's own black text stayed put, reading as washed-out/illegible. A
   translucent white wash instead always lightens whatever is underneath —
   the default dark row background or a colored row's pastel alike — without
   fully overriding it. */
body:has(.admin-layout):not(.theme-light) .req-table tr:hover td,
body:has(.admin-layout):not(.theme-light) tr:hover .ops-board-editable {
    background: rgba(255,255,255,0.10) !important;
}
body:has(.admin-layout):not(.theme-light) .ops-board-editable:hover {
    background: rgba(255,255,255,0.14) !important;
}
/* Same fix, missed the first pass — the clamped-text preview cells (Notes/
   Color/Print/Timeline) have their own separate :hover rule using the same
   darkest-tone token, producing the identical black-chip-on-hover problem. */
body:has(.admin-layout):not(.theme-light) tr:hover .ob-clamp-preview {
    background: rgba(255,255,255,0.10) !important;
}
body:has(.admin-layout):not(.theme-light) .ob-clamp-preview:hover {
    background: rgba(255,255,255,0.14) !important;
}
/* Same darkest-tone-as-hover pattern shows up on a couple of other admin
   lists/tables outside .req-table (plain <table> rows, the Ops Dashboard
   activity list) — same fix for consistency. */
body:has(.admin-layout):not(.theme-light) tr:hover td,
body:has(.admin-layout):not(.theme-light) .ops-item:hover,
body:has(.admin-layout):not(.theme-light) .nj-result-item:hover {
    background: rgba(255,255,255,0.10) !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   Latest Updates — public-facing, shared by updates.php, update.php,
   index.php's homepage strip, and about.php's horizontal section.
   Deliberately native-storefront look (white/near-black/serif), NOT
   Portfolio's dark editorial theme — this is company activity, not a
   curated gallery microsite. One set of classes, several containers.
   ══════════════════════════════════════════════════════════════════════════ */

.upd-card {
    display: flex; flex-direction: column; text-decoration: none;
    background: var(--white); border: 1px solid var(--pale-gray); border-radius: var(--radius-lg);
    overflow: hidden; transition: transform .15s, box-shadow .15s;
}
.upd-card:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(0,0,0,.08); text-decoration: none; }
.upd-card__media { position: relative; aspect-ratio: 4/3; background: var(--off-white); overflow: hidden; }
.upd-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.upd-card__media-empty { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 2rem; color: var(--light-gray); }
.upd-card__video-badge { position: absolute; top: .5rem; left: .5rem; z-index: 2; background: rgba(0,0,0,.72); color: #fff; font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: .2rem .5rem; border-radius: 999px; }
.upd-card__count { position: absolute; bottom: .5rem; right: .5rem; background: rgba(0,0,0,.65); color: #fff; font-size: .68rem; font-weight: 600; padding: .15rem .5rem; border-radius: 999px; }
.upd-card__body { padding: 1.1rem 1.25rem 1.3rem; flex: 1; display: flex; flex-direction: column; }
.upd-card__cat { font-family: var(--font-mono); font-size: .65rem; text-transform: uppercase; letter-spacing: .1em; color: var(--mid-gray); margin-bottom: .4rem; }
.upd-card__title { font-family: var(--font-serif); font-size: 1.15rem; line-height: 1.3; color: var(--near-black); margin-bottom: .3rem; }
.upd-card__date { font-size: .74rem; color: var(--light-gray); margin-bottom: .6rem; }
.upd-card__excerpt { font-size: .87rem; line-height: 1.55; color: var(--dark-gray); margin: 0; }

.upd-card--h { flex: 0 0 300px; scroll-snap-align: start; }

/* Horizontal scroll strip (About, homepage) — keyboard/touch/mouse
   accessible: a real scrollable region with visible affordance, never
   the ONLY way to reach the content (a "View All" link always exists
   alongside it). */
.upd-hscroll-wrap { position: relative; }
.upd-hscroll {
    display: flex; gap: 1.1rem; overflow-x: auto; padding: .5rem .1rem 1rem;
    scroll-snap-type: x proximity; scrollbar-width: thin;
}
.upd-hscroll:focus-visible { outline: 2px solid var(--near-black); outline-offset: 4px; }

.upd-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.5rem; }

.upd-section { padding: 3rem 1.5rem; }
.upd-section__head { max-width: 1120px; margin: 0 auto 1.5rem; display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: .75rem; }
.upd-section__head h2 { font-family: var(--font-serif); font-weight: 600; font-size: 1.85rem; color: var(--near-black); }
.upd-section__viewall { font-size: .85rem; color: var(--mid-gray); text-decoration: none; white-space: nowrap; }
.upd-section__viewall:hover { color: var(--near-black); }
.upd-section__inner { max-width: 1120px; margin: 0 auto; }

/* Individual update page */
.upd-full { max-width: 760px; margin: 0 auto; padding: 2.5rem 1.5rem 4rem; }
.upd-full__meta { display: flex; gap: .75rem; align-items: center; font-size: .78rem; color: var(--mid-gray); margin-bottom: .6rem; }
.upd-full__cat { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .08em; }
.upd-full__title { font-family: var(--font-serif); font-weight: 600; font-size: clamp(1.7rem, 4.2vw, 2.4rem); line-height: 1.2; color: var(--near-black); margin-bottom: .75rem; }
.upd-full__tags { display: flex; gap: .4rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.upd-tag { font-size: .74rem; color: var(--mid-gray); background: var(--off-white); border: 1px solid var(--pale-gray); border-radius: 999px; padding: .2rem .65rem; }

.upd-full__gallery { display: grid; gap: .6rem; margin-bottom: 1.75rem; border-radius: var(--radius-lg); overflow: hidden; }
.upd-full__gallery--one { grid-template-columns: 1fr; }
.upd-full__gallery--many { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.upd-full__media-item img, .upd-full__media-item video { width: 100%; display: block; border-radius: var(--radius-md); background: var(--off-white); }
.upd-full__media-item--video video { aspect-ratio: 16/9; object-fit: contain; background: #000; }

.upd-full__body { font-size: 1rem; line-height: 1.75; color: var(--dark-gray); margin-bottom: 2rem; white-space: pre-line; }
.upd-full__cta { margin-bottom: 2rem; }

.upd-full__share { display: flex; align-items: center; gap: .85rem; font-size: .82rem; padding-top: 1.25rem; border-top: 1px solid var(--pale-gray); margin-bottom: 1.5rem; }
.upd-full__share-lbl { color: var(--mid-gray); }
.upd-full__share a, .upd-copy-link { color: var(--near-black); text-decoration: none; border: 1px solid var(--pale-gray); border-radius: 999px; padding: .3rem .8rem; background: none; font-size: .8rem; cursor: pointer; font-family: var(--font-sans); }
.upd-full__share a:hover, .upd-copy-link:hover { border-color: var(--near-black); }

.upd-full__nav { display: flex; justify-content: space-between; gap: 1rem; padding-top: 1.25rem; border-top: 1px solid var(--pale-gray); }
.upd-full__nav-link { font-size: .85rem; color: var(--near-black); text-decoration: none; max-width: 45%; }
.upd-full__nav-link:hover { text-decoration: underline; }
.upd-full__nav-link--next { text-align: right; margin-left: auto; }

/* Archive page: hero, search/filter bar, load-more */
.upd-hero { background: var(--near-black); color: var(--white); padding: 3.5rem 1.5rem 2.5rem; text-align: center; }
.upd-hero h1 { font-family: var(--font-serif); font-weight: normal; font-size: clamp(1.7rem, 4.5vw, 2.5rem); color: var(--white); margin-bottom: .6rem; }
.upd-hero p { font-size: .95rem; color: rgba(255,255,255,.65); max-width: 560px; margin: 0 auto; line-height: 1.6; }

.upd-toolbar { max-width: 1120px; margin: 0 auto; padding: 1.75rem 1.5rem 0; display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.upd-toolbar input[type="search"] { flex: 1 1 240px; }
.upd-toolbar select { width: auto; }
.upd-toolbar__count { font-size: .8rem; color: var(--mid-gray); width: 100%; margin-top: .3rem; }

.upd-archive-main { max-width: 1120px; margin: 0 auto; padding: 1.5rem 1.5rem 4.5rem; }
.upd-load-more { display: block; margin: 2.5rem auto 0; }
.upd-empty { text-align: center; padding: 4rem 1rem; color: var(--mid-gray); }

@media (max-width: 640px) {
    .upd-full { padding: 1.75rem 1.1rem 3rem; }
    .upd-section { padding: 2.25rem 1.1rem; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Hidden Hunts — deep pan/zoom viewer (assets/js/hunt-viewer.js) +
   mask-based found-target effects. Vanilla JS/CSS, no external viewer
   library — see hunt-viewer.js's own header comment for why.
   ═══════════════════════════════════════════════════════════════════ */
.hv-viewport {
    position: relative; overflow: hidden; touch-action: none; cursor: grab;
    background: #0a0a0a; border-radius: var(--radius-lg);
    width: 100%; height: 100%;
}
.hv-viewport.hv-dragging { cursor: grabbing; }
.hv-stage {
    position: absolute; top: 0; left: 0; transform-origin: 0 0;
    will-change: transform;
}
.hv-stage img.hv-scene-img { display: block; width: 100%; height: 100%; user-select: none; -webkit-user-drag: none; pointer-events: none; }

.hv-found-mark { position: absolute; pointer-events: none; }
.hv-found-mark__mask {
    width: 100%; height: 100%; display: block; object-fit: contain;
    filter: drop-shadow(0 0 6px var(--hv-tint)) drop-shadow(0 0 16px var(--hv-tint)) brightness(1.15) saturate(1.3);
    animation: hvFoundPulse 0.6s ease-out;
}
.hv-found-mark--glow.hv-found-mark--maskless {
    border-radius: 50%;
    background: radial-gradient(circle, color-mix(in srgb, var(--hv-tint) 55%, transparent) 0%, transparent 70%);
    animation: hvFoundPulse 0.6s ease-out, hvFoundGlow 2.2s ease-in-out infinite 0.6s;
}
@keyframes hvFoundPulse {
    0%   { transform: scale(0.6); opacity: 0; }
    45%  { transform: scale(1.25); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}
@keyframes hvFoundGlow {
    0%, 100% { filter: brightness(1); }
    50%      { filter: brightness(1.4); }
}

/* Alternate found-effect display modes (spec section 2) — Glow above is
   the only one styled to full polish for V1; these are lighter-weight
   placeholders proving the architecture supports switching modes later
   (see hunt-viewer.js's markFound(), which only ever adds the --glow
   class today — a future settings toggle would add one of these instead). */
.hv-found-mark--tint .hv-found-mark__mask { filter: none; background-color: var(--hv-tint); mix-blend-mode: color; animation: hvFoundPulse 0.6s ease-out; }
.hv-found-mark--silhouette .hv-found-mark__mask { filter: brightness(0) saturate(100%) drop-shadow(0 0 0 var(--hv-tint)); animation: hvFoundPulse 0.6s ease-out; }
.hv-found-mark--outline { outline: 3px solid var(--hv-tint); border-radius: var(--radius-sm); animation: hvFoundPulse 0.6s ease-out; }
.hv-found-mark--fade .hv-found-mark__mask { opacity: 0.35; filter: grayscale(0.6); animation: hvFoundPulse 0.6s ease-out; }

/* ---- Hidden Hunts page chrome ------------------------------------- */
.hh-hero { background: #1a1a1a; color: #fff; padding: 3rem 1.5rem 2rem; text-align: center; }
.hh-hero h1 { font-family: var(--font-serif); font-weight: normal; font-size: clamp(1.7rem, 4.5vw, 2.5rem); margin-bottom: 0.5rem; }
.hh-hero p { font-size: 0.95rem; color: rgba(255,255,255,0.65); max-width: 620px; margin: 0 auto 1rem; line-height: 1.6; }
.hh-badge { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; padding: 0.35rem 0.85rem; border-radius: 999px; background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.25); color: #fff; }
.hh-main { max-width: 1180px; margin: 0 auto; padding: 2.5rem 1.5rem 4.5rem; }
.hh-section-title { font-family: var(--font-serif); font-size: 1.4rem; color: var(--near-black); margin-bottom: 1rem; }
.hh-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 1.1rem; margin-bottom: 3rem; }
.hh-card { display: flex; flex-direction: column; text-decoration: none; border: 1px solid var(--pale-gray); border-radius: var(--radius-lg); overflow: hidden; background: var(--white); transition: transform 0.15s, box-shadow 0.15s; }
.hh-card:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0,0,0,.08); text-decoration: none; }
.hh-card__img { aspect-ratio: 16/10; background: var(--off-white); overflow: hidden; position: relative; }
.hh-card__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hh-card__badge { position: absolute; top: 0.5rem; right: 0.5rem; font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.2rem 0.5rem; border-radius: 999px; background: rgba(0,0,0,0.65); color: #fff; }
.hh-card__body { padding: 1rem 1.15rem 1.15rem; }
.hh-card__title { font-family: var(--font-serif); font-size: 1.1rem; color: var(--near-black); margin-bottom: 0.3rem; }
.hh-card__meta { font-size: 0.78rem; color: var(--mid-gray); }
.hh-empty { text-align: center; color: var(--mid-gray); padding: 2.5rem 1rem; border: 1px dashed var(--pale-gray); border-radius: var(--radius-lg); margin-bottom: 3rem; }

.hh-generator { background: var(--off-white); border: 1px solid var(--pale-gray); border-radius: var(--radius-lg); padding: 1.5rem; margin-bottom: 3rem; }
.hh-generator__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem; }
.hh-generator__grid .full { grid-column: 1 / -1; }
.hh-generator label { display: block; font-size: 0.78rem; font-weight: 600; color: var(--mid-gray); margin-bottom: 0.3rem; }
@media (max-width: 640px) { .hh-generator__grid { grid-template-columns: 1fr; } }

.hh-progress { text-align: center; padding: 3rem 1.5rem; }
.hh-progress__spinner { width: 3rem; height: 3rem; border: 3px solid var(--pale-gray); border-top-color: var(--near-black); border-radius: 50%; margin: 0 auto 1.25rem; animation: hhSpin 0.9s linear infinite; }
@keyframes hhSpin { to { transform: rotate(360deg); } }
.hh-progress__msg { font-family: var(--font-serif); font-size: 1.2rem; color: var(--near-black); }

/* ---- Play page ------------------------------------------------------ */
.hp-play { display: grid; grid-template-columns: 1fr 300px; gap: 1.25rem; padding: 1.25rem 1.5rem; max-width: 1400px; margin: 0 auto; }
.hp-play__stage { position: relative; height: 72vh; min-height: 420px; border-radius: var(--radius-lg); overflow: hidden; background: #0d0d0f; }
.hp-play__stage canvas { display: block; touch-action: none; }
.hp-sidebar { display: flex; flex-direction: column; gap: 1rem; }

/* PixiJS game renderer — loading state, shown until createHuntGame()'s promise resolves */
.hp-loading { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem; color: rgba(255,255,255,0.7); text-align: center; padding: 1.5rem; }
.hp-loading__spinner { width: 2.5rem; height: 2.5rem; border: 3px solid rgba(255,255,255,0.15); border-top-color: #fff; border-radius: 50%; animation: hhSpin 0.9s linear infinite; }
.hp-loading__text { font-size: 0.9rem; }
.hp-loading--error .hp-loading__spinner { display: none; }
.hp-loading--error .hp-loading__text { color: #f87171; }

/* Immersive/fullscreen mode — the Fullscreen API only renders #hpPlayArea
   and its descendants, so the site header/footer disappear automatically;
   this just reflows the play area itself to fill the screen and turns the
   sidebar into a compact floating overlay instead of a fixed column. */
.hp-play--immersive { display: flex; width: 100vw; height: 100vh; max-width: none; margin: 0; padding: 0; gap: 0; background: #000; }
.hp-play--immersive .hp-play__stage { flex: 1; height: 100vh; min-height: 0; border-radius: 0; }
.hp-play--immersive .hp-sidebar { position: absolute; top: 1rem; right: 1rem; width: 260px; max-height: calc(100vh - 2rem); overflow-y: auto; z-index: 5; gap: 0.6rem; }
.hp-play--immersive .hp-card { background: rgba(15,15,17,0.85); backdrop-filter: blur(8px); border-color: rgba(255,255,255,0.12); padding: 0.8rem 0.9rem; }
.hp-play--immersive .hp-card__title { color: rgba(255,255,255,0.55); }
.hp-play--immersive .hp-checklist li { color: rgba(255,255,255,0.85); }
.hp-play--immersive .hp-checklist li.found { color: rgba(255,255,255,0.4); }
body.hp-immersive-active { overflow: hidden; }
.hp-card { background: var(--white); border: 1px solid var(--pale-gray); border-radius: var(--radius-lg); padding: 1.1rem 1.25rem; }
.hp-card__title { font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--light-gray); margin-bottom: 0.75rem; }
.hp-checklist { list-style: none; display: flex; flex-direction: column; gap: 0.55rem; }
.hp-checklist li { display: flex; align-items: center; gap: 0.55rem; font-size: 0.86rem; color: var(--dark-gray); }
.hp-checklist li.found { color: var(--mid-gray); text-decoration: line-through; }
.hp-checklist__dot { width: 0.85rem; height: 0.85rem; border-radius: 50%; border: 2px solid var(--pale-gray); flex-shrink: 0; }
.hp-checklist li.found .hp-checklist__dot { background: var(--near-black); border-color: var(--near-black); }
.hp-checklist li.primary .hp-checklist__dot { border-color: #eab54e; }
.hp-color-row { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; }
.hp-color-swatch { width: 1.6rem; height: 1.6rem; border-radius: 50%; border: 2px solid transparent; cursor: pointer; }
.hp-color-swatch.active { border-color: var(--near-black); }
.hp-toolbar { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.hp-complete { text-align: center; padding: 1.25rem; background: var(--off-white); border-radius: var(--radius-md); }
@media (max-width: 900px) {
    .hp-play { grid-template-columns: 1fr; padding: 1rem; }
    .hp-play__stage { height: 56vh; }
}
