/* ============================================================
   Greek Library of London LMS — staff redesign
   public/css/staff.css

   Loaded ONLY by app/views/layouts/staff.php and
   app/views/layouts/auth.php, after main.css and components.css.
   Everything is scoped under `.staff-body`, so the OPAC, member
   portal and kiosk layouts — which share the same class names
   out of main.css — are left completely untouched.

   Design language is inherited from the OPAC (public/css/opac.css)
   and the member portal: light surfaces (#f9f8f9 page / #ffffff
   cards), 14px card radius, pill controls, black + brand-red
   buttons, Poppins type, soft layered shadows.
   ============================================================ */

.staff-body {
    /* ── Scoped surfaces (mirrors .opac-body) ─────────────── */
    --s-bg:          #f9f8f9;
    --s-surface:     #ffffff;
    --s-border:      #e6e8ef;
    --s-border-soft: #f0f1f5;

    --s-accent:       #d90a2c;
    --s-accent-soft:  rgba(217, 10, 44, 0.08);
    --s-accent-hover: #b60824;
    --s-black:        #111318;
    --s-navy:         #00378F;
    --s-lime:         #AAC10A;

    --s-text:      #111827;
    --s-text-soft: #374151;
    --s-muted:     #6b7280;

    --s-radius-sm:   8px;
    --s-radius:      14px;
    --s-radius-full: 999px;

    --s-shadow-sm: 0 1px 3px rgba(17, 19, 24, 0.06);
    --s-shadow-md: 0 6px 18px rgba(17, 19, 24, 0.08), 0 2px 5px rgba(17, 19, 24, 0.04);
    --s-shadow-lg: 0 18px 44px rgba(17, 19, 24, 0.12), 0 5px 14px rgba(17, 19, 24, 0.06);

    /* ── Re-point the shared tokens ────────────────────────
       main.css is written almost entirely against these vars,
       so overriding them here re-skins every card, table,
       badge, form and button on the staff side at once.     */
    --color-accent:       #d90a2c;
    --color-accent-soft:  rgba(217, 10, 44, 0.08);
    --color-accent-hover: #b60824;

    --color-bg:            #f9f8f9;
    --color-border:        #e6e8ef;
    --color-border-subtle: #f0f1f5;

    --radius-sm: 8px;
    --radius:    10px;
    --radius-lg: 14px;
    --radius-xl: 18px;

    --shadow-xs: 0 1px 3px rgba(17, 19, 24, 0.06);
    --shadow-sm: 0 1px 3px rgba(17, 19, 24, 0.06);
    --shadow-md: 0 6px 18px rgba(17, 19, 24, 0.08), 0 2px 5px rgba(17, 19, 24, 0.04);
    --shadow-lg: 0 18px 44px rgba(17, 19, 24, 0.12), 0 5px 14px rgba(17, 19, 24, 0.06);

    --sidebar-width: 244px;

    background: var(--s-bg);
    color: var(--s-text);
}

.staff-body a:hover { color: var(--s-accent); }

.staff-body :focus-visible {
    outline: 2px solid var(--s-accent);
    outline-offset: 2px;
    border-radius: 4px;
}


/* ================================================================
   SIDEBAR
   ================================================================ */
.staff-body .sidebar {
    background: var(--s-surface);
    border-right: 1px solid var(--s-border);
    padding-bottom: var(--sp-2);
}

/* -- Brand ---------------------------------------------------- */
/* The tag sits beside the wordmark when it fits and drops to its
   own line when it does not. "Staff" fits the 244px sidebar; the
   Greek "Προσωπικό" is nearly twice as wide and used to overrun
   the edge. Wrapping adapts to whatever a language needs, rather
   than pinning the logo to a height that only just squeezes one
   translation in. */
.staff-body .sidebar__brand {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.6rem;
    padding: 1.25rem 1.15rem 1.1rem;
    border-bottom: 1px solid var(--s-border-soft);
    min-height: 0;
    /* .sidebar is a flex column: without this the brand is the item
       that gives way when an accordion group opens and the nav grows
       past the viewport, crushing its padding around the wordmark. */
    flex-shrink: 0;
}

/* The shared rule gives this no top padding, which leaves the
   language pill sitting on the brand's divider. Scoped to the
   staff shell so the OPAC and login shells keep their spacing. */
.staff-body .sidebar__lang {
    padding: var(--sp-4) var(--sp-4) var(--sp-2);
    flex-shrink: 0;
}

/* The wide wordmark plus the "Staff" tag has to fit a 244px sidebar,
   so height is kept low enough that its width leaves room for both. */
.staff-body .sidebar__brand-logo {
    height: 30px;
    width: auto;
    max-width: 100%;
    min-width: 0;
    object-fit: contain;
}

/* Small "Staff" tag next to the logo, so the back-office is
   instantly distinguishable from the public catalogue. */
.staff-body .sidebar__brand-tag {
    display: inline-flex;
    align-items: center;
    padding: 0.18rem 0.5rem;
    border-radius: var(--s-radius-full);
    background: var(--s-black);
    color: #fff;
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    flex-shrink: 0;
}

/* -- Nav ------------------------------------------------------ */
/* The language switch above supplies the top gap, so the nav
   starts tight and spends its space between the rows instead. */
.staff-body .sidebar__nav {
    padding: 0.25rem 0.7rem 1rem;
    gap: 4px;
}

/* Section labels are the main grouping cue in a 12-item sidebar,
   so the space above one is what separates the groups. */
.staff-body .sidebar__nav-label {
    padding: 1.35rem 0.75rem 0.5rem;
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--s-muted);
}
.staff-body .sidebar__nav-label:first-child { padding-top: 0.55rem; }

.staff-body .sidebar__nav-item,
.staff-body .sidebar__group-toggle {
    display: flex;
    align-items: center;
    width: 100%;
    background: none;
    border: none;
    text-align: left;
    font-family: inherit;
    cursor: pointer;
    gap: 0.6rem;
    padding: 0.62rem 0.8rem;
    border-radius: var(--s-radius-full);
    font-size: 0.855rem;
    font-weight: 500;
    color: var(--s-text-soft);
    transition: background var(--ease), color var(--ease);
}

.staff-body .sidebar__nav-item:hover,
.staff-body .sidebar__group-toggle:hover {
    background: var(--s-border-soft);
    color: var(--s-text);
}

/* Active item = solid black pill, exactly like .opac-nav__item--active */
.staff-body .sidebar__nav-item--active,
.staff-body .sidebar__nav-item--active:hover {
    background: var(--s-black);
    color: #fff;
    font-weight: 600;
}

/* main.css turns the active icon into an accent square — undo it,
   the pill already carries the state. */
.staff-body .sidebar__nav-icon {
    width: 18px;
    height: 18px;
    border-radius: 0;
    background: transparent;
    color: var(--s-muted);
    transition: color var(--ease);
}

.staff-body .sidebar__nav-item:hover .sidebar__nav-icon,
.staff-body .sidebar__group-toggle:hover .sidebar__nav-icon { color: var(--s-text); }

.staff-body .sidebar__nav-item--active .sidebar__nav-icon,
.staff-body .sidebar__nav-item--active:hover .sidebar__nav-icon {
    background: transparent;
    color: #fff;
    font-size: inherit;
}

/* -- Accordion groups ----------------------------------------- */
.staff-body .sidebar__group-items {
    margin: 5px 0 7px;
    padding-left: 1.45rem;
    border-left: 1px solid var(--s-border);
    margin-left: 1.5rem;
}

.staff-body .sidebar__nav-item--child {
    padding-left: 0.7rem;
    font-size: 0.83rem;
    font-weight: 400;
}

.staff-body .sidebar__nav-item--child .sidebar__nav-icon {
    width: 16px;
    height: 16px;
}

.staff-body .sidebar__group-chevron { color: var(--s-muted); }

/* -- Footer ---------------------------------------------------- */
.staff-body .sidebar__footer {
    flex-shrink: 0;
    padding: 0.5rem 0.7rem 0.7rem;
    border-top: 1px solid var(--s-border-soft);
}

/* Product name + running version, at the very bottom of the rail.
   The version is the reason it earns the space: it answers "did my
   deploy land?" without opening a terminal. */
.staff-body .sidebar__product {
    margin: 0.55rem 0 0;
    padding: 0 0.35rem;
    font-size: 0.7rem;
    line-height: 1.4;
    color: var(--s-muted);
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
}
.staff-body .sidebar__product-name { font-weight: 600; }
.staff-body .sidebar__product-version {
    opacity: 0.65;
    font-variant-numeric: tabular-nums;
}


/* ================================================================
   MOBILE TOPBAR
   ================================================================ */
.staff-body .mobile-topbar {
    background: rgba(249, 248, 249, 0.88);
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    border-bottom: 1px solid var(--s-border);
    color: var(--s-text);
    padding: 0.6rem var(--sp-4);
}

.staff-body .mobile-topbar__toggle {
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    color: var(--s-text);
    border-radius: var(--s-radius-full);
    width: 44px;
    height: 44px;
    transition: background var(--ease), color var(--ease), border-color var(--ease);
}
.staff-body .mobile-topbar__toggle:hover {
    background: var(--s-black);
    border-color: var(--s-black);
    color: #fff;
}

.staff-body .mobile-topbar__brand { color: var(--s-text); }
.staff-body .mobile-topbar__end {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
    flex-shrink: 0;
}

/* The topbar carries the account menu as well as the language
   switcher now, so the wordmark is the part that gives way. */
.staff-body .mobile-topbar__brand {
    min-width: 0;
    overflow: hidden;
}
.staff-body .mobile-topbar__logo {
    max-width: 100%;
    object-fit: contain;
    object-position: left center;
}

@media (max-width: 480px) {
    .staff-body .mobile-topbar__brand .sidebar__brand-tag { display: none; }
}
.staff-body .mobile-topbar__logo { height: 30px; width: auto; }

.staff-body .sidebar-overlay { background: rgba(17, 19, 24, 0.42); }


/* ================================================================
   PAGE HEADER — translucent sticky bar, matches .opac-header
   ================================================================ */
/* The sidebar is position:fixed, so the shell does not need to be a
   grid — and dropping it lets the main column size itself from its
   containing block instead of `calc(100vw - sidebar)`. 100vw counts
   the classic scrollbar, which pushed the page into horizontal
   scroll on Windows/Linux. */
.staff-body .app-shell { display: block; }

.staff-body .main-content {
    background: var(--s-bg);
    margin-left: var(--sidebar-width);
    width: auto;
}

@media (max-width: 1024px) {
    .staff-body .main-content { margin-left: 0; }
}

.staff-body .page-header {
    background: rgba(249, 248, 249, 0.86);
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    border-bottom: 1px solid var(--s-border);
    padding: 1.1rem var(--sp-8);
    align-items: flex-end;
}

.staff-body .page-header__title {
    font-size: 1.55rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    color: var(--s-text);
}

.staff-body .page-header__sub {
    font-size: 0.83rem;
    color: var(--s-muted);
    margin-top: 0.15rem;
}

.staff-body .page-header__actions { gap: 0.55rem; }

.staff-body .page-header__lead { min-width: 0; }
.staff-body .page-header__end {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-shrink: 0;
}


/* ================================================================
   ACCOUNT MENU — the staff twin of .member-profile-menu
   Rendered twice by layouts/staff.php: in the page header on
   desktop, in the mobile topbar below 1024px. Only one is ever
   visible, so the two never collide.
   ================================================================ */
.staff-body .staff-profile-menu {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
}
.staff-body .staff-profile-menu--mobile  { display: none; }

.staff-body .staff-profile-menu__btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.85rem;
    border: none;
    border-radius: var(--s-radius-full);
    background: var(--s-accent);
    color: #fff;
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: background var(--ease);
}
.staff-body .staff-profile-menu__btn:hover { background: var(--s-accent-hover); }
.staff-body .staff-profile-menu__btn-name {
    max-width: 12rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.staff-body .staff-profile-menu__caret {
    margin-left: 0.15rem;
    transition: transform var(--ease);
}
.staff-body .staff-profile-menu__btn[aria-expanded="true"] .staff-profile-menu__caret {
    transform: rotate(180deg);
}

.staff-body .staff-profile-menu__panel {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    min-width: 232px;
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
    box-shadow: var(--s-shadow-md);
    padding: 0.4rem;
    z-index: 300;
}
.staff-body .staff-profile-menu__panel[hidden] { display: none; }

.staff-body .staff-profile-menu__head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.75rem 0.4rem;
}
.staff-body .staff-profile-menu__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--s-accent-soft);
    color: var(--s-accent);
    font-size: 0.9rem;
    font-weight: 700;
}
.staff-body .staff-profile-menu__id { min-width: 0; }
.staff-body .staff-profile-menu__name {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--s-text);
}
/* Emails are long and the panel is not — let it truncate rather
   than stretch the menu to the width of the address. */
.staff-body .staff-profile-menu__email {
    font-size: 0.75rem;
    color: var(--s-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 11rem;
}
.staff-body .staff-profile-menu__role {
    margin: 0 0.75rem 0.15rem;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--s-muted);
}

.staff-body .staff-profile-menu__item {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 0.55rem 0.75rem;
    border: none;
    border-radius: var(--s-radius-sm);
    background: none;
    color: var(--s-text);
    font: inherit;
    font-size: 0.875rem;
    font-weight: 500;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--ease), color var(--ease);
}
.staff-body .staff-profile-menu__item:hover { background: var(--s-border-soft); }
.staff-body .staff-profile-menu__item--danger { color: var(--s-accent); }
.staff-body .staff-profile-menu__item--danger:hover { background: var(--s-accent-soft); }
.staff-body .staff-profile-menu__divider {
    height: 1px;
    background: var(--s-border-soft);
    margin: 0.3rem 0.25rem;
}

.staff-body .page-body {
    padding: var(--sp-6) var(--sp-8) var(--sp-16);
    max-width: 1560px;
}


/* ================================================================
   BUTTONS — pill controls, black + brand red
   ================================================================ */
.staff-body .btn {
    border-radius: var(--s-radius-full);
    padding: 0.55rem 1.15rem;
    font-size: 0.855rem;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--ease), color var(--ease),
                border-color var(--ease), transform var(--ease), box-shadow var(--ease);
}

.staff-body .btn--primary {
    background: var(--s-accent);
    border-color: var(--s-accent);
    color: #fff;
}
.staff-body .btn--primary:hover {
    background: var(--s-accent-hover);
    border-color: var(--s-accent-hover);
    transform: translateY(-1px);
    box-shadow: var(--s-shadow-md);
}

.staff-body .btn--secondary {
    background: var(--s-black);
    border-color: var(--s-black);
    color: #fff;
}
.staff-body .btn--secondary:hover {
    background: #000;
    border-color: #000;
    color: #fff;
    transform: translateY(-1px);
    box-shadow: var(--s-shadow-md);
}

/* Ghost buttons behave like .opac-browse-btn: white pill → black */
.staff-body .btn--ghost {
    background: var(--s-surface);
    border-color: var(--s-border);
    color: var(--s-text);
}
.staff-body .btn--ghost:hover {
    background: var(--s-black);
    border-color: var(--s-black);
    color: #fff;
    transform: translateY(-1px);
    box-shadow: var(--s-shadow-md);
}
.staff-body .btn--ghost svg { color: var(--s-muted); transition: color var(--ease); }
.staff-body .btn--ghost:hover svg { color: #fff; }

.staff-body .btn--danger {
    background: var(--s-accent);
    border-color: var(--s-accent);
}
.staff-body .btn--danger:hover {
    background: var(--s-accent-hover);
    border-color: var(--s-accent-hover);
    transform: translateY(-1px);
    box-shadow: var(--s-shadow-md);
}

/* Used ~13 times on the dashboard alone for "View All"-style secondary
   actions. Outlining every one in brand red turns the page into a wall
   of red pills, so these get the same neutral treatment as .btn--ghost
   and red is reserved for genuinely primary actions. */
.staff-body .btn--outline-primary {
    background: var(--s-surface);
    border-color: var(--s-border);
    color: var(--s-text-soft);
}
.staff-body .btn--outline-primary:hover {
    background: var(--s-black);
    border-color: var(--s-black);
    color: #fff;
    transform: translateY(-1px);
    box-shadow: var(--s-shadow-md);
}

/* main.css only defines .btn--small; several views use .btn--sm. */
.staff-body .btn--small,
.staff-body .btn--sm {
    padding: 0.32rem 0.8rem;
    font-size: 0.775rem;
}

.staff-body .btn:disabled,
.staff-body .btn.is-disabled {
    opacity: 0.5;
    pointer-events: none;
}


/* ================================================================
   CARDS
   ================================================================ */
.staff-body .card {
    border-radius: var(--s-radius);
    border-color: var(--s-border);
    box-shadow: var(--s-shadow-sm);
}

.staff-body .card__header {
    padding: 1.1rem 1.35rem;
    border-bottom: 1px solid var(--s-border-soft);
}

.staff-body .card__title {
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: -0.015em;
}

.staff-body .card__body { padding: 1.2rem 1.35rem; }


/* ================================================================
   STAT CARDS — hover-lift, like .member-stat
   ================================================================ */
.staff-body .grid-stats {
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 0.9rem;
}

.staff-body .stat-card {
    border-radius: var(--s-radius);
    border-color: var(--s-border);
    box-shadow: var(--s-shadow-sm);
    padding: 1.1rem 1.15rem;
    gap: 0.85rem;
    align-items: center;
    transition: transform var(--ease), box-shadow var(--ease), border-color var(--ease);
}

.staff-body a.stat-card:hover,
.staff-body .stat-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--s-shadow-md);
    border-color: transparent;
}

.staff-body .stat-card__icon {
    width: 40px;
    height: 40px;
    border-radius: var(--s-radius-sm);
    background: var(--s-accent-soft);
    color: var(--s-accent);
}
.staff-body .stat-card__icon--navy  { background: rgba(0,55,143,0.09);   color: var(--s-navy); }
.staff-body .stat-card__icon--green { background: rgba(22,163,74,0.10);  color: #16a34a; }
.staff-body .stat-card__icon--red   { background: var(--s-accent-soft);  color: var(--s-accent); }
.staff-body .stat-card__icon--amber { background: rgba(217,119,6,0.11);  color: #d97706; }
.staff-body .stat-card__icon--blue  { background: rgba(37,99,235,0.10);  color: #2563eb; }
.staff-body .stat-card__icon--accent{ background: var(--s-accent-soft);  color: var(--s-accent); }

.staff-body .stat-card__label {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--s-muted);
    margin-bottom: 0.3rem;
}

.staff-body .stat-card__value {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.035em;
}


/* ================================================================
   TABLES
   ================================================================ */
.staff-body .table-wrap,
.staff-body .books-table-wrap,
.staff-body .members-table-wrap {
    overflow-x: auto;
    border-radius: var(--s-radius);
}

.staff-body .data-table thead th,
.staff-body .books-table thead th,
.staff-body .members-table thead th,
.staff-body .report-table thead th {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--s-muted);
    padding: 0.7rem var(--sp-4);
    border-bottom: 1px solid var(--s-border);
    background: transparent;
}

.staff-body .data-table tbody td,
.staff-body .books-table tbody td,
.staff-body .members-table tbody td,
.staff-body .report-table tbody td {
    padding: 0.8rem var(--sp-4);
    border-bottom: 1px solid var(--s-border-soft);
    color: var(--s-text-soft);
}

.staff-body .data-table tbody tr,
.staff-body .books-table tbody tr,
.staff-body .members-table tbody tr {
    transition: background var(--ease);
}

.staff-body .data-table tbody tr:hover td,
.staff-body .books-table tbody tr:hover td,
.staff-body .members-table tbody tr:hover td {
    background: var(--s-bg);
}

.staff-body .table-link,
.staff-body .member-name-link {
    font-weight: 600;
    color: var(--s-text);
}
.staff-body .table-link:hover,
.staff-body .member-name-link:hover { color: var(--s-accent); }

.staff-body .member-cell__avatar {
    background: var(--s-accent-soft);
    color: var(--s-accent);
    box-shadow: 0 0 0 1px var(--s-border);
}

.staff-body .book-cell__cover,
.staff-body .book-cell__cover--placeholder {
    width: 34px;
    height: 48px;
    border-radius: 5px;
    border-color: var(--s-border-soft);
    color: var(--s-muted);
}


/* ================================================================
   BADGES
   ================================================================ */
.staff-body .badge {
    padding: 0.22rem 0.6rem;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.015em;
}

.staff-body .badge--accent,
.staff-body .badge--red {
    color: var(--s-accent);
    background: var(--s-accent-soft);
}

.staff-body .badge--solid-accent { background: var(--s-accent); color: #fff; }
.staff-body .badge--premium      { background: var(--s-black); color: #fff; }


/* ================================================================
   TOOLBAR / FILTERS — pill search, like the OPAC search field
   ================================================================ */
.staff-body .toolbar {
    gap: 0.6rem;
    margin-bottom: var(--sp-5);
}

.staff-body .toolbar .form-field__input,
.staff-body .toolbar .form-field__select,
.staff-body .toolbar input[type="search"],
.staff-body .toolbar input[type="text"],
.staff-body .toolbar select {
    border-radius: var(--s-radius-full);
    padding: 0.6rem 1.05rem;
    background: var(--s-surface);
}

.staff-body .toolbar__filter { width: 190px; }


/* ================================================================
   FORMS
   ================================================================ */
.staff-body .form-field__input,
.staff-body .form-field__select,
.staff-body .settings-field__input,
.staff-body textarea {
    border: 1.5px solid var(--s-border);
    border-radius: var(--s-radius-sm);
    padding: 0.6rem 0.85rem;
    font-size: 0.875rem;
    font-family: var(--font-body);
    color: var(--s-text);
    background: var(--s-surface);
    width: 100%;
    line-height: 1.5;
    outline: none;
    transition: border-color var(--ease), box-shadow var(--ease);
    box-sizing: border-box;
}

.staff-body .form-field__input:focus,
.staff-body .form-field__select:focus,
.staff-body .settings-field__input:focus,
.staff-body textarea:focus {
    border-color: var(--s-accent);
    box-shadow: 0 0 0 3px var(--s-accent-soft);
}

.staff-body .form-field__input::placeholder,
.staff-body .settings-field__input::placeholder { color: #9ca3af; }

.staff-body .form-label,
.staff-body .form-field__label,
.staff-body .settings-field__label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--s-text-soft);
    margin-bottom: 0.35rem;
    letter-spacing: 0.01em;
}

.staff-body .form-hint,
.staff-body .form-field__note,
.staff-body .settings-field__desc {
    font-size: 0.75rem;
    color: var(--s-muted);
    margin-top: 0.3rem;
    line-height: 1.5;
}

.staff-body .form-required { color: var(--s-accent); }

.staff-body .settings-field { margin-bottom: 1.25rem; }
.staff-body .settings-field__input--wide { max-width: 100%; }
.staff-body .settings-field__unit {
    font-size: 0.8rem;
    color: var(--s-muted);
    margin-left: 0.4rem;
}

.staff-body .form-section-title {
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: -0.015em;
}

.staff-body .form-actions {
    padding-top: var(--sp-5);
    border-top: 1px solid var(--s-border-soft);
    gap: 0.6rem;
}

.staff-body .form-label--checkbox input[type="checkbox"] { accent-color: var(--s-accent); }


/* ================================================================
   ALERTS / VALIDATION
   ================================================================ */
.staff-body .alert {
    border-radius: var(--s-radius-sm);
    font-size: 0.855rem;
}

.staff-body .alert--error {
    background: var(--s-accent-soft);
    border-color: rgba(217, 10, 44, 0.18);
    color: var(--s-accent-hover);
}

.staff-body .form-errors {
    background: var(--s-accent-soft);
    border: 1px solid rgba(217, 10, 44, 0.18);
    border-radius: var(--s-radius-sm);
    padding: 0.8rem 1rem;
    margin-bottom: 1.15rem;
}

.staff-body .form-errors__item {
    font-size: 0.85rem;
    color: var(--s-accent-hover);
    margin: 0;
}
.staff-body .form-errors__item + .form-errors__item { margin-top: 0.25rem; }

/* Flash toasts are deliberately NOT restyled here — they are shared
   with the member portal, OPAC, auth and kiosk layouts, and are
   defined once in main.css so every surface shows the same component.
   The staff layout renders them inside .page-body for the same
   reason: identical gutters, no per-layout overrides. */


/* ================================================================
   TABS (fines, reports)
   ================================================================ */
.staff-body .fines-tab {
    border-radius: var(--s-radius-full);
    font-weight: 600;
    font-size: 0.83rem;
    padding: 0.5rem 1rem;
    border: 1px solid var(--s-border);
    background: var(--s-surface);
    color: var(--s-text-soft);
    transition: background var(--ease), color var(--ease), border-color var(--ease);
}
.staff-body .fines-tab:hover {
    background: var(--s-border-soft);
    color: var(--s-text);
}
.staff-body .fines-tab--active,
.staff-body .fines-tab--active:hover {
    background: var(--s-black);
    border-color: var(--s-black);
    color: #fff;
}


/* ================================================================
   REPORTS
   ================================================================ */
.staff-body .report-section,
.staff-body .report-card {
    border-radius: var(--s-radius);
    border-color: var(--s-border);
    box-shadow: var(--s-shadow-sm);
}

.staff-body .report-section__title {
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.staff-body .report-bar-track {
    border-radius: var(--s-radius-full);
    background: var(--s-border-soft);
}
.staff-body .report-bar-fill {
    border-radius: var(--s-radius-full);
    background: var(--s-accent);
}


/* ================================================================
   DASHBOARD PANELS
   ================================================================ */
/* Let the action buttons drop to their own line instead of squeezing
   the panel title into a wrap. */
.staff-body .dashboard-panel__header {
    gap: 0.75rem;
    flex-wrap: wrap;
}

.staff-body .dashboard-panel__title {
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

/* This is a 3px rule down the left of the panel title — NOT a fill.
   Setting `background` here paints the whole title block red. */
.staff-body .db-panel__accent-bar {
    background: none;
    border-left: 3px solid var(--s-accent);
    padding-left: 0.6rem;
    line-height: 1.35;
}

.staff-body .db-item__link:hover { background: var(--s-bg); }

.staff-body .db-modal {
    border-radius: var(--s-radius);
    box-shadow: var(--s-shadow-lg);
}
.staff-body .db-modal-backdrop { background: rgba(17, 19, 24, 0.42); }

.staff-body .db-ac-list {
    border-radius: var(--s-radius-sm);
    box-shadow: var(--s-shadow-md);
    border-color: var(--s-border);
}


/* ================================================================
   PROFILE / CONTACT CARDS
   ================================================================ */
.staff-body .contact-card {
    border-radius: var(--s-radius);
    border-color: var(--s-border);
    box-shadow: var(--s-shadow-sm);
}
.staff-body .contact-card__header { border-bottom-color: var(--s-border-soft); }
.staff-body .profile-detail__label { color: var(--s-muted); }


/* ================================================================
   EMPTY STATE
   ================================================================ */
.staff-body .empty-state {
    padding: var(--sp-12) var(--sp-8);
    color: var(--s-muted);
}

.staff-body .empty-state__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.75rem;
    color: #d1d5db;
    opacity: 1;
}

.staff-body .empty-state__message {
    font-size: 0.925rem;
    color: var(--s-muted);
}


/* ================================================================
   PAGINATION
   ================================================================ */
.staff-body .pagination__btn,
.staff-body .pagination__page {
    border-radius: var(--s-radius-full);
    border: 1px solid var(--s-border);
    background: var(--s-surface);
    font-weight: 600;
    transition: background var(--ease), color var(--ease), border-color var(--ease);
}

.staff-body .pagination__btn:hover:not(.is-disabled),
.staff-body .pagination__page:hover {
    background: var(--s-black);
    border-color: var(--s-black);
    color: #fff;
}

.staff-body .pagination__page--active,
.staff-body .pagination__page--active:hover {
    background: var(--s-accent);
    border-color: var(--s-accent);
    color: #fff;
}


/* ================================================================
   AUTH (staff sign-in) — mirrors the OPAC member login card
   ================================================================ */
.staff-body.auth-body {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background: var(--s-bg);
    padding: var(--sp-6) var(--sp-4);
}

.staff-body .auth-wrapper {
    width: 100%;
    max-width: 420px;
    padding: 0;
}

.staff-body .auth-brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.6rem;
}

.staff-body .auth-brand__logo {
    height: 64px;
    width: auto;
}

.staff-body .auth-brand__tag {
    display: inline-flex;
    align-items: center;
    padding: 0.22rem 0.7rem;
    border-radius: var(--s-radius-full);
    background: var(--s-black);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.staff-body .auth-card {
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
    padding: 2.25rem 2rem;
    box-shadow: var(--s-shadow-lg);
}

.staff-body .auth-card__heading {
    font-size: 1.5rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    color: var(--s-text);
    margin: 0 0 0.4rem;
    text-align: center;
}

.staff-body .auth-card__sub {
    font-size: 0.865rem;
    color: var(--s-muted);
    line-height: 1.6;
    margin: 0 0 1.75rem;
    text-align: center;
}

.staff-body .auth-form .form-field { margin-bottom: 1.05rem; }

.staff-body .auth-form__submit {
    width: 100%;
    margin-top: 1.35rem;
    padding: 0.75rem 1rem;
    font-size: 0.95rem;
}

.staff-body .auth-card__footer {
    text-align: center;
    margin-top: 1.5rem;
    font-size: 0.83rem;
    color: var(--s-muted);
}
.staff-body .auth-card__footer a {
    color: var(--s-accent);
    font-weight: 600;
}
.staff-body .auth-card__footer a:hover { color: var(--s-accent-hover); }

/* Under the sign-in card, below the "looking for the catalogue?"
   line, so the library's logo at the top stays the first thing read. */
.staff-body .product-credit--auth {
    text-align: center;
    margin-top: 2rem;
    font-size: 0.75rem;
    color: var(--s-muted);
    opacity: 0.8;
}


/* ================================================================
   ICON NORMALISATION
   The staff views previously used emoji as icons; they are now
   inline SVG, so the containers that were sized with font-size
   need explicit svg sizing instead.
   ================================================================ */

/* Icons sitting inline in a run of text need a nudge onto the baseline. */
.staff-body td > svg,
.staff-body .member-cell__id > svg,
.staff-body .res-info-banner > svg,
.staff-body .co-modal__fine-line > svg { vertical-align: -0.15em; }

/* Cover placeholders */
.staff-body .book-cell__cover--placeholder svg { width: 15px; height: 15px; }

.staff-body .db-item__cover--placeholder {
    color: #9ca3af;
    background: var(--s-bg);
    border-color: var(--s-border);
    border-radius: var(--s-radius-sm);
}
.staff-body .db-item__cover--placeholder svg { width: 22px; height: 22px; }
.staff-body .db-item__cover--overdue { color: var(--s-accent); }

.staff-body .book-card__cover--placeholder {
    color: #c9ced8;
    border-radius: var(--s-radius);
}
.staff-body .book-card__cover--placeholder svg { width: 38px; height: 38px; }

/* Contact card icons */
.staff-body .contact-item__icon {
    border-radius: var(--s-radius-sm);
    background: var(--s-bg);
    color: var(--s-muted);
}

/* Top-authors rank — a numbered pill instead of medal emoji */
.staff-body .db-rank-medal {
    margin-left: auto;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--s-bg);
    border: 1px solid var(--s-border);
    color: var(--s-muted);
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1;
}

/* Book detail hero placeholder */
.staff-body .book-detail__cover-placeholder svg,
.staff-body .book-detail__cover--placeholder svg { color: #c9ced8; }


/* ================================================================
   RESERVATIONS — pill tabs + banners, matching the rest of the UI
   ================================================================ */
.staff-body .res-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    border-bottom: none;
    margin-bottom: 0.5rem;
}

.staff-body .res-tab {
    gap: 0.45rem;
    padding: 0.5rem 1rem;
    border: 1px solid var(--s-border);
    border-bottom: 1px solid var(--s-border);
    border-radius: var(--s-radius-full);
    background: var(--s-surface);
    font-size: 0.83rem;
    font-weight: 600;
    color: var(--s-text-soft);
    transition: background var(--ease), color var(--ease), border-color var(--ease);
}
.staff-body .res-tab:hover {
    background: var(--s-border-soft);
    color: var(--s-text);
}
.staff-body .res-tab--active,
.staff-body .res-tab--active:hover {
    background: var(--s-black);
    border-color: var(--s-black);
    color: #fff;
}

.staff-body .res-tab__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    padding: 0 0.32rem;
    border-radius: var(--s-radius-full);
    background: var(--s-border-soft);
    color: var(--s-muted);
    font-size: 0.7rem;
    font-weight: 700;
}
.staff-body .res-tab__count--active {
    background: rgba(255, 255, 255, 0.22);
    color: #fff;
}

.staff-body .res-info-banner {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    border-radius: var(--s-radius-sm);
}
.staff-body .res-info-banner > svg { flex-shrink: 0; margin-top: 0.15em; }

.staff-body .res-checkout-banner__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: inherit;
}


/* ================================================================
   RESPONSIVE
   ================================================================ */
@media (max-width: 1024px) {
    /* The topbar takes over from the page header at this width, so the
       account menu moves with it. */
    .staff-body .staff-profile-menu--desktop { display: none; }
    .staff-body .staff-profile-menu--mobile  { display: inline-flex; }
    .staff-body .staff-profile-menu--mobile .staff-profile-menu__btn-name { display: none; }

    .staff-body .page-header { padding: 0.9rem var(--sp-5); }
    .staff-body .page-body   { padding: var(--sp-5) var(--sp-5) var(--sp-12); }
}

@media (max-width: 700px) {
    .staff-body .page-header {
        align-items: flex-start;
        flex-direction: column;
    }
    .staff-body .page-header__title { font-size: 1.3rem; }
    .staff-body .page-header__actions {
        width: 100%;
        flex-wrap: wrap;
    }
    .staff-body .page-body { padding: var(--sp-4) var(--sp-4) var(--sp-12); }
    .staff-body .grid-stats { grid-template-columns: repeat(2, 1fr); }
    .staff-body .stat-card {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.6rem;
    }
}


/* ================================================================
   MOTION PREFERENCES
   ================================================================ */
@media (prefers-reduced-motion: reduce) {
    .staff-body *,
    .staff-body *::before,
    .staff-body *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    .staff-body .btn:hover,
    .staff-body .stat-card:hover { transform: none; }
}


/* ================================================================
   NEEDS REVIEW  (/catalog/quality)

   A triage queue, so the visual job is ranking: severity has to be
   legible from the left edge of a row before any text is read, and
   nothing may rely on colour alone — every stripe and swatch is
   paired with a written tier label or badge text.
   ================================================================ */

.staff-body {
    --cq-critical:   var(--s-accent);
    --cq-attention:  #d97706;
    --cq-enrichment: #94a3b8;
    --cq-clean:      #16a34a;
}

/* ── Collection health panel ─────────────────────────────────── */
.staff-body .cq-health {
    display: grid;
    grid-template-columns: minmax(160px, 220px) 1fr;
    gap: var(--sp-6);
    align-items: center;
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
    box-shadow: var(--s-shadow-sm);
    padding: var(--sp-6);
    margin-bottom: var(--sp-5);
}

.staff-body .cq-health__eyebrow {
    margin: 0;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--s-muted);
}

.staff-body .cq-health__value {
    margin: 0.35rem 0 0;
    font-size: 2.6rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    color: var(--cq-critical);
}
.staff-body .cq-health__value--clear { color: var(--cq-clean); }

.staff-body .cq-health__of {
    margin-left: 0.35rem;
    font-size: 1rem;
    font-weight: 500;
    color: var(--s-muted);
}

.staff-body .cq-health__caption {
    margin: 0.5rem 0 0;
    font-size: 0.8rem;
    color: var(--s-muted);
}

/* Stacked proportion bar — clean is the remaining flex space, so the
   segments always add up to the full width without rounding drift. */
.staff-body .cq-bar {
    display: flex;
    height: 10px;
    border-radius: var(--s-radius-full);
    overflow: hidden;
    background: var(--s-border-soft);
}

.staff-body .cq-bar__seg { min-width: 2px; }
.staff-body .cq-bar__seg--critical   { background: var(--cq-critical); }
.staff-body .cq-bar__seg--attention  { background: var(--cq-attention); }
.staff-body .cq-bar__seg--enrichment { background: var(--cq-enrichment); }
.staff-body .cq-bar__seg--clean      { background: var(--cq-clean); }

.staff-body .cq-legend {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 0.6rem var(--sp-5);
    margin: var(--sp-4) 0 0;
    padding: 0;
    list-style: none;
}

.staff-body .cq-legend__item {
    display: grid;
    grid-template-columns: auto auto 1fr;
    align-items: baseline;
    gap: 0.4rem;
}

.staff-body .cq-legend__dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    align-self: center;
}
.staff-body .cq-legend__dot--critical   { background: var(--cq-critical); }
.staff-body .cq-legend__dot--attention  { background: var(--cq-attention); }
.staff-body .cq-legend__dot--enrichment { background: var(--cq-enrichment); }
.staff-body .cq-legend__dot--clean      { background: var(--cq-clean); }

.staff-body .cq-legend__label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--s-text);
}

.staff-body .cq-legend__count {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--s-text);
    font-variant-numeric: tabular-nums;
}

.staff-body .cq-legend__blurb {
    grid-column: 2 / -1;
    font-size: 0.73rem;
    line-height: 1.45;
    color: var(--s-muted);
}

/* ── Issue filter chips ──────────────────────────────────────── */
.staff-body .cq-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-bottom: var(--sp-4);
}

.staff-body .cq-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius-full);
    background: var(--s-surface);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--s-text-soft);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--ease), border-color var(--ease), color var(--ease);
}

.staff-body .cq-chip:hover {
    background: var(--s-bg);
    border-color: var(--s-muted);
    color: var(--s-text);
}

.staff-body .cq-chip:focus-visible {
    outline: 2px solid var(--s-navy);
    outline-offset: 2px;
}

/* A leading dot carries the tier — the same swatch vocabulary as the
   legend above, and it reads cleanly on a fully rounded pill where a
   left border would render as a crescent. */
.staff-body .cq-chip--critical::before,
.staff-body .cq-chip--attention::before,
.staff-body .cq-chip--enrichment::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
}
.staff-body .cq-chip--critical::before   { background: var(--cq-critical); }
.staff-body .cq-chip--attention::before  { background: var(--cq-attention); }
.staff-body .cq-chip--enrichment::before { background: var(--cq-enrichment); }

.staff-body .cq-chip--active,
.staff-body .cq-chip--active:hover {
    background: var(--s-black);
    border-color: var(--s-black);
    color: #fff;
}

.staff-body .cq-chip__count {
    font-size: 0.72rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    padding: 0.05rem 0.4rem;
    border-radius: var(--s-radius-full);
    background: var(--s-bg);
    color: var(--s-muted);
}

.staff-body .cq-chip--active .cq-chip__count {
    background: rgba(255, 255, 255, 0.18);
    color: #fff;
}

.staff-body .cq-chip--toggle {
    margin-left: auto;
    border-style: dashed;
}

/* ── Table ───────────────────────────────────────────────────── */
.staff-body .cq-table-wrap {
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
    box-shadow: var(--s-shadow-sm);
    overflow-x: auto;
}

.staff-body .cq-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.855rem;
}

.staff-body .cq-table th { text-align: left; }
.staff-body .cq-table td { vertical-align: middle; }

/* Severity stripe: the first cell carries a coloured left rule, which
   reads as a per-row rank without adding a whole column. */
.staff-body .cq-row td:first-child { border-left: 3px solid transparent; }
.staff-body .cq-row--critical   td:first-child { border-left-color: var(--cq-critical); }
.staff-body .cq-row--attention  td:first-child { border-left-color: var(--cq-attention); }
.staff-body .cq-row--enrichment td:first-child { border-left-color: var(--cq-enrichment); }

.staff-body .cq-book {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    min-width: 220px;
}

/* The image sits on top of a permanent placeholder, so onerror only has
   to remove the <img> for the fallback icon to appear. */
.staff-body .cq-book__cover-wrap {
    position: relative;
    display: block;
    width: 34px;
    height: 48px;
    flex-shrink: 0;
}

.staff-body .cq-book__cover {
    width: 34px;
    height: 48px;
    object-fit: cover;
    border-radius: 5px;
    border: 1px solid var(--s-border-soft);
    background: var(--s-bg);
}

.staff-body .cq-book__cover--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--s-muted);
}

.staff-body .cq-book__cover--img {
    position: absolute;
    inset: 0;
}

.staff-body .cq-book__text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.staff-body .cq-book__title { font-size: 0.87rem; }

.staff-body .cq-book__meta {
    font-size: 0.75rem;
    color: var(--s-muted);
}

.staff-body .cq-issues {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    align-items: center;
    min-width: 200px;
}

.staff-body .cq-issue { cursor: help; }

.staff-body .cq-issues__muted {
    font-size: 0.72rem;
    color: var(--s-muted);
    cursor: help;
}

/* ── Member reports ──────────────────────────────────────────── */

/* Count on the "Reported by members" tab. Reports are the only rows on
   this screen a reader is waiting on, so the tab carries a live number
   rather than the parenthesised total the other tabs use. */
.staff-body .cq-tab-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.15rem;
    height: 1.15rem;
    margin-left: 0.3rem;
    padding: 0 0.32rem;
    border-radius: var(--s-radius-full);
    font-size: 0.68rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: #fff;
    background: var(--cq-attention);
}

/* Marker on an Open-issues row whose title also has a member report. */
.staff-body .cq-issues__reported {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--cq-attention);
    text-decoration: none;
}
.staff-body .cq-issues__reported:hover { text-decoration: underline; }

/* The member's own words. Quoted rather than restyled — staff are
   reading a message, not a field. */
.staff-body .cq-report__comment {
    display: flex;
    align-items: flex-start;
    gap: 0.35rem;
    max-width: 46ch;
    margin: 0.4rem 0 0;
    font-size: 0.77rem;
    line-height: 1.5;
    color: var(--s-text-soft);
}
.staff-body .cq-report__comment svg {
    flex: 0 0 auto;
    margin-top: 0.15rem;
    color: var(--s-muted);
}

.staff-body .cq-report__ruling {
    max-width: 46ch;
    margin: 0.4rem 0 0;
    font-size: 0.72rem;
    line-height: 1.45;
    color: var(--s-muted);
}

.staff-body .cq-report__member {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--s-text);
}

/* Splits the state filters from the type filters in the same chip row. */
.staff-body .cq-filters__sep {
    width: 1px;
    align-self: stretch;
    margin: 0 0.3rem;
    background: var(--s-border);
}

.staff-body .cq-cell-copies { white-space: nowrap; }

.staff-body .cq-copies {
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    color: var(--s-text-soft);
}
.staff-body .cq-copies--bad { color: var(--cq-critical); font-weight: 600; }

.staff-body .cq-copies__note {
    display: block;
    font-size: 0.72rem;
    color: var(--s-muted);
}

.staff-body .cq-table__actions-head,
.staff-body .cq-cell-actions { text-align: right; }

.staff-body .cq-actions {
    display: inline-flex;
    gap: 0.4rem;
    justify-content: flex-end;
}

.staff-body .cq-action {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    white-space: nowrap;
    cursor: pointer;
}

/* A plain-POST row action (no JS, unlike cq-tag) sitting inside the
   same inline-flex actions row as the button links above it. */
.staff-body .cq-inline-form { display: inline-flex; margin: 0; }

/* ── Tag now ─────────────────────────────────────────────────────
   The button reports its own outcome in place: the row it sits on
   only leaves the queue on the next page load, so without this a
   librarian has no way to tell a tagged book from an untagged one
   while sweeping down the list. */
.staff-body .cq-tag[disabled] {
    opacity: 0.75;
    cursor: default;
}

.staff-body .cq-tag--done {
    color: #15803d;
    border-color: currentColor;
}

.staff-body .cq-tag--failed {
    color: #b91c1c;
    border-color: currentColor;
}

/* ── Biblionet coverage gauge (foyer_unverified queue only) ──── */
.staff-body .cq-gauge-card {
    display: flex;
    align-items: center;
    gap: var(--sp-6);
    flex-wrap: wrap;
    padding: var(--sp-4) var(--sp-5);
    margin: var(--sp-4) 0 var(--sp-2);
    background: var(--s-surface, #fff);
    border: 1px solid var(--s-border);
    border-radius: var(--radius, 8px);
}

.staff-body .cq-gauge {
    position: relative;
    flex: 0 0 auto;
    width: 140px;
    text-align: center;
}

.staff-body .cq-gauge__dial { display: block; overflow: visible; }

.staff-body .cq-gauge__track,
.staff-body .cq-gauge__fill {
    fill: none;
    stroke-width: 12;
    stroke-linecap: round;
}

.staff-body .cq-gauge__track { stroke: var(--s-border); }

.staff-body .cq-gauge__fill {
    stroke: var(--cq-clean);
    transition: stroke-dashoffset 0.5s ease;
}

.staff-body .cq-gauge__value {
    position: absolute;
    top: 34px;
    left: 0;
    right: 0;
    margin: 0;
    font-size: 1.7rem;
    font-weight: 700;
    line-height: 1;
    color: var(--s-text);
}

.staff-body .cq-gauge__pct-sign {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--s-muted);
    margin-left: 1px;
}

.staff-body .cq-gauge__label {
    margin: calc(var(--sp-1) * -1) 0 0;
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--s-muted);
}

.staff-body .cq-gauge__body {
    flex: 1 1 260px;
    min-width: 240px;
}

.staff-body .cq-gauge__caption {
    margin: 0 0 var(--sp-3);
    font-size: 0.85rem;
    color: var(--s-muted);
}

.staff-body .cq-gauge__stats {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-5);
    margin: 0;
    padding: 0;
    list-style: none;
}

.staff-body .cq-gauge__stats li { display: flex; flex-direction: column; }

.staff-body .cq-gauge__stat-value {
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--s-text);
}

.staff-body .cq-gauge__stat-label {
    font-size: 0.78rem;
    color: var(--s-text);
}

.staff-body .cq-gauge__stat-note {
    font-size: 0.72rem;
    color: var(--s-muted);
}

.staff-body .cq-gauge-card .cq-sweep { margin-top: var(--sp-4); }

@media (max-width: 640px) {
    .staff-body .cq-gauge-card { gap: var(--sp-4); }
    .staff-body .cq-gauge { margin: 0 auto; }
}

.staff-body .cq-sweep {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin: var(--sp-3) 0 0;
}

.staff-body .cq-sweep__note {
    font-size: 0.78rem;
    color: var(--s-muted);
}

/* ── Dismiss drawer ──────────────────────────────────────────── */
.staff-body .cq-drawer > td {
    background: var(--s-bg);
    padding: var(--sp-5) var(--sp-4);
    border-bottom: 1px solid var(--s-border);
}

.staff-body .cq-drawer__inner {
    display: grid;
    grid-template-columns: minmax(200px, 300px) 1fr;
    gap: var(--sp-6);
    align-items: start;
}

.staff-body .cq-drawer__title {
    margin: 0;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--s-text);
}

.staff-body .cq-drawer__blurb {
    margin: 0.3rem 0 0;
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--s-muted);
}

.staff-body .cq-drawer__forms {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--sp-4);
}

.staff-body .cq-drawer__label {
    display: block;
    margin-bottom: 0.3rem;
    font-size: 0.73rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--s-muted);
}

.staff-body .cq-drawer__row {
    display: flex;
    gap: 0.4rem;
}

.staff-body .cq-drawer__note {
    flex: 1;
    min-width: 0;
    font-size: 0.8rem;
}

/* ── Dismissed tab ───────────────────────────────────────────── */
.staff-body .cq-dismissed {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.staff-body .cq-dismissed__item {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Takes the slack so Restore lands in the same place on every row
   instead of wrapping under whichever note happens to be longest. */
.staff-body .cq-dismissed__meta {
    flex: 1 1 auto;
    min-width: 120px;
    font-size: 0.75rem;
    color: var(--s-muted);
}

.staff-body .cq-dismissed__form { margin: 0; }

.staff-body .cq-empty__icon { color: var(--cq-clean); }

/* ── Narrow screens ──────────────────────────────────────────── */
@media (max-width: 1024px) {
    .staff-body .cq-health {
        grid-template-columns: 1fr;
        gap: var(--sp-4);
    }
    .staff-body .cq-drawer__inner { grid-template-columns: 1fr; gap: var(--sp-4); }
}

@media (max-width: 640px) {
    .staff-body .cq-chip--toggle { margin-left: 0; }

    /* Comfortable thumb targets once the mouse is gone. */
    .staff-body .cq-chip { padding: 0.55rem 0.9rem; }
    .staff-body .cq-action { min-height: 40px; }

    .staff-body .cq-actions {
        flex-direction: column;
        align-items: stretch;
    }
    .staff-body .cq-health__value { font-size: 2.1rem; }
}


/* ================================================================
   REPORTS — the range bar, the charts, the tables, and paper
   ================================================================ */

/* .stat-card__value carries its own colour, so a tone utility on the
   same element needs to be stated again to win. */
.staff-body .stat-card__value.text-green  { color: var(--color-green); }
.staff-body .stat-card__value.text-red    { color: var(--color-red); }
.staff-body .stat-card__value.text-amber  { color: var(--color-amber); }
.staff-body .stat-card__value.text-accent { color: var(--s-accent); }

/* The hint line under a stat value. It has to live inside
   .stat-card__content: .stat-card is a flex ROW, so a bare third
   child sits beside the value and runs out of the card. */
.staff-body .stat-card__hint {
    margin-top: 0.35rem;
    font-size: 0.72rem;
    line-height: 1.35;
    color: var(--s-muted);
}

/* ── Range bar ─────────────────────────────────────────────── */
.staff-body .rpt-range {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
    padding: 0.85rem 1rem;
    margin-bottom: 0.4rem;
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
    background: var(--s-surface);
}

.staff-body .rpt-range__presets,
.staff-body .rpt-range__form,
.staff-body .rpt-range__actions,
.staff-body .rpt-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}

.staff-body .rpt-range__actions { margin-left: auto; }

.staff-body .rpt-range__field {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.75rem;
    color: var(--s-muted);
}

.staff-body .rpt-range__field input {
    border: 1.5px solid var(--s-border);
    border-radius: var(--s-radius-sm);
    padding: 0.35rem 0.55rem;
    font-size: 0.8rem;
    font-family: var(--font-body);
    color: var(--s-text);
    background: var(--s-surface);
}

.staff-body .rpt-range__showing {
    font-size: 0.78rem;
    color: var(--s-muted);
    margin: 0 0 var(--sp-5);
}

/* ── Pills, shared by the presets and the register filter ──── */
.staff-body .rpt-pill {
    display: inline-block;
    padding: 0.3rem 0.75rem;
    border-radius: var(--s-radius-full);
    border: 1px solid var(--s-border);
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--s-text-soft);
    text-decoration: none;
    white-space: nowrap;
    transition: background var(--ease), color var(--ease), border-color var(--ease);
}
.staff-body .rpt-pill:hover { border-color: var(--s-text-soft); color: var(--s-text); }
.staff-body .rpt-pill--on {
    background: var(--s-accent);
    border-color: var(--s-accent);
    color: #fff;
}

.staff-body .rpt-filter {
    margin: 0 0 var(--sp-4);
    padding-top: var(--sp-2);
}
.staff-body .rpt-filter__label {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--s-muted);
    margin-right: 0.3rem;
}

/* ── Column chart ──────────────────────────────────────────── */
.staff-body .rpt-chart {
    display: flex;
    align-items: flex-end;
    justify-content: flex-start;
    gap: 0.5rem;
    height: 150px;
    overflow-x: auto;
    padding-bottom: 0.25rem;
}
/* One data point should not become a wall of colour, so columns
   are capped and the row stays left-aligned. */
.staff-body .rpt-chart__col {
    flex: 1 0 26px;
    min-width: 26px;
    max-width: 72px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 0.25rem;
    height: 100%;
}
.staff-body .rpt-chart__bar {
    width: 100%;
    min-height: 3px;
    border-radius: 4px 4px 0 0;
    background: var(--s-accent);
    opacity: 0.85;
}
.staff-body .rpt-chart__value {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--s-text);
}
.staff-body .rpt-chart__label {
    font-size: 0.66rem;
    color: var(--s-muted);
    white-space: nowrap;
}

/* ── Report tables and small print ─────────────────────────── */
.staff-body .rpt-table { width: 100%; }
.staff-body .rpt-table--register td { vertical-align: top; }
.staff-body .rpt-nowrap { white-space: nowrap; }
.staff-body .rpt-strong { font-weight: 600; color: var(--s-text); text-decoration: none; }
.staff-body a.rpt-strong:hover { color: var(--s-accent); }
.staff-body .rpt-sub   { font-size: 0.76rem; color: var(--s-muted); font-weight: 400; }
.staff-body .rpt-rank  { color: var(--s-muted); font-size: 0.8rem; margin-right: 0.4rem; }
.staff-body .rpt-note  { font-size: 0.82rem; margin: -0.25rem 0 var(--sp-3); max-width: 62ch; }
.staff-body .rpt-cap   { font-size: 0.78rem; margin-top: var(--sp-3); }

/* ── Overview: the four ways deeper ────────────────────────── */
.staff-body .rpt-links__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.9rem;
}
.staff-body .rpt-link-card {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding: 1rem 1.1rem;
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
    background: var(--s-surface);
    text-decoration: none;
    transition: transform var(--ease), box-shadow var(--ease);
}
.staff-body .rpt-link-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--s-shadow-md);
}
.staff-body .rpt-link-card__title { font-weight: 600; color: var(--s-text); }
.staff-body .rpt-link-card__sub   { font-size: 0.78rem; color: var(--s-muted); line-height: 1.4; }

/* ── Paper ─────────────────────────────────────────────────────
   A printed report is the register plus the figures behind it —
   the chrome around them is of no use to whoever is reading it. */
@media print {
    .staff-body .sidebar,
    .staff-body .mobile-topbar,
    .staff-body .sidebar-overlay,
    .staff-body .page-header__end,
    .staff-body .rpt-range__presets,
    .staff-body .rpt-range__form,
    .staff-body .rpt-range__actions,
    .staff-body .rpt-filter,
    .staff-body .rpt-links,
    .staff-body .toast { display: none !important; }

    .staff-body .app-shell,
    .staff-body .main-content,
    .staff-body .page-body { display: block; margin: 0; padding: 0; }

    .staff-body .rpt-range {
        border: 0;
        padding: 0;
        background: none;
    }

    .staff-body .report-card,
    .staff-body .stat-card {
        border: 1px solid #ccc;
        box-shadow: none;
        break-inside: avoid;
        page-break-inside: avoid;
    }

    .staff-body .report-columns { display: block; }
    .staff-body .table-wrap { overflow: visible; }
    .staff-body .rpt-table { font-size: 0.72rem; }
    .staff-body .rpt-table thead { display: table-header-group; }
    .staff-body .rpt-table tr { break-inside: avoid; page-break-inside: avoid; }
    .staff-body .rpt-cap { display: none; }
}


/* ================================================================
   THE FOYER  (/foyer)

   A staging queue for the ~4,000 books imported out of the old
   system. Each row is a decision, so the layout is two columns
   that read as a comparison: what the old system recorded on the
   left, what the lookup found on the right. The eye should be able
   to check "is this the same book?" without reading carefully.

   Status is never carried by colour alone — every stripe and dot
   sits beside a written badge.
   ================================================================ */

.staff-body {
    --fy-matched:   #16a34a;
    --fy-review:    #d97706;
    --fy-nomatch:   #94a3b8;
    --fy-collision: var(--s-accent);
    --fy-published: #2563eb;
    --fy-skipped:   #cbd5e1;
    --fy-pending:   #a5b4fc;
}

/* ── Empty state ─────────────────────────────────────────────── */
.staff-body .fy-empty {
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
    box-shadow: var(--s-shadow-sm);
    padding: var(--sp-12) var(--sp-6);
    text-align: center;
}

.staff-body .fy-empty__icon { color: var(--fy-pending); display: block; margin-bottom: var(--sp-3); }
.staff-body .fy-empty__heading { margin: 0 0 var(--sp-2); font-size: 1.15rem; }
.staff-body .fy-empty__body {
    margin: 0 auto var(--sp-5);
    max-width: 46ch;
    color: var(--s-text-muted);
    font-size: 0.88rem;
    line-height: 1.55;
}

.staff-body .fy-upload {
    display: flex;
    gap: var(--sp-3);
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
}

.staff-body .fy-upload__file {
    padding: 0.5rem;
    border: 2px dashed var(--s-border);
    border-radius: var(--radius-sm);
    background: var(--s-bg);
    font-size: 0.84rem;
    max-width: 320px;
}

/* ── Batch header ────────────────────────────────────────────── */
.staff-body .fy-batch {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--sp-4);
    flex-wrap: wrap;
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
    padding: var(--sp-4) var(--sp-5);
    margin-bottom: var(--sp-4);
}

.staff-body .fy-batch__name { margin: 0; font-weight: 650; font-size: 0.95rem; }
.staff-body .fy-batch__sub  { margin: 0.15rem 0 0; font-size: 0.78rem; color: var(--s-text-muted); }
.staff-body .fy-batch__actions { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.staff-body .fy-batch__actions form { margin: 0; }

/* ── Lookup runner ───────────────────────────────────────────── */
.staff-body .fy-run {
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-left: 3px solid var(--fy-pending);
    border-radius: var(--s-radius);
    padding: var(--sp-5);
    margin-bottom: var(--sp-5);
}

.staff-body .fy-run__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--sp-4);
    flex-wrap: wrap;
    margin-bottom: var(--sp-4);
}

.staff-body .fy-run__heading { margin: 0 0 0.2rem; font-size: 1rem; }
.staff-body .fy-run__body {
    margin: 0;
    max-width: 62ch;
    font-size: 0.82rem;
    color: var(--s-text-muted);
    line-height: 1.5;
}

.staff-body .fy-run__bar {
    height: 8px;
    border-radius: 99px;
    background: var(--s-border);
    overflow: hidden;
}

.staff-body .fy-run__bar-fill {
    display: block;
    height: 100%;
    border-radius: 99px;
    background: var(--fy-published);
    transition: width 0.4s ease;
}

.staff-body .fy-run__status {
    margin: var(--sp-2) 0 0;
    font-size: 0.8rem;
    color: var(--s-text-muted);
    font-variant-numeric: tabular-nums;
}

/* ── Filter chips ────────────────────────────────────────────── */
.staff-body .fy-filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-bottom: var(--sp-4);
}

.staff-body .fy-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.36rem 0.7rem;
    border: 1px solid var(--s-border);
    border-radius: 99px;
    background: var(--s-surface);
    font-size: 0.79rem;
    color: var(--s-text);
    text-decoration: none;
    transition: border-color 0.15s, background 0.15s;
}

.staff-body .fy-chip:hover { border-color: var(--s-text-muted); }

.staff-body .fy-chip--active {
    background: var(--s-text);
    border-color: var(--s-text);
    color: var(--s-surface);
}

.staff-body .fy-chip__count {
    font-variant-numeric: tabular-nums;
    font-weight: 650;
    font-size: 0.74rem;
    opacity: 0.75;
}

.staff-body .fy-chip__dot { width: 7px; height: 7px; border-radius: 50%; }
.staff-body .fy-chip__dot--matched   { background: var(--fy-matched); }
.staff-body .fy-chip__dot--review    { background: var(--fy-review); }
.staff-body .fy-chip__dot--no_match  { background: var(--fy-nomatch); }
.staff-body .fy-chip__dot--collision { background: var(--fy-collision); }
.staff-body .fy-chip__dot--published { background: var(--fy-published); }
.staff-body .fy-chip__dot--skipped   { background: var(--fy-skipped); }
.staff-body .fy-chip__dot--pending   { background: var(--fy-pending); }

/* ── Search and sort ─────────────────────────────────────────── */
.staff-body .fy-search {
    display: flex;
    gap: var(--sp-2);
    margin-bottom: var(--sp-4);
    max-width: 460px;
    flex-wrap: wrap;
}

.staff-body .fy-search__input {
    flex: 1;
    padding: 0.45rem 0.7rem;
    border: 1px solid var(--s-border);
    border-radius: var(--radius-sm);
    background: var(--s-surface);
    font-size: 0.85rem;
    color: var(--s-text);
}

/* Sits on its own row under the search box on narrow screens —
   the wrapping flex parent handles that, this just stops the
   select collapsing to nothing when it does. */
.staff-body .fy-sort {
    flex: 0 0 auto;
    min-width: 170px;
    padding: 0.45rem 0.7rem;
    border: 1px solid var(--s-border);
    border-radius: var(--radius-sm);
    background: var(--s-surface);
    font-size: 0.85rem;
    color: var(--s-text);
    cursor: pointer;
}

/* ── The queue ───────────────────────────────────────────────── */
.staff-body .fy-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }

.staff-body .fy-item {
    display: grid;
    grid-template-columns: minmax(240px, 1fr) minmax(300px, 1.4fr);
    gap: var(--sp-5);
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-left: 3px solid var(--s-border);
    border-radius: var(--s-radius);
    padding: var(--sp-4) var(--sp-5);
}

.staff-body .fy-item--matched   { border-left-color: var(--fy-matched); }
.staff-body .fy-item--review    { border-left-color: var(--fy-review); }
.staff-body .fy-item--no_match  { border-left-color: var(--fy-nomatch); }
.staff-body .fy-item--collision { border-left-color: var(--fy-collision); }
.staff-body .fy-item--published { border-left-color: var(--fy-published); opacity: 0.72; }
.staff-body .fy-item--skipped   { border-left-color: var(--fy-skipped); opacity: 0.55; }
.staff-body .fy-item--pending   { border-left-color: var(--fy-pending); }

.staff-body .fy-item__eyebrow {
    margin: 0 0 0.25rem;
    font-size: 0.63rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--s-text-muted);
}

.staff-body .fy-item__title { margin: 0 0 0.2rem; font-size: 0.94rem; line-height: 1.35; }
.staff-body .fy-item__line  { margin: 0; font-size: 0.8rem; color: var(--s-text-muted); line-height: 1.45; }

.staff-body .fy-item__shelves { margin: var(--sp-2) 0 0; display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: baseline; }
.staff-body .fy-item__shelf-label {
    font-size: 0.63rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--s-text-muted);
    margin-right: 0.2rem;
}

.staff-body .fy-shelf {
    display: inline-block;
    padding: 0.1rem 0.4rem;
    border-radius: var(--radius-sm);
    background: var(--s-bg);
    border: 1px solid var(--s-border);
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.staff-body .fy-item__old-cat { margin: var(--sp-2) 0 0; font-size: 0.72rem; color: var(--s-text-muted); }
.staff-body .fy-item__old-cat-name { text-decoration: line-through; }
.staff-body .fy-item__old-cat-note { font-style: italic; opacity: 0.75; }

/* ── Match panel ─────────────────────────────────────────────── */
.staff-body .fy-item__status-row {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
    margin-bottom: var(--sp-2);
}

.staff-body .fy-badge {
    display: inline-block;
    padding: 0.16rem 0.5rem;
    border-radius: 99px;
    font-size: 0.7rem;
    font-weight: 650;
    color: #fff;
}

.staff-body .fy-badge--matched   { background: var(--fy-matched); }
.staff-body .fy-badge--review    { background: var(--fy-review); }
.staff-body .fy-badge--no_match  { background: var(--fy-nomatch); }
.staff-body .fy-badge--collision { background: var(--fy-collision); }
.staff-body .fy-badge--published { background: var(--fy-published); }
.staff-body .fy-badge--skipped   { background: #64748b; }
.staff-body .fy-badge--pending   { background: #6366f1; }

/* Fast-tracked: published by the year/publisher rule, not a click —
   outlined rather than solid so it reads as a secondary note next to
   "In the catalogue", not another status of its own. */
.staff-body .fy-badge--auto {
    background: transparent;
    border: 1px solid var(--fy-published);
    color: var(--fy-published);
}

.staff-body .fy-score, .staff-body .fy-source {
    font-size: 0.72rem;
    color: var(--s-text-muted);
    font-variant-numeric: tabular-nums;
}

.staff-body .fy-collision {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    margin: 0 0 var(--sp-2);
    padding: 0.5rem 0.65rem;
    border-radius: var(--radius-sm);
    background: color-mix(in srgb, var(--fy-collision) 9%, transparent);
    color: var(--fy-collision);
    font-size: 0.78rem;
    line-height: 1.45;
}

.staff-body .fy-match { display: flex; gap: var(--sp-3); align-items: flex-start; }

.staff-body .fy-cover {
    position: relative;
    flex: 0 0 auto;
    width: 44px;
    height: 62px;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--s-bg);
    border: 1px solid var(--s-border);
    display: grid;
    place-items: center;
}

.staff-body .fy-cover__ph  { color: var(--s-text-muted); }
.staff-body .fy-cover__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.staff-body .fy-match__body { min-width: 0; }
.staff-body .fy-match__title { margin: 0 0 0.15rem; font-size: 0.88rem; font-weight: 650; line-height: 1.35; }

.staff-body .fy-isbn {
    margin: 0.2rem 0 0;
    font-size: 0.74rem;
    font-variant-numeric: tabular-nums;
    color: var(--s-text-muted);
}

.staff-body .fy-subject { margin: 0.3rem 0 0; font-size: 0.76rem; }
.staff-body .fy-subject__code {
    display: inline-block;
    padding: 0.05rem 0.35rem;
    border-radius: 4px;
    background: var(--s-bg);
    border: 1px solid var(--s-border);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    margin-right: 0.25rem;
}

.staff-body .fy-subject--missing { color: var(--fy-review); display: flex; align-items: center; gap: 0.3rem; }

.staff-body .fy-noresult { margin: 0; font-size: 0.82rem; color: var(--s-text-muted); font-style: italic; }

.staff-body .fy-link {
    color: var(--fy-published);
    text-decoration: none;
    font-size: 0.76rem;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}
.staff-body .fy-link:hover { text-decoration: underline; }

/* ── Alternatives + editing ──────────────────────────────────── */
.staff-body .fy-alts, .staff-body .fy-edit { margin-top: var(--sp-3); }

.staff-body .fy-alts > summary,
.staff-body .fy-edit > summary {
    cursor: pointer;
    font-size: 0.76rem;
    color: var(--s-text-muted);
    display: flex;
    align-items: center;
    gap: 0.3rem;
}

.staff-body .fy-alts__list { list-style: none; margin: var(--sp-2) 0 0; padding: 0; display: grid; gap: var(--sp-2); }

.staff-body .fy-alt {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--sp-3);
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--s-border);
    border-radius: var(--radius-sm);
    background: var(--s-bg);
}

.staff-body .fy-alt form  { margin: 0; }
.staff-body .fy-alt__title { margin: 0; font-size: 0.8rem; font-weight: 600; }
.staff-body .fy-alt__line  { margin: 0.1rem 0 0; font-size: 0.72rem; color: var(--s-text-muted); }

.staff-body .fy-edit__hint { margin: var(--sp-2) 0; font-size: 0.74rem; color: var(--s-text-muted); }

.staff-body .fy-edit__form { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }

.staff-body .fy-edit__form input {
    padding: 0.35rem 0.55rem;
    border: 1px solid var(--s-border);
    border-radius: var(--radius-sm);
    background: var(--s-surface);
    font-size: 0.8rem;
    color: var(--s-text);
    min-width: 0;
}

.staff-body .fy-edit__form input[name="csv_title"]     { flex: 1 1 100%; }
.staff-body .fy-edit__form input[name="csv_author"]    { flex: 1 1 45%; }
.staff-body .fy-edit__form input[name="csv_publisher"] { flex: 1 1 30%; }
.staff-body .fy-edit__form input[name="csv_year"]      { width: 88px; }
.staff-body .fy-edit__form input[name="csv_isbn"]      { width: 150px; }

/* ── Decisions ───────────────────────────────────────────────── */
.staff-body .fy-actions {
    display: flex;
    gap: var(--sp-2);
    align-items: center;
    flex-wrap: wrap;
    margin-top: var(--sp-3);
    padding-top: var(--sp-3);
    border-top: 1px solid var(--s-border);
}

.staff-body .fy-actions form { margin: 0; }

.staff-body .fy-published {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin: var(--sp-3) 0 0;
    font-size: 0.8rem;
    color: var(--fy-published);
}

.staff-body .fy-recall { margin: var(--sp-2) 0 0; }

.staff-body .fy-none {
    padding: var(--sp-8);
    text-align: center;
    color: var(--s-text-muted);
    font-size: 0.88rem;
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
}

.staff-body .fy-newimport { margin-top: var(--sp-6); }
.staff-body .fy-newimport > summary {
    cursor: pointer;
    font-size: 0.8rem;
    color: var(--s-text-muted);
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}
.staff-body .fy-newimport .fy-upload { justify-content: flex-start; margin-top: var(--sp-3); }

/* ── Narrow screens ──────────────────────────────────────────── */
@media (max-width: 860px) {
    .staff-body .fy-item {
        grid-template-columns: 1fr;
        gap: var(--sp-4);
    }

    /* The comparison stops being side-by-side, so the found record
       needs its own visible boundary to stay legible as a separate
       claim about the same book. */
    .staff-body .fy-item__new {
        border-top: 1px dashed var(--s-border);
        padding-top: var(--sp-3);
    }
}

/* Subject picker — only appears on rows the lookup could not
   classify, so it sits inline with the publish button rather than
   taking a form row of its own. */
.staff-body .fy-publish { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.staff-body .fy-catpick { position: relative; min-width: 210px; }

.staff-body .fy-catpick__input {
    width: 100%;
    padding: 0.35rem 0.55rem;
    border: 1px solid var(--fy-review);
    border-radius: var(--radius-sm);
    background: var(--s-surface);
    font-size: 0.8rem;
    color: var(--s-text);
}

.staff-body .fy-catpick .combo-select__list {
    position: absolute;
    z-index: 30;
    left: 0;
    right: 0;
    top: calc(100% + 2px);
    max-height: 240px;
    overflow-y: auto;
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--radius-sm);
    box-shadow: var(--s-shadow-sm);
}

/* ── Shelf sections ───────────────────────────────────────────
   The way into the import: a grid of shelf runs, each showing how
   far through it is. Tiles are small and dense because there are
   43 of them and the whole map should be visible without
   scrolling — the point is to see at a glance which stretch of
   shelf to pick up next. */
.staff-body .fy-sections {
    background: var(--s-surface);
    border: 1px solid var(--s-border);
    border-radius: var(--s-radius);
    padding: var(--sp-4) var(--sp-5);
    margin-bottom: var(--sp-4);
}

.staff-body .fy-sections__head { margin-bottom: var(--sp-3); }
.staff-body .fy-sections__heading { margin: 0 0 0.15rem; font-size: 0.95rem; }
.staff-body .fy-sections__hint {
    margin: 0;
    font-size: 0.78rem;
    color: var(--s-text-muted);
    max-width: 70ch;
    line-height: 1.45;
}

.staff-body .fy-sections__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: var(--sp-2);
}

.staff-body .fy-sec {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.45rem 0.55rem 0.5rem;
    border: 1px solid var(--s-border);
    border-radius: var(--radius-sm);
    background: var(--s-bg);
    text-decoration: none;
    color: var(--s-text);
    transition: border-color 0.15s, background 0.15s;
}

.staff-body .fy-sec:hover { border-color: var(--s-text-muted); }

.staff-body .fy-sec--active {
    border-color: var(--fy-published);
    background: color-mix(in srgb, var(--fy-published) 8%, var(--s-surface));
    box-shadow: inset 0 0 0 1px var(--fy-published);
}

/* A finished section recedes — the eye should land on what is
   still outstanding, not on work already done. */
.staff-body .fy-sec--done { opacity: 0.62; }
.staff-body .fy-sec--done:hover { opacity: 1; }

.staff-body .fy-sec__label {
    font-size: 0.76rem;
    font-weight: 650;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
}

.staff-body .fy-sec__count {
    font-size: 0.68rem;
    color: var(--s-text-muted);
    font-variant-numeric: tabular-nums;
}

.staff-body .fy-sec__bar {
    display: block;
    height: 3px;
    border-radius: 99px;
    background: var(--s-border);
    overflow: hidden;
}

.staff-body .fy-sec__bar-fill {
    display: block;
    height: 100%;
    border-radius: 99px;
    background: var(--fy-published);
}

.staff-body .fy-sec--done .fy-sec__bar-fill { background: var(--fy-matched); }

/* Count of rows in a looked-up section that still want a person. */
.staff-body .fy-sec__open {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 99px;
    background: var(--fy-review);
    color: #fff;
    font-size: 0.63rem;
    font-weight: 700;
    line-height: 17px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.staff-body .fy-sec--all { justify-content: center; }
.staff-body .fy-sec--all .fy-sec__label { font-size: 0.74rem; }

/* ── Extra-copies context (collision rows) ──────────────────────
   Shown only when the collision resolved to a real book — states
   what the catalogue already holds before offering to add to it,
   so the action reads as "extend this record" rather than a bare
   button with no context. */
.staff-body .fy-copies-context {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin: 0 0 var(--sp-2);
    padding: 0.5rem 0.65rem;
    border-radius: var(--radius-sm);
    background: var(--s-bg);
    border: 1px solid var(--s-border);
}

.staff-body .fy-copies-context__line { margin: 0; font-size: 0.78rem; color: var(--s-text); }
.staff-body .fy-copies-context form { margin: 0; }

/* ── Manual Biblionet link ───────────────────────────────────── */
.staff-body .fy-attach { margin-top: var(--sp-2); }

.staff-body .fy-attach > summary {
    cursor: pointer;
    font-size: 0.76rem;
    color: var(--fy-published);
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.staff-body .fy-attach__form {
    display: flex;
    gap: var(--sp-2);
    margin-top: var(--sp-2);
    flex-wrap: wrap;
}

.staff-body .fy-attach__form input {
    flex: 1 1 260px;
    padding: 0.35rem 0.55rem;
    border: 1px solid var(--s-border);
    border-radius: var(--radius-sm);
    background: var(--s-surface);
    font-size: 0.8rem;
    color: var(--s-text);
}

/* ── CSV-vs-found field picker ───────────────────────────────── */
.staff-body .fy-pick {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
    margin-bottom: 0.4rem;
    font-size: 0.75rem;
}

.staff-body .fy-pick__label {
    font-weight: 650;
    color: var(--s-text-muted);
    min-width: 62px;
}

.staff-body .fy-pick__opt {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.15rem 0.5rem;
    border: 1px solid var(--s-border);
    border-radius: 99px;
    cursor: pointer;
    background: var(--s-surface);
}

.staff-body .fy-pick__opt:has(input:checked) {
    border-color: var(--fy-published);
    background: color-mix(in srgb, var(--fy-published) 8%, var(--s-surface));
}

.staff-body .fy-pick__opt input { margin: 0; }

/* ── Bulk select ──────────────────────────────────────────────
   The checkbox sits outside the card's own two-column grid — an
   absolutely-positioned corner element rather than a third grid
   column — so it never competes for width with the title/match
   panels, which is where the eye is actually meant to go. */
.staff-body .fy-item--selectable { position: relative; padding-left: calc(var(--sp-5) + 1.6rem); }

.staff-body .fy-select {
    position: absolute;
    top: var(--sp-4);
    left: var(--sp-4);
    cursor: pointer;
}

.staff-body .fy-select__input { width: 16px; height: 16px; cursor: pointer; margin: 0; }

.staff-body .fy-bulkbar {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    margin-bottom: var(--sp-3);
    padding: 0.55rem 0.9rem;
    border: 1px solid var(--s-border);
    border-radius: var(--radius-sm);
    background: var(--s-bg);
    font-size: 0.82rem;
}

.staff-body .fy-bulkbar__all {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    font-weight: 600;
}

.staff-body .fy-bulkbar__count {
    color: var(--s-text-muted);
    font-variant-numeric: tabular-nums;
}

.staff-body .fy-bulkbar #fy-bulk-publish { margin-left: auto; }

.staff-body .cq-sweep__progress {
    margin: var(--sp-2) 0 0;
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
    color: var(--s-muted);
}

/* ================================================================
   SPECIAL COLLECTIONS — REVIEW QUEUE
   app/views/special/review.php

   Photo-first cards. You are judging a record against a
   photograph, so the photograph gets the room and the fields sit
   beside it, not the other way round.
   ================================================================ */
.staff-body .rv-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    margin-bottom: var(--sp-6);
}
.staff-body .rv-card__head {
    display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
    padding: var(--sp-4) var(--sp-5);
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg);
}
.staff-body .rv-card__title { font-weight: 700; font-size: 1.02rem; color: var(--color-ink); }
.staff-body .rv-card__call {
    font-size: .8rem; color: var(--color-muted); font-variant-numeric: tabular-nums;
}
.staff-body .rv-card__body { display: grid; gap: var(--sp-5); padding: var(--sp-5); }
@media (min-width: 1100px) {
    .staff-body .rv-card__body { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); align-items: start; }
}

/* Big enough to actually read a title page. */
.staff-body .rv-photos { display: grid; gap: var(--sp-3); }
.staff-body .rv-photos img {
    width: 100%; height: auto; display: block;
    border: 1px solid var(--color-border); border-radius: var(--radius);
    background: var(--color-bg);
}
.staff-body .rv-photo__cap {
    display: flex; align-items: center; gap: var(--sp-2);
    font-size: .75rem; color: var(--color-muted); margin-top: .25rem;
}

.staff-body .rv-block { margin-bottom: var(--sp-5); }
.staff-body .rv-block__title {
    font-size: .74rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--color-muted); margin-bottom: var(--sp-2);
}

/* ── Evidence coding (§6.3) ──────────────────────────────────
   The one thing on this page that most protects the catalogue: a
   librarian should see at a glance which facts came off the title
   page and which the model reasoned its way to. */
.staff-body .rv-field { display: grid; gap: .15rem; padding: .4rem 0; border-bottom: 1px solid var(--color-border-subtle); }
.staff-body .rv-field:last-child { border-bottom: 0; }
.staff-body .rv-field__k { font-size: .75rem; color: var(--color-muted); }
.staff-body .rv-field__v { font-size: .92rem; color: var(--color-text); line-height: 1.45; }
.staff-body .rv-field--inferred .rv-field__v {
    color: var(--color-amber);
    text-decoration: underline dotted var(--color-amber);
    text-underline-offset: 3px;
}
.staff-body .rv-ev {
    display: inline-block; margin-left: .4rem; padding: .05rem .4rem;
    border-radius: var(--radius-full); font-size: .66rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .04em; vertical-align: middle;
}
.staff-body .rv-ev--printed  { background: var(--color-green-soft); color: var(--color-green); }
.staff-body .rv-ev--source   { background: var(--color-blue-soft);  color: var(--color-blue); }
.staff-body .rv-ev--inferred { background: var(--color-amber-soft); color: var(--color-amber); }

.staff-body .rv-warn {
    background: var(--color-amber-soft);
    border: 1px solid rgba(217,119,6,.3);
    border-radius: var(--radius);
    padding: var(--sp-3) var(--sp-4);
    font-size: .85rem; line-height: 1.5; color: var(--color-text-soft);
    margin-bottom: var(--sp-4);
}

/* The model's own caveats. Often the most valuable thing on the
   card — this is where "I could not confirm this edition" lives. */
.staff-body .rv-notes {
    background: var(--color-bg); border: 1px solid var(--color-border);
    border-radius: var(--radius); padding: var(--sp-3) var(--sp-4);
    font-size: .85rem; line-height: 1.55; color: var(--color-text-soft);
    max-height: 15rem; overflow-y: auto; white-space: pre-wrap;
}
.staff-body .rv-sources { display: grid; gap: .2rem; margin-top: var(--sp-2); }
.staff-body .rv-sources a { font-size: .78rem; word-break: break-all; }

.staff-body .rv-actions {
    display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
    padding: var(--sp-4) var(--sp-5);
    border-top: 1px solid var(--color-border); background: var(--color-bg);
}
.staff-body .rv-actions form { display: inline; }
.staff-body .rv-hint { font-size: .78rem; color: var(--color-muted); }

/* Cover thumbnail in the Special Collections item list. Fixed box, so
   a row's height never depends on whether a photograph exists. */
.staff-body .si-thumb {
    width: 34px; height: 45px; border-radius: 3px; display: block;
    object-fit: cover; background: var(--color-bg);
    border: 1px solid var(--color-border);
}
.staff-body .si-thumb--none {
    display: flex; align-items: center; justify-content: center;
    color: var(--color-muted-light);
}
