html, body {
    font-family: var(--mn-font-body);
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: var(--mn-text-link);
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem var(--mn-gold);
}

/* === form-switch — dark-mode visibility ===
   Bootstrap's default off-state (white track + near-black thumb + black-25
   border) disappears on the Midnette ink palette. Restore the off-state with a
   paper-tinted thumb and a visible border; checked state lights up in ember.
   For switches that gate a feature and need to draw attention even when off,
   add the .mn-switch-emphasis modifier on the wrapper (see /books taboo). */
.form-switch .form-check-input {
    background-color: rgba(240, 232, 216, 0.08);
    border-color: var(--mn-border-strong);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba(240, 232, 216, 0.65)'/%3e%3c/svg%3e");
}

.form-switch .form-check-input:hover:not(:disabled) {
    border-color: rgba(var(--mn-gold-rgb), 0.5);
}

.form-switch .form-check-input:checked {
    background-color: var(--mn-gold);
    border-color: var(--mn-gold);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23f0e8d8'/%3e%3c/svg%3e");
}

.form-switch .form-check-input:focus:not(:checked) {
    border-color: var(--mn-gold);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba(240, 232, 216, 0.85)'/%3e%3c/svg%3e");
}

.form-switch .form-check-input:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

/* Emphasis: ember outline at rest so the switch reads as deliberate, even off.
   Use sparingly — reserved for switches that change what content is visible
   (e.g., the taboo filter), not routine settings toggles. */
.form-switch.mn-switch-emphasis .form-check-input {
    border-color: var(--mn-gold);
    border-width: 1.5px;
    background-color: rgba(var(--mn-gold-rgb), 0.06);
}

.form-switch.mn-switch-emphasis .form-check-input:hover:not(:disabled) {
    background-color: rgba(var(--mn-gold-rgb), 0.14);
    border-color: var(--mn-gold-light);
}

.form-switch.mn-switch-emphasis .form-check-input:disabled {
    /* Stay visible — the user needs to see the affordance and learn (via the
       title tooltip) that it gates on sign-in. */
    opacity: 0.65;
    border-color: rgba(var(--mn-gold-rgb), 0.55);
}

/* Wrapper carries the title attribute and needs a help cursor so the tooltip
   intent reads on hover. */
.form-switch.mn-switch-emphasis {
    cursor: help;
}

.content {
    padding-top: 1.1rem;
}


.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #e0e0e0;
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: var(--mn-navy);
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code {
    color: #c02d76;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ===== Book Detail Page ===== */

/* Metadata table — compact rows */
.book-metadata-table th {
    font-weight: 600;
    font-size: 0.9rem;
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
}

.book-metadata-table td {
    font-size: 0.9rem;
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
}

/* Stacked sections — clear separation between content areas */
.book-detail-section {
    padding: 1.25rem 0;
    border-top: 1px solid var(--bs-border-color, #dee2e6);
}

.book-detail-section:first-of-type {
    border-top: 2px solid var(--bs-border-color, #dee2e6);
}

.book-section-heading {
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: 0.75rem;
    color: var(--bs-heading-color, inherit);
}

.book-section-heading i {
    color: var(--bs-secondary-color, #6c757d);
}

/* Book card synopsis — line-clamp for consistent card heights */
.book-card-synopsis {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* =============================================
   BOOK CARD GRID — Kobo-style compact cards
   Cover-forward, minimal text, clickable card
   ============================================= */

.book-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--mn-space-4);
}

@media (min-width: 576px) {
    .book-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: var(--mn-space-5);
    }
}

@media (min-width: 768px) {
    .book-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

@media (min-width: 992px) {
    .book-grid {
        grid-template-columns: repeat(5, minmax(0, 1fr));
        gap: var(--mn-space-6);
    }
}

.book-card {
    text-decoration: none;
    color: inherit;
    display: flex;
    flex-direction: column;
    gap: var(--mn-space-2);
    transition: transform var(--mn-transition-fast);
    min-width: 0;
}

.book-card:hover {
    color: inherit;
    text-decoration: none;
}

.book-card:hover .book-card-cover {
    box-shadow: var(--mn-shadow-lg);
    transform: translateY(-2px);
}

.book-card-cover {
    position: relative;
    border-radius: var(--mn-radius-md);
    overflow: hidden;
    box-shadow: var(--mn-shadow-sm);
    transition: box-shadow var(--mn-transition-fast),
                transform var(--mn-transition-fast);
    background: var(--mn-gray-200);
}

.book-card-cover img,
.book-card-cover .book-cover {
    width: 100%;
    display: block;
}

/* === Find Similar Button (overlay on book card cover) === */
.find-similar-btn {
    position: absolute;
    top: var(--mn-space-2);
    right: var(--mn-space-2);
    width: 32px;
    height: 32px;
    border-radius: var(--mn-radius-full);
    border: none;
    background: rgba(0, 0, 0, 0.55);
    color: var(--mn-gold);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--mn-text-sm);
    cursor: pointer;
    opacity: 0;
    transition: opacity var(--mn-transition-fast), background var(--mn-transition-fast);
    z-index: 2;
}

.book-card:hover .find-similar-btn {
    opacity: 1;
}

.find-similar-btn:hover {
    background: rgba(0, 0, 0, 0.8);
}

/* Mobile: always show (no hover) */
@media (max-width: 767.98px) {
    .find-similar-btn {
        opacity: 0.7;
        width: 28px;
        height: 28px;
        font-size: var(--mn-text-xs);
    }
}

/* === Book Hover Card — shared popover component (Desktop Only) ===
   Trigger: place inside any .book-hover-wrap container.
   Positioning variants:
     default          — centered above the trigger (browse grid)
     .book-hover-wrap--side — to the right of the trigger (admin table) */

.book-hover-wrap {
    position: relative;
}

.book-hover-card {
    position: absolute;
    z-index: var(--mn-z-popover, 1060);
    width: 340px;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(4px);
    transition: opacity 150ms ease, visibility 150ms ease, transform 150ms ease;
    transition-delay: 0ms;
    /* Default: above the trigger, centered. hover-popover.js may switch this
       to position: fixed with computed left/top to keep the card inside the
       viewport — when it does, it also sets [data-placement] so the bridge
       padding flips to the correct side. */
    bottom: 100%;
    left: 50%;
    margin-left: -170px; /* half of width */
    padding-bottom: 8px;
}

/* Bridge padding flips when JS places the card below the trigger so the
   transparent hover zone sits between trigger and visible card content. */
.book-hover-card[data-placement="below"] {
    padding-bottom: 0;
    padding-top: 8px;
    transform: translateY(-4px);
}
.book-hover-wrap:hover .book-hover-card[data-placement="below"] {
    transform: translate(0);
}

/* Side variant (admin table): to the right of trigger */
.book-hover-wrap--side .book-hover-card {
    bottom: auto;
    left: calc(100% + 12px);
    margin-left: 0;
    top: -8px;
    padding-bottom: 0;
    transform: translateX(-4px);
}

/* Show on desktop hover with delay */
@media (hover: hover) and (min-width: 768px) {
    .book-hover-wrap:hover .book-hover-card {
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
        transform: translate(0);
        transition-delay: 250ms;
    }
    .book-hover-wrap:not(:hover) .book-hover-card {
        transition-delay: 0ms;
    }
}

/* Keep visible when hovering the card itself */
.book-hover-card:hover {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translate(0);
}

/* Edge positioning: keep card within viewport on browse grid */
.book-hover-wrap:first-child > .book-hover-card,
.book-hover-wrap:nth-child(2) > .book-hover-card {
    left: 0;
    margin-left: 0;
}
.book-hover-wrap:last-child > .book-hover-card,
.book-hover-wrap:nth-last-child(2) > .book-hover-card {
    left: auto;
    right: 0;
    margin-left: 0;
}

/* Hidden on touch devices */
@media (hover: none) {
    .book-hover-card { display: none; }
}

/* Arrow — points down toward trigger (default) */
.book-hover-card__arrow {
    display: none;
}
.book-hover-wrap--side .book-hover-card__arrow {
    display: block;
    position: absolute;
    top: 16px;
    left: -7px;
    width: 12px;
    height: 12px;
    background: var(--mn-bg-surface, #fff);
    border-left: 1px solid var(--mn-border-default, #dee2e6);
    border-bottom: 1px solid var(--mn-border-default, #dee2e6);
    transform: rotate(45deg);
}

.book-hover-card__inner {
    display: flex;
    gap: 14px;
    padding: 14px;
    background: var(--mn-bg-surface, #fff);
    border: 1px solid var(--mn-border-default, #dee2e6);
    border-radius: var(--mn-radius-md, 8px);
    box-shadow: var(--mn-shadow-lg, 0 10px 25px rgba(0,0,0,.15));
    overflow: hidden;
}

.book-hover-card__cover {
    width: 56px;
    height: 84px;
    border-radius: var(--mn-radius-sm, 4px);
    overflow: hidden;
    flex-shrink: 0;
    background: var(--mn-gray-200);
}

.book-hover-card__cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.book-hover-card__no-cover {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--mn-text-tertiary);
    font-size: 1.2rem;
}

.book-hover-card__body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.book-hover-card__title {
    font-weight: 700;
    font-size: 0.9rem;
    line-height: 1.3;
    color: var(--mn-text-primary, #1a1a2e);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.book-hover-card__author {
    font-size: 0.8rem;
    color: var(--mn-text-secondary, #6c757d);
}

.book-hover-card__genres {
    display: flex;
    flex-wrap: wrap;
    gap: 3px;
}

.book-hover-card__genre {
    font-family: var(--mn-font-system);
    font-size: 0.625rem;
    padding: 0.05em 0.4em;
    background: var(--mn-bg-surface-alt);
    border: 1px solid var(--mn-border-light);
    border-radius: 999px;
    color: var(--mn-text-tertiary);
    white-space: nowrap;
}

.book-hover-card__badges {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 2px;
}

.book-hover-card__stats {
    display: flex;
    gap: var(--mn-space-2);
    font-family: var(--mn-font-system);
    font-size: 0.65rem;
    color: var(--mn-text-tertiary);
}

.book-hover-card__star {
    color: var(--mn-gold);
    font-size: 0.6rem;
}

.book-hover-card__synopsis {
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-xs);
    color: var(--mn-text-secondary);
    line-height: 1.6;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.book-hover-card__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    margin-top: 2px;
}

/* Justification (per style-guide § Badges): micro-density context. A hover-card
   overlay needs to fit ~12 labels in a small space — 0.575rem font and minimal
   padding differ from .mn-tag by enough that the canonical primitive would break
   the layout. Not a content-tag primitive; do not use outside hover-card surfaces. */
.book-hover-card__tag {
    font-family: var(--mn-font-system);
    font-size: 0.575rem;
    padding: 0.05em 0.35em;
    background: rgba(var(--mn-gold-rgb, 181, 152, 74), 0.1);
    border: 1px solid rgba(var(--mn-gold-rgb, 181, 152, 74), 0.2);
    border-radius: 999px;
    color: var(--mn-text-tertiary);
    white-space: nowrap;
}

.book-hover-card__tag--more {
    background: transparent;
    border-color: var(--mn-border-light);
    font-weight: var(--mn-font-medium);
}

.book-hover-card__dates {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 0.75rem;
    color: var(--mn-text-secondary, #6c757d);
    margin-top: 4px;
    border-top: 1px solid var(--mn-border-light, #f0f0f0);
    padding-top: 6px;
}

.book-hover-card__dates i {
    width: 14px;
    text-align: center;
    color: var(--mn-text-muted, #adb5bd);
}

/* === Cover zoom — hover-to-enlarge thumbnail (Desktop Only) ===
   Used wherever a small pending cover thumbnail needs an inspectable
   enlargement on hover (Book Edit pending AI cover, pending animation, etc.).
   Markup:
     <div class="mn-cover-zoom">
       <img class="mn-cover-zoom__trigger" ... />   small thumbnail (sized by caller)
       <div class="mn-cover-zoom__preview">         popout container
         <img ... />                                same URL, displayed at 320px wide
       </div>
     </div>
   The trigger keeps its own sizing (e.g., inline width: 80px) so row layout is
   unchanged. The popout floats to the right of the thumbnail (or left at narrower
   widths / right-aligned containers) and only appears on real hover-capable input. */

.mn-cover-zoom {
    position: relative;
    display: inline-block;
}

.mn-cover-zoom__preview {
    position: absolute;
    top: 0;
    left: 100%;
    margin-left: var(--mn-space-3);
    z-index: var(--mn-z-popover, 1060);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 150ms ease, visibility 150ms ease;
    border-radius: var(--mn-radius-lg);
    box-shadow: var(--mn-shadow-xl);
    overflow: hidden;
    background: var(--mn-bg-surface, #fff);
}

.mn-cover-zoom__preview img {
    display: block;
    width: 320px;
    aspect-ratio: 2 / 3;
    object-fit: cover;
    border-radius: var(--mn-radius-lg);
}

@media (hover: hover) and (min-width: 768px) {
    .mn-cover-zoom:hover .mn-cover-zoom__preview {
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
    }
}

/* At narrower desktop widths, flip the popout to the left so it doesn't get
   clipped by the right edge of the CoverPanel's verb-body column. */
@media (max-width: 991px) {
    .mn-cover-zoom__preview {
        left: auto;
        right: 100%;
        margin-left: 0;
        margin-right: var(--mn-space-3);
    }
}

/* Kill switch on touch devices — hover-only affordance. */
@media (hover: none) {
    .mn-cover-zoom__preview { display: none; }
}

/* === Similarity Banner === */
/* === Browse page — Backroom layout ======================================== */

/* Title strip: meta bar + big title with italic accent paragraph */
.books-title-strip {
    margin: 0 calc(var(--mn-space-4) * -1) var(--mn-space-6);
    padding: var(--mn-space-8) var(--mn-space-6) var(--mn-space-4);
    border-bottom: 1px solid var(--mn-border-default);
}

.books-meta-bar {
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--mn-gold);
    margin-bottom: var(--mn-space-3);
}

.books-title-row {
    display: flex;
    flex-direction: column;
    gap: var(--mn-space-3);
    align-items: flex-start;
    justify-content: space-between;
}

@media (min-width: 992px) {
    .books-title-row {
        flex-direction: row;
        align-items: flex-end;
        gap: var(--mn-space-10);
    }
}

.books-title {
    font-family: var(--mn-font-body);
    font-size: clamp(2rem, 5.5vw, 4rem);
    font-weight: var(--mn-font-bold);
    line-height: 0.95;
    letter-spacing: -0.03em;
    color: var(--mn-text-primary);
    margin: 0;
    flex: 1;
}

.books-title em {
    font-style: italic;
    font-weight: var(--mn-font-regular);
    color: var(--mn-gold);
}

.books-aside {
    font-family: var(--mn-font-body);
    font-style: italic;
    font-size: var(--mn-text-base);
    line-height: 1.5;
    color: #e8c8a8;
    margin: 0;
    max-width: 360px;
    padding-bottom: var(--mn-space-2);
    font-weight: var(--mn-font-light);
}

/* Grid layout: stacked on mobile, sidebar+main on desktop */
.books-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--mn-space-6);
    margin: 0 calc(var(--mn-space-4) * -1);
}

@media (min-width: 992px) {
    .books-layout {
        grid-template-columns: 320px 1fr;
        gap: 0;
    }
}

.books-sidebar {
    display: none;
}

@media (min-width: 992px) {
    .books-sidebar {
        display: block;
        background: var(--mn-bg-surface);
        border-right: 1px solid var(--mn-border-default);
        padding: var(--mn-space-6) var(--mn-space-5) var(--mn-space-10);
        align-self: start;
        position: sticky;
        top: var(--mn-header-height);
        max-height: calc(100vh - var(--mn-header-height));
        overflow-y: auto;
        scrollbar-width: thin;
        scrollbar-color: rgba(240, 232, 216, 0.18) transparent;
    }
}

/* Subtle Backroom scrollbar inside sidebar */
.books-sidebar::-webkit-scrollbar {
    width: 6px;
}

.books-sidebar::-webkit-scrollbar-track {
    background: transparent;
}

.books-sidebar::-webkit-scrollbar-thumb {
    background: rgba(240, 232, 216, 0.12);
    border-radius: 3px;
    transition: background 150ms ease;
}

.books-sidebar:hover::-webkit-scrollbar-thumb,
.books-sidebar::-webkit-scrollbar-thumb:hover {
    background: rgba(217, 137, 71, 0.35);
}

.books-results {
    min-width: 0;
    padding: 0 var(--mn-space-4);
}

@media (min-width: 992px) {
    .books-results {
        padding: var(--mn-space-6) var(--mn-space-8);
    }
}

/* Results header: kicker + big italic count + taboo + mobile Filters button */
.books-results-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--mn-space-4);
    margin-bottom: var(--mn-space-5);
}

.books-results-kicker {
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--mn-gold);
    margin-bottom: var(--mn-space-2);
}

.books-results-count {
    font-family: var(--mn-font-body);
    font-size: clamp(1.5rem, 3vw, 2rem);
    font-style: italic;
    color: var(--mn-text-primary);
    line-height: 1.05;
    font-weight: var(--mn-font-regular);
}

.books-results-count strong {
    font-family: var(--mn-font-body);
    font-style: normal;
    font-weight: var(--mn-font-bold);
    color: var(--mn-text-primary);
}

.books-results-count em {
    font-style: italic;
    font-weight: var(--mn-font-regular);
    color: var(--mn-text-secondary);
}

.books-results-sort {
    display: block;
    font-family: var(--mn-font-body);
    font-style: normal;
    font-size: var(--mn-text-sm);
    color: var(--mn-text-tertiary);
    margin-top: var(--mn-space-1);
}

/* "(N hidden by the taboo filter)" — appears under the result count when the
   user's current filters would have surfaced more books if they opted into
   taboo. Quiet by default; the action link uses gold to invite the toggle. */
.books-results-hidden-hint {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--mn-space-2);
    margin-top: var(--mn-space-2);
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-sm);
    font-style: italic;
    color: var(--mn-text-secondary);
}
.books-results-hidden-hint strong {
    font-style: normal;
    font-weight: var(--mn-font-bold);
    color: var(--mn-text-primary);
}
.books-results-hidden-action {
    appearance: none;
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-style: normal;
    color: var(--mn-gold);
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.books-results-hidden-action:hover {
    color: var(--mn-gold-light);
}
.books-results-hidden-action-muted {
    font-style: normal;
    color: var(--mn-text-tertiary);
}

/* Phase B-2b — /books → /series pivot link. Subtle gold underline; sits below
   the results count and carries overlapping filter state to the series page. */
.books-series-pivot {
    display: inline-flex;
    align-items: center;
    gap: var(--mn-space-1);
    margin-top: var(--mn-space-2);
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--mn-gold);
    text-decoration: none;
    transition: color var(--mn-transition-fast);
}
.books-series-pivot:hover {
    color: var(--mn-gold-light);
}

.books-filters-btn-mobile {
    display: inline-flex;
}

@media (min-width: 992px) {
    .books-filters-btn-mobile {
        display: none;
    }
}


.similar-banner {
    display: flex;
    align-items: center;
    padding: var(--mn-space-3) var(--mn-space-4);
    background: rgba(217, 137, 71, 0.08);
    border: 1px solid rgba(217, 137, 71, 0.3);
    border-left: 3px solid var(--mn-gold);
    border-radius: var(--mn-radius-lg);
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-sm);
    color: var(--mn-text-primary);
}

.similar-banner i.bi-stars {
    color: var(--mn-gold);
    font-size: var(--mn-text-base);
}

.similar-banner .btn-link {
    color: var(--mn-text-secondary);
    text-decoration: none;
}

.similar-banner .btn-link:hover {
    color: var(--mn-text-primary);
}

/* Topic hub suggestion on /books when filter matches exactly one eligible tag. Tinted to
   the same ember family as .similar-banner; readers should recognise it as the same
   class of inline help. Mobile-first: full width, comfortable padding. */
.topic-hub-banner {
    display: flex;
    align-items: center;
    padding: var(--mn-space-3) var(--mn-space-4);
    background: rgba(217, 137, 71, 0.08);
    border: 1px solid rgba(217, 137, 71, 0.3);
    border-left: 3px solid var(--mn-gold);
    border-radius: var(--mn-radius-lg);
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-sm);
    color: var(--mn-text-primary);
}

.topic-hub-banner i.bi-bookmark-heart-fill {
    color: var(--mn-gold);
    font-size: var(--mn-text-base);
}

.topic-hub-banner a {
    color: var(--mn-text-link);
    font-weight: var(--mn-font-semibold);
    text-decoration: none;
}

.topic-hub-banner a:hover {
    text-decoration: underline;
}

/* === Loading Skeleton Cards === */
@keyframes shimmer {
    0% { background-position: -400px 0; }
    100% { background-position: 400px 0; }
}

.shimmer {
    background: linear-gradient(
        90deg,
        var(--mn-gray-200) 25%,
        var(--mn-gray-100, #f0ede8) 37%,
        var(--mn-gray-200) 63%
    );
    background-size: 800px 100%;
    animation: shimmer 1.5s infinite ease-in-out;
}

.book-card-skeleton {
    display: flex;
    flex-direction: column;
    gap: var(--mn-space-2);
}

.skeleton-cover {
    border-radius: var(--mn-radius-md);
    aspect-ratio: 2/3;
    width: 100%;
}

.skeleton-info {
    display: flex;
    flex-direction: column;
    gap: var(--mn-space-1);
    padding: 0 var(--mn-space-1);
}

.skeleton-title {
    height: 1rem;
    border-radius: var(--mn-radius-sm);
    width: 80%;
}

.skeleton-author {
    height: 0.75rem;
    border-radius: var(--mn-radius-sm);
    width: 50%;
}

.skeleton-meta {
    height: 0.75rem;
    border-radius: var(--mn-radius-sm);
    width: 60%;
}

/* Content tag groups — category label + inline badges */
.book-tag-group {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.35rem;
}

.book-tag-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--bs-secondary-color, #6c757d);
    min-width: 5rem;
    flex-shrink: 0;
}

/* Social proof stats bar */
.book-stats-bar {
    gap: 0.5rem;
}

/* Author note callout */
.book-author-note {
    border-left: 3px solid var(--bs-primary, #0d6efd);
    padding: 0.75rem 1rem;
    background: var(--bs-tertiary-bg, #f8f9fa);
    border-radius: 0 0.375rem 0.375rem 0;
    font-size: 0.95rem;
}

/* On sm+ screens, larger section headings */
@media (min-width: 576px) {
    .book-section-heading {
        font-size: 1.25rem;
    }

    .book-detail-section {
        padding: 1.5rem 0;
    }

    .book-tag-label {
        min-width: 7rem;
    }
}


/* =============================================
   TAG PRIMITIVES — canonical tag / chip / meta-badge
   The Backroom aesthetic. Documented at /admin/style-guide § Badges & heat.

   Use:
     <ContentTagBadge Tag="@dto" />                  rich tag w/ intensity flames
     <span class="mn-tag">Fantasy</span>             plain ember tag
     <a class="mn-tag" href="...">Genre</a>          linked tag (hover lift + ember outline)
     <span class="mn-tag mn-tag--rouge">…</span>     warning / taboo variant
     <span class="mn-tag mn-tag--compact">…</span>   tight padding
     <span class="mn-meta-badge">Audiobook</span>    mono uppercase metadata label
     <span class="mn-meta-badge mn-meta-badge--ember">Complete</span>

   DO NOT redefine these in scoped .razor.css. Extend here or raise it first.
   ============================================= */

.mn-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.7rem;
    margin: 0 0.3rem 0.35rem 0;
    font-family: var(--mn-font-body);
    font-size: 0.78rem;
    font-weight: var(--mn-font-regular);
    letter-spacing: 0.01em;
    line-height: 1.2;
    color: var(--mn-text-primary);
    background: rgba(217, 137, 71, 0.04);
    border: 1px solid var(--mn-border-strong);
    border-radius: var(--mn-radius-sm);
    text-decoration: none;
    white-space: nowrap;
    cursor: default;
    transition: border-color var(--mn-transition-fast),
                color var(--mn-transition-fast),
                transform var(--mn-transition-fast);
}

/* Ember is the default look — the modifier is an explicit alias so callers
   can opt-in by name rather than relying on the absence of --rouge. */
.mn-tag--ember {
    color: var(--mn-text-primary);
    border-color: var(--mn-border-strong);
    background: rgba(217, 137, 71, 0.04);
}

/* Anchor variant — pointer + hover lift (used for genre, tag-link anchors) */
a.mn-tag {
    cursor: pointer;
}
a.mn-tag:hover {
    border-color: var(--mn-gold);
    color: var(--mn-gold-light);
    transform: translateY(-1px);
}

/* Rouge — content warnings, taboo themes */
.mn-tag--rouge {
    color: var(--mn-danger);
    border-color: var(--mn-danger);
    background: rgba(168, 58, 74, 0.06);
}
a.mn-tag--rouge:hover {
    color: var(--mn-danger-dark);
    border-color: var(--mn-danger);
}

/* Compact */
.mn-tag--compact {
    padding: 0.2rem 0.45rem;
    font-size: 0.7rem;
    gap: 0.35rem;
}

/* Selected — filled "this is on" state. Used by <TagSelector>. Layers on ember or rouge. */
.mn-tag--selected {
    background: rgba(217, 137, 71, 0.18);
    border-color: var(--mn-gold);
    color: var(--mn-gold-light);
}
.mn-tag--rouge.mn-tag--selected {
    background: rgba(168, 58, 74, 0.18);
    border-color: var(--mn-danger);
    color: var(--mn-danger-dark);
}

/* Primary — highest emphasis, solid gold fill. For primary-genre chips in pickers. */
.mn-tag--primary {
    background: var(--mn-gold);
    border-color: var(--mn-gold);
    color: var(--mn-text-inverse);
    font-weight: var(--mn-font-semibold);
}

/* Suggested — AI suggestion, dashed info-colored border, subtle info tint. */
.mn-tag--suggested {
    border-style: dashed;
    border-color: var(--mn-info);
    background: rgba(58, 123, 154, 0.05);
}
.mn-tag--suggested:hover,
button.mn-tag--suggested:hover:not(:disabled) {
    border-color: var(--mn-gold);
    background: rgba(217, 137, 71, 0.06);
}

/* Muted — inactive/archived/secondary-context tag. Used on author public profile
   listings where the genre/tag is informational chrome rather than an interactive
   filter, and on profile cards in the directory where the visual weight should
   stay quiet. Transparent fill, default border, tertiary text. */
.mn-tag--muted {
    color: var(--mn-text-tertiary);
    border-color: var(--mn-border-default);
    background: transparent;
}
a.mn-tag--muted:hover {
    color: var(--mn-text-secondary);
    border-color: var(--mn-border-strong);
}

/* Button variant — TagSelector and similar pickers use <button class="mn-tag">. */
button.mn-tag {
    font: inherit;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}
button.mn-tag:focus-visible {
    outline: 2px solid var(--mn-border-focus);
    outline-offset: 1px;
}
button.mn-tag:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    transform: none;
}

/* Wrappers used to mark tag lineage without touching the .mn-tag visuals themselves.
   Canonical pattern: put the wrapper around the tag, not a new variant on the tag.
   Global CSS cascades into components naturally (no ::deep needed). */
.mn-tag-new {
    display: inline-block;
}
.mn-tag-new .mn-tag {
    box-shadow: 0 0 0 1.5px var(--mn-gold-light);
}
.mn-tag-inherited {
    display: inline-block;
    opacity: 0.55;
}

/* Intensity flame pip — used by <ContentTagBadge> */
.mn-tag__flames {
    display: inline-flex;
    gap: 1px;
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    line-height: 1;
    letter-spacing: 0;
}
.mn-tag .flame-off { opacity: 0.22; }
.mn-tag:not(.mn-tag--rouge) .flame-on { color: var(--mn-gold); }
.mn-tag--rouge .flame-on { color: var(--mn-danger); }

.mn-tag__icon {
    font-size: 0.7rem;
    opacity: 0.7;
}

/* --- Meta badge — small-caps mono label for metadata (type, rating, format) --- */
.mn-meta-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.4rem 0.7rem;
    border: 1px solid var(--mn-border-strong);
    color: var(--mn-text-primary);
    background: transparent;
    font-family: var(--mn-font-mono);
    font-size: 0.6875rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    font-weight: var(--mn-font-semibold);
    line-height: 1;
    white-space: nowrap;
}

.mn-meta-badge--ember {
    border-color: var(--mn-gold);
    color: var(--mn-gold);
    background: rgba(217, 137, 71, 0.08);
}

.mn-meta-badge--rouge {
    border-color: var(--mn-danger);
    color: var(--mn-danger);
    background: rgba(168, 58, 74, 0.08);
}

.mn-meta-badge--success {
    border-color: rgba(74, 143, 94, 0.4);
    color: var(--mn-success-dark, #4a8f5e);
    background: rgba(74, 143, 94, 0.10);
}

.mn-meta-badge--info {
    border-color: rgba(var(--mn-info-rgb), 0.4);
    color: var(--mn-info-dark);
    background: rgba(var(--mn-info-rgb), 0.10);
}

/* Phase E §6: whole-book §4.2 review in-flight. Distinct from --info (which is
   "ready/informational") and --ember (which is warning/gold for AppealPending);
   semantically this state is "decision pending, AI is thinking", so it borrows
   the info hue but uses a dashed border to signal motion / in-flight. */
.mn-meta-badge--pending-book-review {
    border: 1px dashed rgba(var(--mn-info-rgb), 0.55);
    color: var(--mn-info-dark);
    background: rgba(var(--mn-info-rgb), 0.10);
}

.mn-meta-badge--muted {
    border-color: var(--mn-border-default);
    color: var(--mn-text-tertiary);
    background: transparent;
}

/* Sizes */
.mn-meta-badge--sm { padding: 0.22rem 0.55rem; font-size: 0.625rem; letter-spacing: 0.12em; }
.mn-meta-badge--lg { padding: 0.5rem 0.9rem; font-size: 0.8125rem; }

/* Pill — fully rounded (announcement labels: "Book of the Day", "Audio Pick", etc.) */
.mn-meta-badge--pill { border-radius: var(--mn-radius-full); }

/* ============================================================
   .mn-alert — inline alert banner (heavier than meta-badge,
   used for full-width contextual callouts on detail surfaces).
   AI-INSTRUCTION: Use --rouge variant for compliance-grade
   warnings that must be impossible to miss (e.g. surprise-won
   dispute on /admin/commerce/disputes/{id}). Non-dismissible
   by convention — the audit trail value is the always-on
   presence of the banner; do not add a close button.
   ============================================================ */
.mn-alert {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.85rem 1rem;
    border-radius: var(--mn-radius-md, 6px);
    border: 1px solid transparent;
    border-left-width: 4px;
    background: var(--mn-surface-2, rgba(255, 255, 255, 0.04));
    color: var(--mn-text-primary);
    font: inherit;
    line-height: 1.5;
}

.mn-alert--rouge {
    border-color: rgba(var(--mn-danger-rgb), 0.35);
    border-left-color: var(--mn-danger);
    background: rgba(var(--mn-danger-rgb), 0.10);
    color: var(--mn-danger-dark, var(--mn-text-primary));
}

.mn-alert--rouge strong {
    color: var(--mn-danger-dark, var(--mn-danger));
}

/* AI-INSTRUCTION: Use --ember variant for auto-suspend and trust-and-safety
   banners that require serious but non-terminal attention (e.g. book under review).
   Mirrors --rouge but uses --mn-warning (ember/gold) palette. Non-dismissible
   by convention — same audit-trail rationale as --rouge. */
.mn-alert--ember {
    border-color: rgba(var(--mn-warning-rgb), 0.35);
    border-left-color: var(--mn-warning);
    background: rgba(var(--mn-warning-rgb), 0.10);
    color: var(--mn-warning-dark, var(--mn-text-primary));
}

.mn-alert--ember strong {
    color: var(--mn-warning-dark, var(--mn-warning));
}

/* Solid — gold fill with inverse text. For featured/announcement callouts. */
.mn-meta-badge--solid {
    background: var(--mn-gold);
    border-color: var(--mn-gold);
    color: var(--mn-text-inverse);
}

/* ──────────────────────────────────────────────────────────────────────────
   Series-metadata badges (Phase A: HEA / cliffhanger / reading-arc / resolution).
   AI-INSTRUCTION: compose alongside .mn-meta-badge — the base class supplies
   the mono / uppercase / radius / border baseline; these classes paint colour
   only. Use .mn-ending-badge--* when surfacing a single book's EndingType, use
   .mn-series-resolution for the series-level marketing claim ("HEA each book"),
   use .mn-cliffhanger-warning when the book's EndsOnCliffhanger flag is true
   and you want to call it out alongside the ending badge. Use --sm modifier
   inside dense rows.
   ────────────────────────────────────────────────────────────────────────── */

.mn-ending-badge--hea {
    background: rgba(118, 195, 137, 0.16);
    border-color: rgba(118, 195, 137, 0.32);
    color: #b6e7c5;
}
.mn-ending-badge--hfn {
    background: rgba(122, 178, 211, 0.16);
    border-color: rgba(122, 178, 211, 0.32);
    color: #b9d8eb;
}
.mn-ending-badge--open {
    background: rgba(255, 244, 224, 0.06);
    border-color: rgba(255, 244, 224, 0.18);
    color: var(--mn-text-muted);
}
.mn-ending-badge--cliffhanger {
    background: rgba(208, 78, 78, 0.16);
    border-color: rgba(208, 78, 78, 0.36);
    color: #f0b3b3;
}
.mn-ending-badge--not-applicable {
    background: rgba(255, 244, 224, 0.04);
    border-color: rgba(255, 244, 224, 0.12);
    color: var(--mn-text-muted);
    font-style: italic;
}

/* Cliffhanger teaser-hook chip — distinct from the EndingType=Cliffhanger case.
   Used when a book is e.g. EndingType=HEA but EndsOnCliffhanger=true (the
   resolution is complete but a teaser hooks the next entry). Ember palette
   matches the existing audit / warning chip vocabulary. */
.mn-cliffhanger-warning {
    background: rgba(212, 158, 86, 0.18);
    border-color: rgba(212, 158, 86, 0.42);
    color: #f3d49a;
}
.mn-cliffhanger-warning::before {
    content: "⚠ ";
    margin-right: 0.18em;
}

/* Reading-arc indicator — neutral mono pill for "Sequential / Interconnected
   Standalones / Episodic / Companion". The --sequential modifier hints at
   order with a chevron. Use in series cards + reader detail eyebrows. */
.mn-arc-indicator {
    background: transparent;
    border-color: rgba(255, 244, 224, 0.22);
    color: var(--mn-text-muted);
}
.mn-arc-indicator--sequential::before {
    content: "▸ ";
    color: var(--mn-gold);
    margin-right: 0.18em;
}

/* Series-level resolution claim — slightly more emphatic than .mn-ending-badge
   because this is the headline marketing copy on series cards / detail pages.
   Uses the gold palette since it's a trust-copy surface. */
.mn-series-resolution {
    background: rgba(212, 158, 86, 0.12);
    border-color: rgba(212, 158, 86, 0.36);
    color: var(--mn-gold);
    letter-spacing: 0.16em;
}

/* ──────────────────────────────────────────────────────────────────────────
   Series detail — banner hero and accent-coloured CTA. Phase B-1.
   AI-INSTRUCTION: --mn-series-accent is scoped to descendants of an
   opt-in element (e.g. .mn-series-detail page root). NEVER apply on <body>
   and NEVER rely on it being defined; always supply a fallback in var().
   ────────────────────────────────────────────────────────────────────────── */

.mn-series-banner {
    width: 100%;
    aspect-ratio: 3 / 1;
    background-color: var(--mn-bg-surface-alt);
    background-size: cover;
    background-position: center;
    border-radius: var(--mn-radius-lg);
    position: relative;
    overflow: hidden;
}
.mn-series-banner::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 55%, rgba(0, 0, 0, 0.45) 100%);
    pointer-events: none;
}
@media (max-width: 575.98px) {
    .mn-series-banner {
        aspect-ratio: 2 / 1;
        border-radius: var(--mn-radius-md);
    }
}

.mn-series-accent-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem 1rem;
    border: 1px solid transparent;
    border-radius: var(--mn-radius-md);
    background: var(--mn-series-accent, var(--mn-gold));
    color: var(--mn-text-primary);
    font-weight: 600;
    text-decoration: none;
    transition: background var(--mn-transition-fast);
}
.mn-series-accent-cta:hover {
    /* Fallback for Safari < 16.2 — gold-light on hover when color-mix unsupported. */
    background: var(--mn-gold-light);
    background: color-mix(in srgb, var(--mn-series-accent, var(--mn-gold)) 88%, black 12%);
    color: var(--mn-text-primary);
    text-decoration: none;
}
.mn-series-accent-cta:focus-visible {
    outline: 2px solid var(--mn-border-focus);
    outline-offset: 2px;
}

/* ──────────────────────────────────────────────────────────────────────────
   Backroom typographic primitives — page chrome (breadcrumb, hero title,
   by-line, section eyebrow + headline). These are the PRIMARY design;
   every reader page uses them. Do NOT redefine in .razor.css per-page.
   AI-INSTRUCTION: compose these directly on the markup. Page-scoped CSS
   is for genuine one-off layout (page-hero grid, sticky bars), never for
   re-skinning these primitives.
   ────────────────────────────────────────────────────────────────────────── */

/* ===== Breadcrumb ===== */
.mn-breadcrumb {
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--mn-text-tertiary);
    margin-bottom: var(--mn-space-4);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
}
.mn-breadcrumb a {
    color: var(--mn-text-secondary);
    text-decoration: none;
    transition: color var(--mn-transition-fast);
}
.mn-breadcrumb a:hover {
    color: var(--mn-gold-light);
}
.mn-breadcrumb__sep {
    margin: 0 0.55em;
    color: var(--mn-text-tertiary);
    opacity: 0.55;
}
.mn-breadcrumb__current {
    color: var(--mn-gold);
}

/* ===== Hero title ===== */
.mn-hero-title {
    font-family: var(--mn-font-body);
    font-size: clamp(2rem, 4.5vw, 3.5rem);
    line-height: 0.98;
    font-weight: var(--mn-font-regular);
    letter-spacing: -0.02em;
    color: var(--mn-text-primary);
    margin: 0 0 var(--mn-space-2) 0;
}
.mn-hero-title em {
    font-style: italic;
    color: var(--mn-gold);
    font-weight: var(--mn-font-regular);
}

/* Heavier variant — used by full-bleed page heroes like BookDetail. */
.mn-hero-title--display {
    font-size: clamp(2.25rem, 5.5vw, 4.75rem);
    line-height: 0.95;
    letter-spacing: -0.03em;
}

/* ===== Hero by-line / attribution ===== */
.mn-hero-byline {
    font-family: var(--mn-font-body);
    font-size: 1.0625rem;
    font-style: italic;
    color: var(--mn-text-secondary);
    margin-bottom: var(--mn-space-3);
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.35em;
}
.mn-hero-byline a {
    color: var(--mn-gold-light);
    text-decoration: underline;
    text-underline-offset: 4px;
    text-decoration-color: var(--mn-border-strong);
    text-decoration-thickness: 1px;
    transition: color var(--mn-transition-fast), text-decoration-color var(--mn-transition-fast);
}
.mn-hero-byline a:hover {
    color: var(--mn-gold);
    text-decoration-color: var(--mn-gold);
}
.mn-hero-byline__sep {
    color: var(--mn-text-tertiary);
    opacity: 0.6;
    font-style: normal;
}

/* ===== Section header — eyebrow + headline ===== */
.mn-section-eyebrow {
    font-family: var(--mn-font-mono);
    font-size: 0.6875rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--mn-gold);
    font-weight: var(--mn-font-semibold);
    margin-bottom: var(--mn-space-2);
}
.mn-section-eyebrow--rouge { color: var(--mn-danger); }
.mn-section-eyebrow--compact {
    font-size: 0.625rem;
    letter-spacing: 0.16em;
}

.mn-section-headline {
    font-family: var(--mn-font-body);
    font-style: italic;
    font-size: clamp(1.375rem, 2.8vw, 1.875rem);
    font-weight: var(--mn-font-regular);
    color: var(--mn-text-primary);
    line-height: 1.15;
    letter-spacing: -0.01em;
    margin: 0 0 var(--mn-space-4);
}
.mn-section-headline em {
    color: var(--mn-gold);
    font-style: italic;
}

/* Larger variant for top-of-page headlines on full-bleed sections. */
.mn-section-headline--display {
    font-size: clamp(1.625rem, 3.2vw, 2.375rem);
    margin-bottom: var(--mn-space-5);
}

.mn-section-header-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--mn-space-4);
    flex-wrap: wrap;
    margin-bottom: var(--mn-space-3);
}
.mn-section-header-row .mn-section-headline { margin-bottom: 0; }

/* ===== Retail variants — brand-showcase surfaces (Home, /series browse, etc.)
   Bold-sans headlines, italic regular gold em-emphasis. Louder than the
   editorial italic-serif used on reader product pages. Compose with the
   base class: <h2 class="mn-section-headline mn-section-headline--retail">. */

.mn-section-eyebrow--retail {
    font-weight: var(--mn-font-regular);
    font-size: 0.625rem;
    letter-spacing: 0.2em;
    line-height: 1;
}

.mn-section-headline--retail {
    font-style: normal;
    font-weight: var(--mn-font-bold);
    font-size: clamp(1.75rem, 4vw, 2.625rem);
    line-height: 1.05;
    letter-spacing: -0.02em;
}
.mn-section-headline--retail em {
    font-weight: var(--mn-font-regular);
    font-style: italic;
    color: var(--mn-gold);
}

.mn-hero-title--retail {
    font-weight: var(--mn-font-bold);
    font-size: clamp(2rem, 5.5vw, 3.75rem);
    line-height: 1.02;
    letter-spacing: -0.02em;
}
.mn-hero-title--retail em {
    font-weight: var(--mn-font-regular);
    font-style: italic;
    color: var(--mn-gold);
}

.mn-hero-byline--retail {
    font-size: clamp(1.125rem, 2.2vw, 1.375rem);
}
.mn-hero-byline--retail a {
    text-decoration: none;
    font-weight: var(--mn-font-regular);
}
.mn-hero-byline--retail a:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ──────────────────────────────────────────────────────────────────────────
   Author avatar primitive — circular author identity avatar used by the
   BookDetail "About the author" panel and the AuthorPublic landing hero.
   Default 96px; --xl modifier 150px for landing-page heroes.
   Gradient fallback (rouge → gold, italic serif initial) is the universal
   no-avatar treatment. Promoted from page-scoped BookDetail.razor.css so
   both pages render the same author chrome.
   AI-INSTRUCTION: do NOT redefine .mn-author-avatar per-page. Extend here.
   ────────────────────────────────────────────────────────────────────────── */
.mn-author-avatar {
    width: 96px;
    height: 96px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}

.mn-author-avatar--gradient {
    background: linear-gradient(135deg, var(--mn-danger) 0%, var(--mn-gold) 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--mn-font-body);
    font-style: italic;
    font-size: 2.75rem;
    color: var(--mn-bg-body);
    font-weight: var(--mn-font-regular);
}

/* Landing-page hero size — used by AuthorPublic where the avatar overlaps
   the banner and carries the page's identity weight. */
.mn-author-avatar--xl {
    width: 150px;
    height: 150px;
}

.mn-author-avatar--xl.mn-author-avatar--gradient {
    font-size: 4.25rem;
}

/* ──────────────────────────────────────────────────────────────────────────
   Topic/aisle chip primitive — used on AisleLanding (child + related strips)
   and on the /aisles hub index. Promoted from page-scoped TopicLanding.razor.css
   so both pages render identical pills without divergent styling.
   AI-INSTRUCTION: do NOT redefine .topic-chip per-page. Extend here.
   ────────────────────────────────────────────────────────────────────────── */
.topic-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mn-space-2);
}

.topic-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--mn-space-2);
    padding: var(--mn-space-2) var(--mn-space-3);
    background-color: var(--mn-bg-surface);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-full);
    color: var(--mn-text-primary);
    text-decoration: none;
    font-size: var(--mn-text-sm);
    line-height: 1.2;
    transition: background-color var(--mn-transition-fast),
                border-color var(--mn-transition-fast);
    /* Tap target ≥ 44px tall — mobile a11y rule */
    min-height: 44px;
    /* Guards 30+ char topic names from breaking grids on mobile */
    max-width: 100%;
    min-width: 0;
}

.topic-chip:hover,
.topic-chip:focus-visible {
    background-color: var(--mn-bg-surface-alt);
    border-color: var(--mn-gold);
    color: var(--mn-text-primary);
    text-decoration: none;
}

.topic-chip__name {
    font-weight: var(--mn-font-medium);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.topic-chip__count {
    font-size: var(--mn-text-xs);
    color: var(--mn-text-tertiary);
    padding: 0 var(--mn-space-2);
    border-left: 1px solid var(--mn-border-default);
    flex-shrink: 0;
}

/* ──────────────────────────────────────────────────────────────────────────
   Browse-page chrome primitives. Promotes the previously page-scoped
   .books-* / .series-* duplicates into a single canonical set so /books,
   /series, and any future listing-style page render with the same rhythm.
   /books still uses .books-* aliases for now; migration is a follow-up.
   AI-INSTRUCTION: compose these directly. Do NOT redefine in .razor.css
   per-page — that's exactly the duplication CLAUDE.md forbids.
   ────────────────────────────────────────────────────────────────────────── */

/* Full-bleed title strip — mono kicker + retail title + italic aside.
   The negative margins are the "escape the page container" trick so the strip
   spans edge-to-edge inside .container or .mn-page-layout. */
.mn-page-strip {
    margin: 0 calc(var(--mn-space-4) * -1) var(--mn-space-6);
    padding: var(--mn-space-8) var(--mn-space-6) var(--mn-space-4);
    border-bottom: 1px solid var(--mn-border-default);
}

.mn-page-strip__meta {
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--mn-gold);
    margin-bottom: var(--mn-space-3);
}

.mn-page-strip__row {
    display: flex;
    flex-direction: column;
    gap: var(--mn-space-3);
    align-items: flex-start;
    justify-content: space-between;
}

@media (min-width: 992px) {
    .mn-page-strip__row {
        flex-direction: row;
        align-items: flex-end;
        gap: var(--mn-space-6);
    }
}

.mn-page-strip__aside {
    font-family: var(--mn-font-body);
    font-style: italic;
    font-size: var(--mn-text-base);
    line-height: 1.5;
    color: #e8c8a8;
    margin: 0;
    max-width: 360px;
    padding-bottom: var(--mn-space-2);
    font-weight: var(--mn-font-light);
}

/* Two-column browse shell — sticky 320px sidebar (desktop) + flexible main. */
.mn-page-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--mn-space-6);
    margin: 0 calc(var(--mn-space-4) * -1);
}

@media (min-width: 992px) {
    .mn-page-layout {
        grid-template-columns: 320px 1fr;
        gap: 0;
    }
}

.mn-page-sidebar {
    /* Mobile default: hidden — page-level state controls a slide-in drawer. */
    display: none;
}

@media (min-width: 992px) {
    .mn-page-sidebar {
        display: block;
        background: var(--mn-bg-surface);
        border-right: 1px solid var(--mn-border-default);
        padding: var(--mn-space-6) var(--mn-space-5) var(--mn-space-10);
        align-self: start;
        position: sticky;
        top: var(--mn-space-5);
        max-height: calc(100vh - var(--mn-space-5));
        overflow-y: auto;
    }
}

.mn-page-sidebar::-webkit-scrollbar { width: 6px; }
.mn-page-sidebar::-webkit-scrollbar-track { background: transparent; }
.mn-page-sidebar::-webkit-scrollbar-thumb {
    background: rgba(240, 232, 216, 0.12);
    border-radius: 3px;
    transition: background 150ms ease;
}
.mn-page-sidebar:hover::-webkit-scrollbar-thumb,
.mn-page-sidebar::-webkit-scrollbar-thumb:hover {
    background: rgba(217, 137, 71, 0.35);
}

.mn-page-results {
    min-width: 0;
    padding: 0 var(--mn-space-4);
}

@media (min-width: 992px) {
    .mn-page-results {
        padding: var(--mn-space-6) var(--mn-space-8);
    }
}

/* Results header — mono gold kicker over big italic count. */
.mn-results-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--mn-space-4);
    margin-bottom: var(--mn-space-5);
}

.mn-results-kicker {
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--mn-gold);
    margin-bottom: var(--mn-space-2);
}

.mn-results-count {
    font-family: var(--mn-font-body);
    font-size: clamp(1.5rem, 3vw, 2rem);
    font-style: italic;
    color: var(--mn-text-primary);
    line-height: 1.05;
    font-weight: var(--mn-font-regular);
}
.mn-results-count strong {
    font-family: var(--mn-font-body);
    font-style: normal;
    font-weight: var(--mn-font-bold);
    color: var(--mn-text-primary);
}
.mn-results-count em {
    font-style: italic;
    font-weight: var(--mn-font-regular);
    color: var(--mn-text-secondary);
}

.mn-results-count__sort {
    display: block;
    font-family: var(--mn-font-body);
    font-style: normal;
    font-size: var(--mn-text-sm);
    color: var(--mn-text-tertiary);
    margin-top: var(--mn-space-1);
}

/* Empty state — dashed-bordered card with icon + italic prompt. */
.mn-page-empty {
    text-align: center;
    padding: var(--mn-space-8) var(--mn-space-4);
    color: var(--mn-text-tertiary);
    background: var(--mn-bg-surface);
    border: 1px dashed var(--mn-border-default);
    border-radius: var(--mn-radius-lg);
}
.mn-page-empty > i {
    font-size: 2.5rem;
    color: var(--mn-text-tertiary);
    margin-bottom: var(--mn-space-2);
    display: block;
}
.mn-page-empty > p {
    font-family: var(--mn-font-body);
    font-style: italic;
    margin: 0;
}

/* ──────────────────────────────────────────────────────────────────────────
   Series card — primitive for /series browse, AuthorPublic series rails,
   and any future series listing surface. Composes alongside --mn-series-accent
   when an inline-style supplies it on the card itself; otherwise falls back
   to --mn-gold. Phase B-2.
   AI-INSTRUCTION: place the inline accent style on .mn-series-card so the
   accent-bar + accent-cta below pick it up via custom-property inheritance.
   ────────────────────────────────────────────────────────────────────────── */

.mn-series-card {
    display: flex;
    flex-direction: column;
    background: var(--mn-bg-surface);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-lg);
    overflow: hidden;
    transition: transform var(--mn-transition-fast), border-color var(--mn-transition-fast), box-shadow var(--mn-transition-fast);
    text-decoration: none;
    color: inherit;
    position: relative;
}
.mn-series-card:hover {
    transform: translateY(-2px);
    border-color: var(--mn-border-strong);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.32);
    color: inherit;
    text-decoration: none;
}

/* 4px vertical strip carrying the series's accent (gold fallback). Sits flush
   left edge inside the card. */
.mn-series-accent-bar {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 4px;
    background: var(--mn-series-accent, var(--mn-gold));
    pointer-events: none;
}

/* Progress bar primitive — "X of Y owned" inside .mn-series-card. Renders on
   bg-surface-alt rail with --mn-gold fill (NOT --mn-series-accent — the
   ownership progress narrative is platform-level, not author-styled). */
.mn-series-card__progress {
    height: 4px;
    background: var(--mn-bg-surface-alt);
    border-radius: var(--mn-radius-full);
    overflow: hidden;
}
.mn-series-card__progress > .mn-series-card__progress-fill {
    height: 100%;
    background: var(--mn-gold);
    border-radius: var(--mn-radius-full);
    transition: width var(--mn-transition-base);
}

/* ──────────────────────────────────────────────────────────────────────────
   .mn-step-indicator — small circular step number for multi-step wizards.
   AI-INSTRUCTION: used on flows like PayoutSetup where the page shows N steps
   in a row, each with a circular badge containing either a number ("1", "2",
   "3") or a status icon (check / exclamation). Compose with --complete,
   --warning, or --active to colour the state. Mirrors the StyleGuide gold
   accent palette — do not introduce per-page replicas.
   ────────────────────────────────────────────────────────────────────────── */
.mn-step-indicator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--mn-radius-full);
    border: 1px solid var(--mn-border-default);
    background: transparent;
    color: var(--mn-text-tertiary);
    font-family: var(--mn-font-mono);
    font-size: 0.8125rem;
    font-weight: var(--mn-font-semibold);
    line-height: 1;
}

.mn-step-indicator--active {
    border-color: var(--mn-gold);
    color: var(--mn-gold);
    background: rgba(217, 137, 71, 0.08);
}

.mn-step-indicator--complete {
    border-color: var(--mn-success);
    color: var(--mn-success);
    background: rgba(74, 143, 94, 0.10);
}

.mn-step-indicator--warning {
    border-color: var(--mn-gold);
    color: var(--mn-gold);
    background: rgba(217, 137, 71, 0.10);
}

/* ──────────────────────────────────────────────────────────────────────────
   .mn-step-card — clickable card wrapping a step indicator. Strips native
   <button> chrome (background, border, padding) so it renders identically
   to a normal .card, but stays keyboard-accessible and tappable.
   AI-INSTRUCTION: use on wizards where each step should be independently
   reachable (e.g. PayoutSetup). Pair with .mn-step-indicator inside.
   ────────────────────────────────────────────────────────────────────────── */
.mn-step-card {
    appearance: none;
    -webkit-appearance: none;
    padding: 0;
    text-align: inherit;
    cursor: pointer;
    color: inherit;
    transition: border-color 0.15s ease, transform 0.05s ease;
}

.mn-step-card:hover {
    border-color: var(--mn-gold);
}

.mn-step-card:focus-visible {
    outline: 2px solid var(--mn-gold);
    outline-offset: 2px;
}

.mn-step-card:active {
    transform: translateY(1px);
}

/* ──────────────────────────────────────────────────────────────────────────
   .mn-rail-card — selectable card for picking a payout rail in the author
   onboarding wizard. Strips <button> chrome, dark-palette compatible, and
   surfaces a clear selected state without depending on Bootstrap radio
   semantics (which don't card-wrap cleanly on mobile).
   AI-INSTRUCTION: use anywhere the user picks one option from a small set
   of independent cards. Pair with .mn-meta-badge for state ribbons.
   ────────────────────────────────────────────────────────────────────────── */
.mn-rail-card {
    appearance: none;
    -webkit-appearance: none;
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.875rem 1rem;
    background: var(--mn-surface);
    color: inherit;
    border: 1px solid var(--mn-border);
    border-radius: var(--mn-radius-md, 8px);
    cursor: pointer;
    min-height: 44px;
    transition: border-color 0.15s ease, background 0.15s ease, transform 0.05s ease;
}

.mn-rail-card:hover:not(:disabled) {
    border-color: var(--mn-gold);
}

.mn-rail-card:focus-visible {
    outline: 2px solid var(--mn-gold);
    outline-offset: 2px;
}

.mn-rail-card:active:not(:disabled) {
    transform: translateY(1px);
}

.mn-rail-card--selected {
    border-color: var(--mn-gold);
    background: rgba(217, 137, 71, 0.08);
}

.mn-rail-card--disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

/* ──────────────────────────────────────────────────────────────────────────
   .mn-code-block — dark-palette code/JSON dump primitive.
   AI-INSTRUCTION: use for displaying pre-formatted text on dark surfaces —
   tool-call result blobs, JSON dumps, raw debug output. Replaces Bootstrap's
   `<pre class="bg-light">` which renders a stark light surface against
   Midnette's dark palette. Default max-height + scroll is appropriate for
   trace surfaces; override with utility classes when full-height is needed.
   ────────────────────────────────────────────────────────────────────────── */
.mn-code-block {
    font-family: var(--mn-font-mono);
    font-size: 0.75rem;
    line-height: 1.45;
    color: var(--mn-text-secondary);
    background: var(--mn-bg-inset);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-sm);
    padding: 0.5rem 0.6rem;
    margin: 0;
    max-height: 200px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
}

/* ──────────────────────────────────────────────────────────────────────────
   .mn-confidence-bar — single-bar confidence visualization with a threshold
   marker. Used in the admin moderation evidence panel to render a chapter
   policy evaluation's model-stated confidence next to the policy-specific
   reject threshold (so admins can eyeball "barely passed" vs. "decisively
   over the line"). Width on .mn-confidence-bar__fill is the model's confidence
   in percent; left position on .mn-confidence-bar__threshold is the policy's
   reject threshold in percent.
   ────────────────────────────────────────────────────────────────────────── */

.mn-confidence-bar {
    position: relative;
    width: 100%;
    height: 0.625rem;
    background: var(--mn-bg-elevated);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-sm);
    overflow: hidden;
}

.mn-confidence-bar__fill {
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    background: var(--mn-danger);
    transition: width var(--mn-transition-base);
}

.mn-confidence-bar__fill--pass { background: var(--mn-success); }

.mn-confidence-bar__threshold {
    position: absolute;
    inset-block: -2px;
    width: 2px;
    background: var(--mn-text-primary);
    opacity: 0.7;
}

.mn-confidence-bar__labels {
    display: flex;
    justify-content: space-between;
    margin-top: var(--mn-space-1);
    font-family: var(--mn-font-mono);
    font-size: 0.6875rem;
    color: var(--mn-text-tertiary);
    letter-spacing: 0.06em;
}

/* ──────────────────────────────────────────────────────────────────────────
   .mn-timeline — vertical event list with a left rule (admin override audit
   history, future activity feeds). Each .mn-timeline__entry is a stacked row
   with optional metadata; the rule lives on the parent so the entries stay
   aligned without each one re-declaring the border.
   ────────────────────────────────────────────────────────────────────────── */

.mn-timeline {
    border-left: 3px solid var(--mn-border-strong);
    padding-left: var(--mn-space-3);
}

.mn-timeline__entry {
    margin-bottom: var(--mn-space-3);
    font-size: 0.875rem;
}

.mn-timeline__entry:last-child { margin-bottom: 0; }

.mn-timeline__header {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--mn-space-2);
}

.mn-timeline__meta {
    color: var(--mn-text-tertiary);
    font-size: 0.8125rem;
}

.mn-timeline__body {
    margin-top: var(--mn-space-1);
    color: var(--mn-text-tertiary);
}

/* Anchor variant — meta-badge can render as <a> when the chip is a deep-link
   (e.g. policy code chips in the chapter rejection alert linking to the matching
   subsection on /resources). Strip the default anchor underline and add a subtle
   hover so the chip still reads as a label, just clickable. */
a.mn-meta-badge {
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

a.mn-meta-badge:hover,
a.mn-meta-badge:focus-visible {
    text-decoration: none;
    filter: brightness(1.15);
}

/* Pulse dot — used inside meta-badge to signal "fresh / new" (e.g. New chapter) */
.mn-meta-badge .mn-pulse-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    margin-right: 0.4rem;
    animation: mn-meta-badge-pulse 1.5s ease-in-out infinite;
}

@keyframes mn-meta-badge-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.4; }
}


/* =============================================
   HEAT LEVEL BADGE — book-level heat with ♨ flames
   The Backroom aesthetic. Documented at /admin/style-guide § Badges & heat.
   Used by <HeatLevelBadge>; do NOT redefine in scoped CSS.
   ============================================= */

.mn-heat {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--mn-font-mono);
    font-weight: var(--mn-font-semibold);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    white-space: nowrap;
    cursor: help;
    line-height: 1;
    vertical-align: baseline;
    border: 1px solid currentColor;
    background: rgba(217, 137, 71, 0.06);
}

.mn-heat__flames {
    letter-spacing: 0;
    font-family: var(--mn-font-mono);
}

/* Sizes */
.mn-heat--sm { padding: 0.22rem 0.55rem; font-size: 0.625rem; }
.mn-heat--md { padding: 0.3rem 0.65rem; font-size: 0.6875rem; }
.mn-heat--lg { padding: 0.5rem 0.9rem; font-size: 0.8125rem; gap: 0.55rem; }

.mn-heat--compact { gap: 0; padding-left: 0.5rem; padding-right: 0.5rem; }

/* Tones */
.mn-heat--ember {
    color: var(--mn-gold);
    background: rgba(217, 137, 71, 0.06);
}

.mn-heat--gold {
    color: var(--mn-gold);
    background: rgba(217, 137, 71, 0.10);
}

.mn-heat--rouge {
    color: var(--mn-danger);
    background: rgba(168, 58, 74, 0.08);
}


/* =============================================
   PRICE DISPLAY — USD + ◈ tokens, italic-ember "Free"
   Used by <PriceDisplay>; do NOT redefine in scoped CSS.
   ============================================= */

.mn-price {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    font-family: var(--mn-font-body);
}

.mn-price--compact { gap: 0.25rem; }

/* USD — serif paper, hero-weight at lg */
.mn-price__usd {
    font-family: var(--mn-font-body);
    color: var(--mn-text-primary);
    font-weight: var(--mn-font-semibold);
    letter-spacing: -0.01em;
    line-height: 1;
}

.mn-price__usd--sm { font-size: 1rem; }
.mn-price__usd--md { font-size: 1.375rem; }
.mn-price__usd--lg { font-size: 2.75rem; letter-spacing: -0.02em; }

/* Separator — muted mono */
.mn-price__sep {
    font-family: var(--mn-font-mono);
    font-size: 0.6875rem;
    color: var(--mn-text-tertiary);
    letter-spacing: 0.1em;
    text-transform: lowercase;
}

/* Token — ember mono with ◈ glyph */
.mn-price__token {
    font-family: var(--mn-font-mono);
    color: var(--mn-gold);
    letter-spacing: 0.08em;
    line-height: 1;
    white-space: nowrap;
}

.mn-price__token--sm { font-size: 0.6875rem; }
.mn-price__token--md { font-size: 0.75rem; }
.mn-price__token--lg { font-size: 1rem; }

/* Free — italic serif ember */
.mn-price__free {
    font-family: var(--mn-font-body);
    font-style: italic;
    color: var(--mn-gold);
    line-height: 1;
}

.mn-price__free--sm { font-size: 1rem; }
.mn-price__free--md { font-size: 1.25rem; }
.mn-price__free--lg { font-size: 2.75rem; }


/* =============================================
   STAR RATING — display + input. Used by <StarRating>.
   Do NOT redefine in scoped CSS. Reader uses its own <ReaderStarRating>.
   ============================================= */

.star-rating {
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
    line-height: 1;
}

/* Sizes */
.star-rating-sm .star-rating-star { font-size: 0.875rem; }
.star-rating-md .star-rating-star { font-size: 1.125rem; }
.star-rating-lg .star-rating-star { font-size: 1.5rem; }

.star-rating-star {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.15s ease, color 0.15s ease;
}

.star-rating-star.star-filled {
    color: var(--mn-gold);
}

.star-rating-star.star-empty-state,
.star-rating-star.star-partial-state {
    color: var(--mn-text-tertiary);
}

/* Partial star overlay */
.star-rating-star .star-partial {
    position: absolute;
    top: 0;
    left: 0;
    color: var(--mn-gold);
}

.star-rating-star .star-empty {
    color: var(--mn-text-tertiary);
}

/* Input mode — interactive */
.star-rating-input .star-rating-star {
    cursor: pointer;
}

.star-rating-input .star-rating-star:hover {
    transform: scale(1.15);
}

.star-rating-input .star-rating-star:focus-visible {
    outline: 2px solid var(--mn-gold);
    outline-offset: 2px;
    border-radius: 2px;
}

.star-rating-readonly .star-rating-star {
    cursor: default;
}


/* =============================================
   DASHBOARD & CHART COMPONENTS
   Reusable classes for KPI cards, chart containers,
   and metric tables. Uses --mn-chart-* tokens from
   design-tokens.css. Used by /admin/ai-usage and
   any future dashboard/analytics pages.
   ============================================= */

/* Spotlight Card — generic editorial "spotlight" card used by /aisle/{slug} for
   the rotating featured-book block. Two-column layout supplied by the consuming
   page; this primitive only carries the tone, radius, border, and shadow so the
   card feels consistent if reused elsewhere. */
.mn-spotlight-card {
    background: var(--mn-bg-surface);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-xl);
    padding: var(--mn-space-6);
    box-shadow: var(--mn-shadow-md);
    transition: border-color var(--mn-transition-fast);
}

.mn-spotlight-card:hover {
    border-color: var(--mn-border-strong);
}

@media (min-width: 768px) {
    .mn-spotlight-card {
        padding: var(--mn-space-8);
    }
}

/* KPI Card — use on .card elements for dashboard stat cards */
.mn-kpi-card {
    border: none;
    border-radius: var(--mn-radius-lg);
    box-shadow: var(--mn-shadow-sm);
    background: var(--mn-bg-surface);
    transition: transform var(--mn-transition-fast), box-shadow var(--mn-transition-fast);
}

.mn-kpi-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--mn-shadow-md);
}

.mn-kpi-value {
    font-size: var(--mn-text-3xl);
    font-weight: var(--mn-font-bold);
    color: var(--mn-text-primary);
    line-height: var(--mn-leading-tight);
}

.mn-kpi-label {
    font-size: var(--mn-text-xs);
    color: var(--mn-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: var(--mn-font-semibold);
    margin-bottom: var(--mn-space-1);
}

/* KPI change indicator — add .positive, .negative, or .neutral */
.mn-kpi-change {
    font-size: var(--mn-text-sm);
    font-weight: var(--mn-font-semibold);
    display: inline-flex;
    align-items: center;
    gap: 0.2em;
}

.mn-kpi-change.positive { color: var(--mn-success); }
.mn-kpi-change.negative { color: var(--mn-danger); }
.mn-kpi-change.neutral  { color: var(--mn-text-tertiary); }

/* Chart Container — wraps <canvas> elements */
.mn-chart-container {
    position: relative;
    background: var(--mn-bg-surface);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-lg);
    box-shadow: var(--mn-shadow-sm);
}

.mn-chart-container canvas {
    max-width: 100%;
}

/* Dashboard metric table — use alongside .table */
.mn-metric-table th {
    font-size: var(--mn-text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--mn-text-secondary);
    font-weight: var(--mn-font-semibold);
    border-bottom: 2px solid var(--mn-border-strong);
}

.mn-metric-table .metric-value {
    font-family: var(--mn-font-mono);
    font-size: var(--mn-text-sm);
}


/* =============================================
   BROWSE PAGE — Sort Pills, Filter Chips,
   Active Filter Bar
   ============================================= */

/* --- Sort & Filter Pills ---
   Justification (per style-guide § Badges): browse navigation controls, not content tags.
   44px min-height for touch; full-radius pill; interactive (changes the page on click).
   A .mn-tag is a label describing content; these are buttons that filter the view.
   Different semantic role — keep separate. */
.sort-pill-bar {
    display: flex;
    gap: var(--mn-space-2);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: var(--mn-space-2) 0;
    margin-bottom: var(--mn-space-3);
}

.sort-pill-bar::-webkit-scrollbar {
    display: none;
}

.sort-pill {
    scroll-snap-align: start;
    flex-shrink: 0;
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-sm);
    font-weight: var(--mn-font-medium);
    line-height: 1;
    padding: 0.5rem 1rem;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    border-radius: var(--mn-radius-full);
    border: 1px solid var(--mn-border-strong);
    background: transparent;
    color: var(--mn-text-primary);
    opacity: 0.75;
    cursor: pointer;
    transition: background-color var(--mn-transition-fast),
                color var(--mn-transition-fast),
                border-color var(--mn-transition-fast),
                opacity var(--mn-transition-fast);
    white-space: nowrap;
}

.sort-pill:hover {
    background: rgba(217, 137, 71, 0.06);
    color: var(--mn-gold);
    border-color: var(--mn-gold);
    opacity: 1;
}

.sort-pill--active {
    background: var(--mn-gold);
    color: var(--mn-text-inverse);
    border-color: var(--mn-gold);
    opacity: 1;
    font-weight: var(--mn-font-semibold);
}

.sort-pill--active:hover {
    background: var(--mn-gold-dark);
    color: var(--mn-text-inverse);
    border-color: var(--mn-gold-dark);
}

/* --- Quick Filter Chip Bar --- */
.quick-chip-bar {
    display: flex;
    gap: var(--mn-space-2);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: var(--mn-space-1) 0;
    margin-bottom: var(--mn-space-3);
}

.quick-chip-bar::-webkit-scrollbar {
    display: none;
}

.filter-chip {
    scroll-snap-align: start;
    flex-shrink: 0;
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-sm);
    font-weight: var(--mn-font-medium);
    line-height: 1;
    padding: 0.375rem 0.875rem;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    border-radius: var(--mn-radius-full);
    border: 1px solid var(--mn-border-strong);
    background: transparent;
    color: var(--mn-text-primary);
    opacity: 0.75;
    cursor: pointer;
    transition: background-color var(--mn-transition-fast),
                color var(--mn-transition-fast),
                border-color var(--mn-transition-fast),
                opacity var(--mn-transition-fast);
    white-space: nowrap;
}

.filter-chip:hover {
    border-color: var(--mn-gold);
    color: var(--mn-gold);
    opacity: 1;
}

.filter-chip--active {
    background: rgba(217, 137, 71, 0.12);
    color: var(--mn-gold);
    border-color: var(--mn-gold);
    font-weight: var(--mn-font-semibold);
    opacity: 1;
}

.filter-chip--active:hover {
    background: rgba(217, 137, 71, 0.20);
}

/* --- Active Filter Bar --- */
.active-filter-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--mn-space-2);
    padding: var(--mn-space-2) 0;
    margin-bottom: var(--mn-space-3);
    border-bottom: 1px solid var(--mn-border-light);
}

.active-filter-count {
    font-family: var(--mn-font-system);
    font-size: var(--mn-text-sm);
    color: var(--mn-text-secondary);
    font-weight: var(--mn-font-medium);
    white-space: nowrap;
}

.active-filter-pills {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mn-space-1);
    flex: 1;
    min-width: 0;
}

/* Justification (per style-guide § Badges): search-domain active-filter control.
   Denser than .mn-tag (needs to fit many applied filters in a bar), has a close
   button, max-width + ellipsis. Not a content-label primitive — it's the UI
   surface for "here's what you've filtered by, click X to remove". */
.filter-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-xs);
    font-weight: var(--mn-font-medium);
    color: var(--mn-text-primary);
    background: rgba(217, 137, 71, 0.08);
    border: 1px solid rgba(217, 137, 71, 0.25);
    border-radius: var(--mn-radius-full);
    padding: 0.2rem 0.5rem;
    max-width: 200px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.filter-pill-icon {
    font-size: 0.65rem;
    opacity: 0.7;
    flex-shrink: 0;
}

.filter-pill--tag {
    background: rgba(var(--mn-gold-rgb, 181, 152, 74), 0.1);
    border-color: rgba(var(--mn-gold-rgb, 181, 152, 74), 0.3);
    color: var(--mn-text-primary);
}

.filter-pill--exclude {
    background: rgba(var(--mn-danger-rgb, 220, 53, 69), 0.08);
    border-color: rgba(var(--mn-danger-rgb, 220, 53, 69), 0.25);
    color: var(--mn-danger);
    text-decoration: line-through;
    text-decoration-color: rgba(var(--mn-danger-rgb, 220, 53, 69), 0.4);
}

.filter-pill-dismiss {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    margin-left: 0.15rem;
    color: inherit;
    opacity: 0.5;
    font-size: 0.85rem;
    line-height: 1;
    flex-shrink: 0;
    transition: opacity var(--mn-transition-fast);
}

.filter-pill-dismiss:hover {
    opacity: 1;
}

.active-filter-clear {
    font-family: var(--mn-font-system);
    font-size: var(--mn-text-sm);
    color: var(--mn-text-secondary);
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--mn-space-1) var(--mn-space-2);
    border-radius: var(--mn-radius-sm);
    transition: color var(--mn-transition-fast),
                background-color var(--mn-transition-fast);
    white-space: nowrap;
    flex-shrink: 0;
    margin-left: auto;
}

.active-filter-clear:hover {
    color: var(--mn-danger);
    background: var(--mn-danger-light);
}

/* ==================== Commerce ==================== */

/* Nav commerce elements */
.nav-token-balance {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--mn-gold-light);
    text-decoration: none;
    font-weight: 600;
    font-family: var(--mn-font-mono);
    font-size: 0.8rem;
    padding: 0.25rem 0.6rem;
    border: 1px solid rgba(217, 137, 71, 0.25);
    border-radius: 9999px;
    transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}
.nav-token-balance:hover {
    background-color: rgba(217, 137, 71, 0.08);
    border-color: var(--mn-gold);
    color: var(--mn-gold);
}

.nav-cart-badge {
    position: relative;
    display: inline-flex;
    align-items: center;
    color: var(--mn-text-primary);
    opacity: 0.85;
    text-decoration: none;
    font-size: 1.1rem;
    padding: 0.25rem 0.5rem;
    border-radius: 0.375rem;
    transition: background-color 0.15s, color 0.15s, opacity 0.15s;
}
.nav-cart-badge:hover {
    background-color: rgba(217, 137, 71, 0.08);
    color: var(--mn-gold);
    opacity: 1;
    color: #fff;
}
.nav-cart-badge .badge {
    position: absolute;
    top: -2px;
    right: -4px;
    font-size: 0.65rem;
    padding: 0.15em 0.4em;
}

/* Token package cards */
.token-package-card {
    border: 2px solid transparent;
    transition: border-color 0.2s, transform 0.2s;
    cursor: pointer;
}
.token-package-card:hover {
    border-color: var(--mn-gold);
    transform: translateY(-2px);
}
.token-package-card.selected {
    border-color: var(--mn-gold);
    box-shadow: 0 0 0 3px rgba(var(--mn-gold-rgb, 212, 175, 55), 0.25);
}
.token-package-card .per-token {
    font-size: 0.75rem;
    color: var(--mn-text-secondary);
}

/* Price display */
.price-free {
    color: var(--mn-success);
    font-weight: 600;
}
.price-tokens {
    color: var(--mn-gold);
}

/* Cart */
.cart-item {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--mn-border-color, #dee2e6);
}
.cart-item:last-child {
    border-bottom: none;
}
.cart-item-details {
    flex: 1;
    min-width: 0;
}
.cart-item-title {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cart-item-meta {
    font-size: 0.8rem;
    color: var(--mn-text-secondary);
}
.cart-item-card {
    transition: opacity 0.25s ease, transform 0.25s ease, max-height 0.3s ease;
    max-height: 300px;
}
.cart-item-removing {
    opacity: 0;
    transform: translateX(-30px);
    max-height: 0;
    margin-bottom: 0 !important;
    overflow: hidden;
}
.cart-summary {
    position: sticky;
    top: 5rem;
}
.cart-mobile-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--mn-bg-surface);
    border-top: 1px solid var(--mn-border-default);
    padding: 0.75rem 1rem;
    z-index: 1030;
    box-shadow: 0 -2px 8px rgba(0,0,0,0.1);
}

/* Cart — page header */
.cart-page-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 1rem;
    padding-bottom: 1.25rem;
    margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--mn-border-default);
    flex-wrap: wrap;
}
.cart-headline {
    font-family: var(--mn-font-body);
    font-weight: 700;
    color: var(--mn-text-primary);
    font-size: clamp(2rem, 5vw, 3rem);
    line-height: 1.05;
    margin: 0.25rem 0 0;
    letter-spacing: -0.02em;
}
.cart-headline em {
    color: var(--mn-gold);
    font-style: italic;
}
.cart-eyebrow {
    font-family: var(--mn-font-body);
    font-size: 0.7rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--mn-text-secondary);
    font-weight: 600;
}
.cart-eyebrow-success { color: var(--mn-success); }
.cart-eyebrow-accent { color: var(--mn-gold); }

/* Cart — section heading */
.cart-section-heading {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding-bottom: 0.5rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid var(--mn-border-default);
}
.cart-section-title {
    font-family: var(--mn-font-body);
    font-style: italic;
    font-size: 1.25rem;
    color: var(--mn-text-primary);
    margin: 0;
}

/* Cart — token nudge banner */
.cart-token-banner {
    border: 1px solid var(--mn-border-default);
    padding: 0.875rem 1.125rem;
    margin-bottom: 1rem;
    border-radius: 0.375rem;
}
.cart-token-banner-ok {
    border-color: var(--mn-success);
    background: rgba(45, 122, 79, 0.06);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}
.cart-token-banner-short {
    border-color: var(--mn-gold);
    background: rgba(181, 152, 74, 0.06);
}
.cart-token-banner-body {
    font-size: 1rem;
    color: var(--mn-text-primary);
    margin-top: 0.25rem;
}
.cart-token-savings {
    color: var(--mn-success);
    font-weight: 600;
    margin-left: 0.25rem;
    font-size: 0.9rem;
}
.cart-token-banner-meta {
    font-size: 0.8rem;
    color: var(--mn-text-secondary);
    margin-top: 0.35rem;
}
.cart-token-banner-link {
    color: var(--mn-gold);
    font-weight: 600;
    text-decoration: none;
}
.cart-token-banner-link:hover { text-decoration: underline; }

/* Cart — heat indicator */
.cart-heat {
    display: inline-flex;
    align-items: center;
    gap: 0.1rem;
    color: var(--mn-danger);
    font-size: 0.7rem;
    line-height: 1;
}
.cart-heat-dot {
    opacity: 0.85;
}
.cart-heat-dot.bi-circle {
    opacity: 0.25;
}

/* Cart — chapter credit note */
.cart-credit-note {
    margin-top: 0.5rem;
    padding: 0.4rem 0.6rem;
    font-size: 0.8rem;
    color: var(--mn-success);
    background: rgba(45, 122, 79, 0.08);
    border-left: 3px solid var(--mn-success);
    line-height: 1.4;
}

/* Cart — pay-with toggle */
.cart-pay-toggle {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
}
.cart-pay-btn {
    flex: 1;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--mn-border-default);
    background: transparent;
    color: var(--mn-text-primary);
    position: relative;
    font-size: 0.85rem;
}
.cart-pay-btn:hover { background: var(--mn-bg-surface-alt); }
.cart-pay-btn-active-card {
    background: var(--mn-navy);
    color: #fff;
    border-color: var(--mn-navy);
}
.cart-pay-btn-active-card:hover { background: var(--mn-navy-light); color: #fff; }
.cart-pay-btn-active-tokens {
    background: var(--mn-gold);
    color: var(--mn-text-inverse);
    border-color: var(--mn-gold);
}
.cart-pay-btn-active-tokens:hover { background: var(--mn-gold-light); color: var(--mn-text-inverse); }
.cart-pay-price {
    font-weight: 700;
    font-size: 0.95rem;
}
.cart-pay-warn {
    color: var(--mn-danger);
    font-size: 0.75rem;
    margin-left: 0.25rem;
}
.cart-pay-savings {
    position: absolute;
    top: -0.65rem;
    right: 0.4rem;
    background: var(--mn-success);
    color: #fff;
    padding: 0.05rem 0.4rem;
    font-size: 0.65rem;
    letter-spacing: 0.08em;
    font-weight: 700;
    border-radius: 0.2rem;
    line-height: 1.4;
}

/* Cart — keep-browsing link */
.cart-keep-browsing {
    color: var(--mn-gold);
    font-weight: 600;
    text-decoration: none;
    font-size: 0.9rem;
}
.cart-keep-browsing:hover { text-decoration: underline; }

/* Cart — reassurance strip */
.cart-reassure {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    padding: 1.25rem;
    background: var(--mn-bg-surface-alt);
    border: 1px solid var(--mn-border-default);
    border-radius: 0.375rem;
    margin: 1rem 0;
}
.cart-reassure-item i {
    color: var(--mn-gold);
    font-size: 1.25rem;
    display: block;
    margin-bottom: 0.35rem;
}
.cart-reassure-title {
    font-family: var(--mn-font-body);
    font-style: italic;
    font-weight: 600;
    color: var(--mn-text-primary);
    font-size: 0.95rem;
}
.cart-reassure-sub {
    font-size: 0.78rem;
    color: var(--mn-text-secondary);
    margin-top: 0.2rem;
    line-height: 1.4;
}
.cart-reassure-sub a { color: inherit; text-decoration: underline; }
@media (max-width: 767.98px) {
    .cart-reassure { grid-template-columns: repeat(2, 1fr); }
}

/* Cart — saved row */
.cart-saved-row {
    display: grid;
    grid-template-columns: 48px 1fr auto;
    gap: 0.875rem;
    align-items: center;
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--mn-border-default);
}
.cart-saved-row img {
    width: 48px;
    height: 72px;
    object-fit: cover;
    border-radius: 3px;
}
.cart-saved-cover-fallback {
    width: 48px;
    height: 72px;
    background: var(--mn-bg-surface-alt);
    border-radius: 3px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.cart-saved-title a {
    font-weight: 600;
    color: var(--mn-text-primary);
    text-decoration: none;
}
.cart-saved-title a:hover { color: var(--mn-gold-light); }
.cart-saved-actions {
    display: flex;
    gap: 0.25rem;
}

/* Cart — summary */
.cart-summary-title {
    font-family: var(--mn-font-body);
    font-style: italic;
    color: var(--mn-text-primary);
    font-size: 1.4rem;
    margin: 0.25rem 0 1rem;
    line-height: 1.1;
}
.cart-summary-lines {
    max-height: 260px;
    overflow-y: auto;
}
.cart-summary-line {
    display: flex;
    justify-content: space-between;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
    gap: 0.75rem;
}
.cart-summary-line-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cart-summary-line-type {
    color: var(--mn-text-secondary);
    font-size: 0.75rem;
    margin-left: 0.25rem;
}
.cart-summary-line-price {
    white-space: nowrap;
    font-weight: 600;
}
.cart-summary-line-tokens {
    color: var(--mn-gold);
}
.cart-summary-subtotal {
    display: flex;
    justify-content: space-between;
    font-size: 0.9rem;
    margin-bottom: 0.35rem;
}
.cart-summary-total {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding-top: 0.75rem;
    margin-top: 0.5rem;
    border-top: 1px solid var(--mn-border-default);
}
.cart-summary-total-label {
    font-family: var(--mn-font-body);
    font-style: italic;
    font-size: 1.15rem;
    color: var(--mn-text-primary);
}
.cart-summary-total-amounts {
    text-align: right;
}
.cart-summary-total-usd {
    font-weight: 700;
    font-size: 1.5rem;
    color: var(--mn-gold);
    line-height: 1;
}
.cart-summary-total-tokens {
    font-size: 0.85rem;
    color: var(--mn-gold);
    margin-top: 0.25rem;
    font-weight: 600;
}
.cart-summary-balance {
    display: flex;
    justify-content: space-between;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mn-text-secondary);
    margin-top: 0.75rem;
    padding-top: 0.5rem;
    border-top: 1px dashed var(--mn-border-default);
    font-weight: 600;
}
.cart-summary-balance-short {
    color: var(--mn-danger);
}
.cart-trust-mini {
    display: flex;
    justify-content: center;
    gap: 1rem;
    font-size: 0.7rem;
    color: var(--mn-text-secondary);
}
.cart-trust-mini a {
    color: inherit;
    text-decoration: none;
}
.cart-trust-mini a:hover { text-decoration: underline; }

/* Cart — what happens next */
.cart-what-next {
    margin-top: 1rem;
    padding: 1rem 1.25rem;
    background: var(--mn-bg-surface);
    border: 1px solid var(--mn-border-default);
    border-radius: 0.375rem;
}
.cart-what-next ol {
    margin: 0.5rem 0 0;
    padding-left: 1.25rem;
    font-size: 0.85rem;
    line-height: 1.6;
    color: var(--mn-text-primary);
}
.cart-what-next li { margin-bottom: 0.35rem; }

/* Cart — empty state */
.cart-empty-state {
    text-align: center;
    padding: 3.5rem 1rem;
    border: 1px solid var(--mn-border-default);
    background: var(--mn-bg-surface);
    border-radius: 0.5rem;
}
.cart-empty-mark {
    font-family: var(--mn-font-body);
    font-style: italic;
    font-size: 6rem;
    color: var(--mn-gold);
    line-height: 0.9;
    letter-spacing: -0.05em;
}
.cart-empty-headline {
    font-family: var(--mn-font-body);
    font-size: 2rem;
    color: var(--mn-text-primary);
    margin: 0.75rem 0 0.5rem;
    font-weight: 700;
}
.cart-empty-headline em { color: var(--mn-gold); font-style: italic; }
.cart-empty-sub {
    color: var(--mn-text-secondary);
    max-width: 50ch;
    margin: 0 auto 1.5rem;
}
.cart-empty-actions {
    display: flex;
    gap: 0.75rem;
    justify-content: center;
    flex-wrap: wrap;
}

/* Checkout */
.checkout-order-summary {
    background: var(--mn-bg-surface);
    border-radius: 0.5rem;
    padding: 1.25rem;
}

/* Upgrade card */
.upgrade-savings {
    font-size: 0.85rem;
    color: var(--mn-success);
    font-weight: 600;
}

/* Entitlement states */
.content-locked {
    position: relative;
    opacity: 0.7;
}
.content-locked::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(transparent 60%, var(--mn-bg-body) 100%);
    pointer-events: none;
}

/* Order receipt */
.receipt-header {
    border-bottom: 2px solid var(--mn-navy);
    padding-bottom: 0.75rem;
    margin-bottom: 1rem;
}
.receipt-line-refunded {
    text-decoration: line-through;
    opacity: 0.6;
}

/* Earnings dashboard */
.earnings-kpi {
    text-align: center;
    padding: 1rem;
}
.earnings-kpi .kpi-value {
    font-size: 1.5rem;
    font-weight: 700;
}
.earnings-kpi .kpi-label {
    font-size: 0.8rem;
    color: var(--mn-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* Commerce empty states */
.commerce-empty-state {
    text-align: center;
    padding: 3rem 1.5rem;
    color: var(--mn-text-secondary);
}
.commerce-empty-state i {
    font-size: 3rem;
    display: block;
    margin-bottom: 1rem;
    opacity: 0.5;
}
.commerce-empty-state p {
    margin-bottom: 1.5rem;
    max-width: 30ch;
    margin-inline: auto;
}

/* Commerce loading shimmer */
.commerce-skeleton {
    background: linear-gradient(90deg, var(--mn-bg-surface) 25%, rgba(255,255,255,0.1) 50%, var(--mn-bg-surface) 75%);
    background-size: 200% 100%;
    animation: commerce-shimmer 1.5s infinite;
    border-radius: 0.375rem;
}
@keyframes commerce-shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* Commerce toast notifications */
.commerce-toast-container {
    position: fixed;
    bottom: 1.5rem;
    right: 1.5rem;
    z-index: 1090;
    display: flex;
    flex-direction: column-reverse;
    gap: 0.5rem;
    max-width: 22rem;
}
.commerce-toast {
    background: var(--mn-bg-surface);
    border: 1px solid;
    border-left-width: 4px;
    border-radius: 0.5rem;
    padding: 0.75rem 1rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    animation: toast-slide-in 0.3s ease-out;
}
@keyframes toast-slide-in {
    from { opacity: 0; transform: translateY(1rem); }
    to { opacity: 1; transform: translateY(0); }
}

/* Mobile responsive */
@media (max-width: 575.98px) {
    .cart-item {
        flex-direction: column;
        align-items: flex-start;
    }
    .cart-summary {
        position: static;
    }
    .earnings-kpi .kpi-value {
        font-size: 1.25rem;
    }
    .commerce-toast-container {
        left: 0.75rem;
        right: 0.75rem;
        bottom: 1rem;
        max-width: none;
    }
}

/* Token Store page — "Backroom" glow-up.
   Ink + ember editorial reskin. Everything here is genuine page-specific
   layout; shared editorial primitives (.mn-section-eyebrow,
   .mn-section-headline) come from the Backroom typographic block above and
   are composed directly on the markup — do NOT redefine them here. */

/* ---- Hero: page ink + centered ember glow (replaces the old navy band) ---- */
.store-hero {
    position: relative;
    overflow: hidden;
    text-align: center;
    padding: 4.5rem 1rem 3.5rem;
    margin-top: -1rem;
    background: var(--mn-bg-body);
    border-bottom: 1px solid var(--mn-border-default);
}
.store-hero::before {
    content: "";
    position: absolute;
    top: -180px;
    left: 50%;
    transform: translateX(-50%);
    width: min(1000px, 135%);
    height: 600px;
    background: radial-gradient(ellipse at 50% 38%,
        rgba(var(--mn-gold-rgb), 0.20),
        rgba(var(--mn-danger-rgb), 0.10) 44%,
        transparent 70%);
    filter: blur(26px);
    pointer-events: none;
}
.store-hero > .container {
    position: relative;
    max-width: 720px;
}
.store-hero-eyebrow {
    margin-bottom: 1.25rem;
}
.store-hero-title {
    font-family: var(--mn-font-body);
    font-size: clamp(2.25rem, 6vw, 3.75rem);
    font-weight: var(--mn-font-regular);
    line-height: 1.04;
    letter-spacing: -0.02em;
    color: var(--mn-text-primary);
    text-wrap: balance;
    margin: 0 0 1.25rem;
}
.store-hero-title em {
    font-style: italic;
    color: var(--mn-gold);
}
.store-hero-subtitle {
    font-family: var(--mn-font-body);
    font-size: 1.15rem;
    line-height: 1.55;
    color: var(--mn-text-secondary);
    max-width: 540px;
    margin: 0 auto 1.75rem;
}
.store-hero-subtitle strong {
    color: var(--mn-text-primary);
    font-style: italic;
    font-weight: var(--mn-font-regular);
}
.store-balance-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    background: var(--mn-bg-surface);
    border: 1px solid var(--mn-border-strong);
    border-radius: var(--mn-radius-full);
    padding: 0.7rem 1.4rem;
    font-family: var(--mn-font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--mn-text-secondary);
}
.store-balance-pill i {
    color: var(--mn-gold);
}
.store-balance-pill strong {
    color: var(--mn-gold-light);
    font-weight: var(--mn-font-semibold);
}

/* ---- Centered section header (kicker + headline) ---- */
.store-section-head {
    text-align: center;
    margin-bottom: 2.25rem;
}
.store-section-head .mn-section-headline {
    margin: 0;
}

/* ---- Package cards ---- */
.store-package {
    position: relative;
    background: var(--mn-bg-surface);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-sm);
    padding: 1.9rem 1.1rem 1.25rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    height: 100%;
    cursor: pointer;
    transition: border-color var(--mn-transition-fast),
                transform var(--mn-transition-fast),
                box-shadow var(--mn-transition-fast);
}
.store-package:hover {
    border-color: var(--mn-border-strong);
    transform: translateY(-3px);
}
.store-package-featured {
    border-color: rgba(var(--mn-gold-rgb), 0.5);
    background:
        radial-gradient(ellipse at 50% 0%, rgba(var(--mn-gold-rgb), 0.12), transparent 60%),
        var(--mn-bg-surface);
    box-shadow: 0 0 0 1px rgba(var(--mn-gold-rgb), 0.25),
                0 24px 60px rgba(0, 0, 0, 0.5);
}
.store-package-selected,
.store-package-selected:hover {
    border-color: var(--mn-gold);
    box-shadow: 0 0 0 1px var(--mn-gold);
}

/* Package badge — pill straddling the top edge */
.store-package-badge {
    position: absolute;
    top: -0.6rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    white-space: nowrap;
    font-family: var(--mn-font-mono);
    font-size: 0.5625rem;
    font-weight: var(--mn-font-semibold);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    padding: 0.32rem 0.85rem;
    border-radius: var(--mn-radius-sm);
}
.store-badge-popular {
    background: var(--mn-gold);
    color: var(--mn-bg-body);
}
.store-badge-best {
    background: var(--mn-bg-surface-alt);
    color: var(--mn-gold-light);
    border: 1px solid var(--mn-gold-dark);
}
.store-badge-default {
    background: var(--mn-bg-surface-alt);
    color: var(--mn-text-secondary);
    border: 1px solid var(--mn-border-strong);
}

/* Package token count */
.store-token-count {
    font-family: var(--mn-font-body);
    font-size: 3.25rem;
    font-weight: var(--mn-font-bold);
    color: var(--mn-gold);
    line-height: 0.9;
}
.store-package-featured .store-token-count,
.store-package-selected .store-token-count {
    color: var(--mn-gold-light);
}
.store-token-label {
    display: block;
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    color: var(--mn-text-secondary);
    margin-top: 0.5rem;
    margin-bottom: 1rem;
}
.store-package-rule {
    width: 34px;
    height: 1px;
    background: var(--mn-border-strong);
    margin: 0 auto 1rem;
}
.store-package-price {
    font-family: var(--mn-font-body);
    font-size: 1.85rem;
    color: var(--mn-text-primary);
    line-height: 1;
    margin-bottom: 0.4rem;
}
.store-package-per-token {
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.04em;
    color: var(--mn-text-secondary);
    margin-bottom: 0.5rem;
}
.store-package-savings {
    font-family: var(--mn-font-mono);
    font-size: 0.625rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mn-success-dark);
    margin-bottom: 0.9rem;
}

/* Package CTA buttons */
.store-package-btn {
    width: 100%;
    margin-top: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.7rem 0.5rem;
    font-family: var(--mn-font-mono);
    font-size: 0.6875rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--mn-text-primary);
    background: transparent;
    border: 1px solid var(--mn-border-strong);
    border-radius: var(--mn-radius-sm);
    cursor: pointer;
    transition: background var(--mn-transition-fast),
                border-color var(--mn-transition-fast),
                color var(--mn-transition-fast);
}
.store-package-btn:hover {
    border-color: var(--mn-gold);
    color: var(--mn-gold-light);
}
.store-package-btn--featured {
    border-color: transparent;
    background: linear-gradient(180deg, var(--mn-gold-light), var(--mn-gold));
    color: var(--mn-bg-body);
    font-weight: var(--mn-font-semibold);
}
.store-package-btn--featured:hover {
    color: var(--mn-bg-body);
    filter: brightness(1.05);
}
.store-package-btn--selected,
.store-package-btn--selected:hover {
    border-color: var(--mn-gold);
    background: var(--mn-gold);
    color: var(--mn-bg-body);
    font-weight: var(--mn-font-semibold);
}

/* ---- Checkout bar — sticky, rides the viewport on selection ---- */
.store-checkout-bar {
    position: sticky;
    bottom: 1rem;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    flex-wrap: wrap;
    background: var(--mn-bg-surface);
    border: 1px solid var(--mn-gold);
    border-radius: var(--mn-radius-sm);
    padding: 1rem 1.5rem;
    margin-top: 1.75rem;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}
.store-checkout-summary {
    font-family: var(--mn-font-body);
    font-size: 1.25rem;
    color: var(--mn-text-primary);
}
.store-checkout-summary b {
    color: var(--mn-gold-light);
    font-style: italic;
    font-weight: var(--mn-font-regular);
}
.store-checkout-summary .sep {
    color: var(--mn-text-secondary);
    font-size: 0.95rem;
    margin: 0 0.5rem;
}
.store-checkout-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.8rem 2.5rem;
    font-family: var(--mn-font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    font-weight: var(--mn-font-semibold);
    color: var(--mn-bg-body);
    background: linear-gradient(180deg, var(--mn-gold-light), var(--mn-gold));
    border: none;
    border-radius: var(--mn-radius-sm);
    cursor: pointer;
    box-shadow: 0 8px 26px rgba(var(--mn-gold-rgb), 0.4);
    transition: filter var(--mn-transition-fast);
}
.store-checkout-btn:hover:not(:disabled) {
    filter: brightness(1.05);
}
.store-checkout-btn:disabled {
    opacity: 0.7;
    cursor: default;
}

/* ---- "What Can You Unlock?" cards ---- */
.store-section {
    margin-top: 4.5rem;
}
.store-example-card {
    position: relative;
    overflow: hidden;
    background: var(--mn-bg-surface);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-sm);
    padding: 2rem 1.6rem;
    text-align: left;
    height: 100%;
}
.store-example-card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 2px;
    background: linear-gradient(90deg, var(--mn-gold), transparent);
    opacity: 0.6;
}
.store-example-icon {
    font-size: 1.6rem;
    color: var(--mn-gold);
    margin-bottom: 1rem;
}
.store-example-card h3 {
    font-family: var(--mn-font-body);
    font-style: italic;
    font-size: 1.4rem;
    font-weight: var(--mn-font-regular);
    color: var(--mn-text-primary);
    margin-bottom: 0.6rem;
}
.store-example-card p {
    font-family: var(--mn-font-system);
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--mn-text-secondary);
    margin-bottom: 1.1rem;
}
.store-example-price {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--mn-font-mono);
    font-size: 0.6875rem;
    letter-spacing: 0.06em;
    color: var(--mn-gold-light);
    padding-top: 0.9rem;
    border-top: 1px solid var(--mn-border-default);
}
.store-example-price i {
    color: var(--mn-gold);
}

/* ---- "Why Tokens?" benefits ---- */
.store-benefit-icon {
    font-size: 1.6rem;
    color: var(--mn-gold);
    display: block;
    margin-bottom: 0.9rem;
}
.store-benefit h4 {
    font-family: var(--mn-font-body);
    font-style: italic;
    font-weight: var(--mn-font-regular);
    font-size: 1.3rem;
    color: var(--mn-text-primary);
    margin-bottom: 0.5rem;
}
.store-benefit p {
    font-family: var(--mn-font-system);
    font-size: 0.85rem;
    line-height: 1.55;
    color: var(--mn-text-secondary);
    max-width: 280px;
    margin: 0 auto;
}

/* ---- FAQ accordion ---- */
.store-faq {
    max-width: 640px;
    margin: 0 auto;
}
.store-faq-item {
    border-bottom: 1px solid var(--mn-border-default);
}
.store-faq-q {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    background: transparent;
    border: none;
    padding: 1.25rem 0.25rem;
    text-align: left;
    cursor: pointer;
    font-family: var(--mn-font-body);
    font-size: 1.15rem;
    color: var(--mn-text-primary);
    transition: color var(--mn-transition-fast);
}
.store-faq-q:hover {
    color: var(--mn-gold-light);
}
.store-faq-item.open .store-faq-q {
    color: var(--mn-gold);
}
.store-faq-chevron {
    font-family: var(--mn-font-mono);
    color: var(--mn-text-secondary);
    transition: transform var(--mn-transition-fast),
                color var(--mn-transition-fast);
}
.store-faq-item.open .store-faq-chevron {
    transform: rotate(180deg);
    color: var(--mn-gold);
}
.store-faq-a {
    padding: 0 0.25rem 1.4rem;
    font-family: var(--mn-font-system);
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--mn-text-secondary);
}
.store-faq-a a {
    color: var(--mn-gold-light);
}

/* ---- Mobile store ---- */
@media (max-width: 575.98px) {
    .store-hero {
        padding: 3rem 1rem 2.5rem;
    }
    .store-token-count {
        font-size: 2.5rem;
    }
    .store-package {
        padding: 1.6rem 0.7rem 1rem;
    }
    .store-example-card {
        padding: 1.5rem 1.25rem;
    }
    .store-section {
        margin-top: 3.5rem;
    }
    .store-checkout-bar {
        bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
        padding: 0.85rem 1rem;
        gap: 0.85rem;
    }
    .store-checkout-summary {
        font-size: 1.1rem;
    }
    .store-checkout-btn {
        padding: 0.75rem 2rem;
    }
}

/* --- Mobile tab bar: push floating elements above the bar --- */
@media (max-width: 767.98px) {
    body:has([data-mobile-tabbar]) .chat-bubble-btn {
        bottom: calc(72px + env(safe-area-inset-bottom, 0px)) !important;
    }
}

/* AI-INSTRUCTION
   .mn-choice-chip — segmented-style choice chip used in option groups (e.g. cover-studio
   mood/palette selectors). Use anywhere the user picks ONE value from a small fixed list
   and the appearance should communicate "this one is selected." Don't use for tag/badge
   content — those are .mn-tag and .mn-meta-badge. Single class, no per-page variants. */
.mn-choice-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.45rem 0.85rem;
    font-family: var(--mn-font-body);
    font-size: 0.82rem;
    font-weight: var(--mn-font-regular);
    line-height: 1.2;
    color: var(--mn-text-primary);
    background: var(--mn-bg-elevated);
    border: 1px solid var(--mn-border-strong);
    border-radius: var(--mn-radius-sm);
    cursor: pointer;
    transition: border-color var(--mn-transition-fast),
                color var(--mn-transition-fast),
                background var(--mn-transition-fast);
}

.mn-choice-chip:hover {
    border-color: var(--mn-gold);
    color: var(--mn-gold);
}

.mn-choice-chip.is-selected {
    color: var(--mn-bg-elevated);
    background: var(--mn-gold);
    border-color: var(--mn-gold);
    font-weight: var(--mn-font-medium);
}

.mn-choice-chip:focus-visible {
    outline: 2px solid var(--mn-gold);
    outline-offset: 2px;
}

/* AI-INSTRUCTION
   .filter-* primitives — building blocks for browse / search filter UIs.
   Global because they're shared across browse surfaces (FilterDrawer, BooksFilterPanel,
   future SeriesFilterPanel, etc.) and the underlying atoms (FilterSection, ChoiceChipGroup,
   HeatLevelFilter, TagFilterSection) must render the same look regardless of which
   parent page composes them. Do NOT re-introduce these as ::deep selectors inside a
   page-scoped .razor.css — that would re-fuse the primitive to one consumer.

   .filter-section / -section-header / -section-body — collapsible filter group
   .filter-radio-group / -radio-btn / --active — single-choice pill (rounded-full),
       used by Price / Length / Status / Intensity / Rating / Format / Available-As.
       Visually distinct from .mn-choice-chip (square, smaller); --radio-btn is the
       drawer-native option chip with a larger tap target.
   .filter-heat-grid / -heat-btn / --1..--4 — graduated ember→rouge tier chip used
       by HeatLevelFilter. Single-select clears on re-click of the active level.
   .filter-tag-grid / -tag-btn + --active / --exclude / --mild / --moderate / --intense
       — multi-select tag pill with three modes: include, exclude (strikethrough rouge),
       intensity-cycle (Mild → Moderate → Intense → off). */
.filter-section {
    border-bottom: 1px solid var(--mn-border-default);
}

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

.filter-section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: var(--mn-space-4) 0;
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-base);
    font-weight: var(--mn-font-semibold);
    color: var(--mn-text-primary);
    letter-spacing: -0.01em;
    transition: color var(--mn-transition-fast);
}

.filter-section-header:hover {
    color: var(--mn-gold);
}

.filter-section-header i {
    color: var(--mn-gold);
    transition: transform var(--mn-transition-fast);
    opacity: 0.7;
}

.filter-section-header small {
    font-family: var(--mn-font-body);
    font-style: italic;
    color: var(--mn-text-tertiary);
}

.filter-section-body {
    padding: var(--mn-space-1) 0 var(--mn-space-4);
}

/* === Tag Grid (multi-select buttons) === */
.filter-tag-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mn-space-2);
}

.filter-tag-btn {
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-sm);
    font-weight: var(--mn-font-medium);
    padding: 0.4rem 0.85rem;
    border-radius: var(--mn-radius-full);
    border: 1px solid var(--mn-border-strong);
    background: transparent;
    color: var(--mn-text-primary);
    opacity: 0.8;
    cursor: pointer;
    transition: all var(--mn-transition-fast);
    white-space: nowrap;
}

.filter-tag-btn:hover {
    border-color: var(--mn-gold);
    color: var(--mn-gold);
    opacity: 1;
}

/* Plain include state (Trope, Genre, Setting, Character, Relationship) */
.filter-tag-btn--active {
    background: rgba(217, 137, 71, 0.12);
    color: var(--mn-gold);
    border-color: var(--mn-gold);
    font-weight: var(--mn-font-semibold);
    opacity: 1;
}

/* Content Warning exclude — rouge with strikethrough */
.filter-tag-btn--exclude {
    background: rgba(168, 58, 74, 0.15);
    color: var(--mn-danger-dark);
    border-color: var(--mn-danger);
    font-weight: var(--mn-font-semibold);
    text-decoration: line-through;
    opacity: 1;
}

.filter-tag-btn--exclude::before {
    content: "\2715";
    margin-right: 0.35rem;
    font-family: var(--mn-font-body);
    font-weight: var(--mn-font-regular);
    text-decoration: none;
    display: inline-block;
}

/* Intensity cycling (Kink, Mood): Mild → Moderate → Intense → off */
.filter-tag-btn--mild {
    background: rgba(217, 137, 71, 0.08);
    color: var(--mn-gold-light);
    border-color: rgba(217, 137, 71, 0.4);
    font-weight: var(--mn-font-semibold);
    opacity: 1;
}

.filter-tag-btn--moderate {
    background: rgba(217, 137, 71, 0.18);
    color: var(--mn-gold);
    border-color: var(--mn-gold);
    font-weight: var(--mn-font-semibold);
    opacity: 1;
}

.filter-tag-btn--intense {
    background: rgba(168, 58, 74, 0.18);
    color: var(--mn-danger-dark);
    border-color: var(--mn-danger);
    font-weight: var(--mn-font-semibold);
    opacity: 1;
}

/* === Radio Group (single-select pill) === */
.filter-radio-group {
    display: flex;
    flex-wrap: wrap;
    gap: var(--mn-space-2);
}

.filter-radio-btn {
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-sm);
    font-weight: var(--mn-font-medium);
    padding: 0.5rem 1.1rem;
    min-height: 40px;
    border-radius: var(--mn-radius-full);
    border: 1px solid var(--mn-border-strong);
    background: transparent;
    color: var(--mn-text-primary);
    opacity: 0.8;
    cursor: pointer;
    transition: all var(--mn-transition-fast);
    white-space: nowrap;
}

.filter-radio-btn:hover {
    border-color: var(--mn-gold);
    color: var(--mn-gold);
    opacity: 1;
}

.filter-radio-btn--active {
    background: var(--mn-gold);
    color: var(--mn-text-inverse);
    border-color: var(--mn-gold);
    font-weight: var(--mn-font-semibold);
    opacity: 1;
}

/* === Heat Level Buttons (Steamy / Explicit / Erotic / Extreme) === */
.filter-heat-grid {
    display: flex;
    gap: var(--mn-space-2);
    flex-wrap: wrap;
}

.filter-heat-btn {
    font-family: var(--mn-font-body);
    font-size: var(--mn-text-sm);
    font-weight: var(--mn-font-medium);
    padding: 0.55rem 1rem;
    min-height: 42px;
    border-radius: var(--mn-radius-full);
    border: 1px solid var(--mn-border-strong);
    background: transparent;
    color: var(--mn-text-primary);
    opacity: 0.8;
    cursor: pointer;
    transition: all var(--mn-transition-fast);
    white-space: nowrap;
    flex: 1;
    min-width: 140px;
    text-align: center;
    letter-spacing: 0.02em;
}

.filter-heat-btn:hover {
    border-color: var(--mn-gold);
    color: var(--mn-gold);
    opacity: 1;
}

/* Heat tiers — graduated ember → rouge */
.filter-heat-btn--active.filter-heat-btn--1 {
    background: rgba(217, 137, 71, 0.10);
    color: var(--mn-warning-dark);
    border-color: rgba(217, 137, 71, 0.5);
    opacity: 1;
    font-weight: var(--mn-font-semibold);
}

.filter-heat-btn--active.filter-heat-btn--2 {
    background: rgba(217, 137, 71, 0.20);
    color: var(--mn-gold);
    border-color: var(--mn-gold);
    opacity: 1;
    font-weight: var(--mn-font-semibold);
}

/* bootstrap-eradication: REVIEW — off-palette pinks (#e8a0a8 / #c77a8a) for heat-3 exclude state; needs --mn-rouge-* token decision. */
.filter-heat-btn--active.filter-heat-btn--3 {
    background: rgba(199, 122, 138, 0.18);
    color: #e8a0a8;
    border-color: #c77a8a;
    opacity: 1;
    font-weight: var(--mn-font-semibold);
}

.filter-heat-btn--active.filter-heat-btn--4 {
    background: rgba(168, 58, 74, 0.22);
    color: var(--mn-danger-dark);
    border-color: var(--mn-danger);
    opacity: 1;
    font-weight: var(--mn-font-semibold);
}

/* === Range Input (min / max number pair) — used by RangeInput primitive === */
.filter-range {
    display: flex;
    align-items: center;
    gap: var(--mn-space-2);
}

.filter-range input {
    width: 5rem;
    background: var(--mn-bg-surface-alt);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-sm);
    color: var(--mn-text-primary);
    padding: var(--mn-space-1) var(--mn-space-2);
    font-family: var(--mn-font-body);
    font-size: 0.875rem;
}

.filter-range span {
    color: var(--mn-text-tertiary);
    font-size: 0.8125rem;
}

/* Form-check switch inside filter sections: ember when on */
.filter-section-body .form-check-input:checked {
    background-color: var(--mn-gold);
    border-color: var(--mn-gold);
}

.filter-section-body .form-check-input:focus {
    border-color: var(--mn-gold);
    box-shadow: 0 0 0 0.2rem rgba(217, 137, 71, 0.30);
}

.filter-section-body .form-check-label {
    color: var(--mn-text-primary);
    font-family: var(--mn-font-body);
}

/* Print styles for receipts */
@media print {
    .site-header, .nav-actions, .btn, .mobile-overlay,
    .mobile-toggle, footer, .gate-cta-group {
        display: none !important;
    }
    .receipt-header {
        border-color: #000;
    }
}

/* =============================================
   BookEdit Sticky Save Bar (global because position:fixed viewport elements
   under Blazor CSS isolation can fail silently across hot-reload boundaries;
   sticky save UI is the kind of primitive that's likely to want reuse anyway).
   ============================================= */
.book-edit-save-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1031; /* +1 above responsive-tabs-mobile bottom bar (1030) */
    /* Gold-tinted band so the bar reads as an attention surface rather than another
       flat strip of page chrome. Gradient sits on top of --mn-bg-surface so the rgba
       gold tint composites cleanly without bleeding through to the page below. */
    background: linear-gradient(
        to bottom,
        rgba(var(--mn-gold-rgb), 0.16),
        rgba(var(--mn-gold-rgb), 0.06)
    ), var(--mn-bg-surface);
    border-top: 2px solid var(--mn-gold);
    box-shadow: 0 -10px 32px rgba(0, 0, 0, 0.45);
    padding: var(--mn-space-4) var(--mn-space-4);
    padding-bottom: calc(var(--mn-space-4) + env(safe-area-inset-bottom, 0px));
    animation: book-edit-save-bar-slide-in 200ms ease-out;
}

@keyframes book-edit-save-bar-slide-in {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}

.book-edit-save-bar-inner {
    max-width: 900px;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--mn-space-3);
    flex-wrap: wrap;
}

.book-edit-save-bar-status {
    display: flex;
    align-items: center;
    gap: var(--mn-space-2);
    color: var(--mn-gold);
    font-size: var(--mn-text-base);
    font-weight: var(--mn-font-semibold);
    letter-spacing: 0.01em;
}

.book-edit-save-bar-status i {
    color: var(--mn-gold);
    font-size: 1.25em;
    animation: book-edit-save-bar-pulse 2s ease-in-out infinite;
}

@keyframes book-edit-save-bar-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.45; }
}

.book-edit-save-bar-actions {
    display: flex;
    gap: var(--mn-space-2);
    flex-wrap: wrap;
}

/* Primary CTA inside the bar gets a touch more horizontal padding so it reads as
   the bar's main action, not just any button. */
.book-edit-save-bar-actions .btn {
    padding-inline: var(--mn-space-5);
}

/* Mobile: sit above the responsive-tabs-mobile bottom tab bar (~64px + safe area). */
@media (max-width: 767.98px) {
    .book-edit-save-bar {
        bottom: calc(64px + env(safe-area-inset-bottom, 0px));
        padding-bottom: var(--mn-space-3);
    }
    .book-edit-save-bar-status {
        font-size: var(--mn-text-sm);
    }
}

/* =============================================
   Clickable row / card affordance — used on admin list rows and mobile cards
   that act as links to a detail page. Centralises the cursor:pointer hint so
   per-page inline styles don't need to redeclare it (CLAUDE.md non-negotiable
   #1: shared visual affordances belong in global CSS, not inline styles).
   ============================================= */
.mn-clickable-row {
    cursor: pointer;
}

/* =============================================
   .mn-collection-card — global card primitive for the /collections index
   and any surface that renders a collection summary card (Plan 05 consumes it).
   Ported from the AisleLanding scoped collage CSS (.topic-hero-collage,
   AisleLanding.razor.css ~242–284) and adapted to the __collage/__collage-cover
   names. NEVER redefine in a .razor.css file — extend here only (CLAUDE.md #1).
   The page-scoped collection landing hero uses a SEPARATE .coll-hero-collage
   class (Plan 04), not this card collage.
   Uses --mn-* tokens only (CLAUDE.md #2); no raw hex.
   ============================================= */
.mn-collection-card {
    display: flex;
    flex-direction: column;
    background: var(--mn-bg-surface);
    border: 1px solid var(--mn-border-default);
    border-radius: var(--mn-radius-lg);
    box-shadow: var(--mn-shadow-sm);
    overflow: hidden;
    transition: border-color var(--mn-transition-base), box-shadow var(--mn-transition-base), transform var(--mn-transition-base);
    cursor: pointer;
}

.mn-collection-card:hover,
.mn-collection-card:focus-within {
    border-color: var(--mn-gold);
    box-shadow: var(--mn-shadow-gold);
    transform: translateY(-2px);
}

.mn-collection-card__hero {
    position: relative;
    aspect-ratio: 5 / 2;
    overflow: hidden;
    background: linear-gradient(135deg, var(--mn-bg-inset), var(--mn-bg-surface-alt));
}

.mn-collection-card__hero img:not([class]) {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Collage backdrop — global variant for collection cards.
   Port of .topic-hero-collage from AisleLanding.razor.css ~242–284. */
.mn-collection-card__collage {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    opacity: 0.22;
    filter: blur(2px);
    z-index: 0;
    display: none;
}

.mn-collection-card__collage-cover {
    position: absolute;
    width: 28%;
    max-width: 200px;
    aspect-ratio: 2 / 3;
    overflow: hidden;
}

.mn-collection-card__collage-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* nth-child positions: ported verbatim from AisleLanding.razor.css ~260–278 */
.mn-collection-card__collage-cover:nth-child(1) {
    top: -10%;
    right: 6%;
    transform: rotate(-6deg);
}

.mn-collection-card__collage-cover:nth-child(2) {
    top: 20%;
    right: 32%;
    transform: rotate(4deg);
    opacity: 0.85;
}

.mn-collection-card__collage-cover:nth-child(3) {
    top: -4%;
    right: 58%;
    transform: rotate(-2deg);
    opacity: 0.7;
}

@media (min-width: 480px) {
    .mn-collection-card__collage {
        display: block;
    }
}

.mn-collection-card__body {
    padding: var(--mn-space-4) var(--mn-space-4) var(--mn-space-5);
}

.mn-collection-card__eyebrow {
    /* Used together with .mn-section-eyebrow, which owns the mono/ember styling. */
    margin-bottom: var(--mn-space-1);
}

.mn-collection-card__title {
    font-size: var(--mn-text-xl);
    font-weight: var(--mn-font-bold);
    color: var(--mn-text-primary);
    margin: 0 0 var(--mn-space-1);
    line-height: 1.25;
}

.mn-collection-card__kicker {
    font-style: italic;
    font-size: var(--mn-text-base);
    color: var(--mn-text-secondary);
    margin: 0 0 var(--mn-space-2);
}

.mn-collection-card__meta {
    margin-top: var(--mn-space-3);
    display: flex;
    gap: var(--mn-space-2);
    flex-wrap: wrap;
}