:root {
    color-scheme: dark light;
}

html,
body {
    min-height: 100%;
    margin: 0;
}

body {
    font-family: Inter, Segoe UI, Arial, sans-serif;
}

.top-bar {
    border-bottom: 1px solid var(--mud-palette-divider);
}

/*
    An admin-chosen name can be up to 60 characters, and 60 characters is about 800px — wider than a phone.
    Measured at a 894px layout width it pushed the header 519px past the viewport, so the name truncates
    rather than shoving the account menu off screen. Both min-width: 0 rules are load-bearing: a flex item
    will not shrink below its content without them, and text-overflow needs the box to actually be short.
*/
.brand {
    font-weight: 800;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.brand-link {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    color: inherit;
    text-decoration: none;
    border-radius: 8px;
    padding: 2px 6px;
    margin-left: -6px;
    transition: background-color 120ms ease;
}

.brand-link:hover {
    background: color-mix(in srgb, currentColor, transparent 90%);
}

/* No border-radius here: favicon.svg carries its own rounded tile, and clipping it again shaves the corners. */
.brand-logo {
    width: 28px;
    height: 28px;
    display: block;
    flex: 0 0 auto;
}

.scan-activity-indicator {
    appearance: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 36px;
    padding: 0 10px;
    margin-right: 4px;
    border: 1px solid color-mix(in srgb, var(--mud-palette-primary), transparent 56%);
    border-radius: 999px;
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 88%);
    color: inherit;
    font: inherit;
}

.scan-activity-button {
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease, transform .16s ease;
}

.scan-activity-button:hover,
.scan-activity-button:focus-visible {
    border-color: color-mix(in srgb, var(--mud-palette-primary), transparent 22%);
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 78%);
    outline: 0;
    transform: translateY(-1px);
}

.scan-current-file {
    overflow-wrap: anywhere;
}

.side-nav {
    border-right: 1px solid var(--mud-palette-divider);
}

.side-nav .mud-drawer-content {
    display: flex;
    flex-direction: column;
    align-items: stretch;
}

.side-nav-top,
.side-nav-menu {
    flex: 0 0 auto;
}

.main-content {
    min-height: 100vh;
    background:
        linear-gradient(180deg, rgba(179, 124, 255, .08), transparent 260px),
        var(--mud-palette-background);
}

.page-shell {
    max-width: 1440px;
    margin: 0 auto;
    padding: 28px;
}

.toolbar-band,
.reader-toolbar {
    border-bottom: 1px solid var(--mud-palette-divider);
    background: color-mix(in srgb, var(--mud-palette-surface), transparent 8%);
}

.book-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 16px;
}

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

.home-card-row {
    display: flex;
    gap: 16px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 0 2px 14px;
    scroll-snap-type: x proximity;
}

.home-card-row .browse-card-shell,
.home-card-row .browse-card-link {
    flex: 0 0 auto;
    scroll-snap-align: start;
}

.home-folder-row .browse-card-link {
    width: 248px;
}

.home-book-row .browse-card-shell {
    width: 204px;
}

.home-card-row .browse-card {
    min-height: 100%;
}

.home-section-loading {
    align-items: center;
    display: flex;
    gap: 10px;
    min-height: 64px;
}

.folder-card {
    min-height: 150px;
}

.browse-card-link {
    color: inherit;
    display: block;
    height: 100%;
    text-decoration: none;
}

.browse-card-shell {
    height: 100%;
    position: relative;
}

.browse-card-shell.selected .browse-card {
    border-color: var(--mud-palette-primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--mud-palette-primary), transparent 58%);
    background: color-mix(in srgb, var(--mud-palette-primary), var(--mud-palette-surface) 86%);
}

.browse-card {
    height: 100%;
    border: 1px solid transparent;
    position: relative;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease, background-color .15s ease;
}

.browse-card-link:hover .browse-card,
.browse-card-link:focus-visible .browse-card {
    border-color: var(--mud-palette-primary);
    box-shadow: 0 10px 28px rgba(123, 47, 214, .2);
    transform: translateY(-2px);
    background: color-mix(in srgb, var(--mud-palette-primary), var(--mud-palette-surface) 88%);
}

.browse-card-link:focus-visible {
    border-radius: 6px;
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 3px;
}

.item-select-toggle {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 5;
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: color-mix(in srgb, var(--mud-palette-surface), transparent 16%);
    color: var(--mud-palette-primary);
    cursor: pointer;
    opacity: 0;
    transform: translateY(-3px);
    transition: opacity .15s ease, transform .15s ease, background-color .15s ease;
}

.browse-card-shell:hover .item-select-toggle,
.browse-card-shell:focus-within .item-select-toggle,
.browse-card-shell.selected .item-select-toggle {
    opacity: 1;
    transform: translateY(0);
}

.item-select-toggle:hover {
    background: color-mix(in srgb, var(--mud-palette-primary), var(--mud-palette-surface) 78%);
}

.item-select-toggle .mud-icon-root {
    display: block;
}

.bulk-action-bar {
    position: sticky;
    top: 12px;
    z-index: 12;
    border: 1px solid color-mix(in srgb, var(--mud-palette-primary), transparent 35%);
}

.folder-title {
    margin-top: 10px;
    overflow-wrap: anywhere;
}

.reading-marker {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 2;
    border-radius: 999px;
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    padding: 0;
    color: #050007;
}

.browse-card-shell.selection-active .reading-marker {
    left: 8px;
}

.favorite-marker {
    position: absolute;
    right: 8px;
    bottom: 44px;
    z-index: 3;
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    background: #ffcc80;
    color: #050007;
}

.pinned-library-marker {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 3;
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    background: #ffcc80;
    color: #050007;
}

.card-menu {
    position: absolute;
    right: 4px;
    bottom: 4px;
    z-index: 4;
}

.marker-current {
    background: #ffcc80;
}

.marker-completed {
    background: #8be6c4;
}

.book-cover {
    aspect-ratio: 2 / 3;
    display: grid;
    place-items: center;
    background: linear-gradient(150deg, rgba(123, 47, 214, .24), rgba(0, 108, 103, .16));
    border-bottom: 1px solid var(--mud-palette-divider);
    overflow: hidden;
}

.book-cover img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
}

.book-title {
    min-height: 48px;
    overflow-wrap: anywhere;
}

.path-text {
    max-width: 520px;
    overflow-wrap: anywhere;
}

.text-right {
    text-align: right;
}

.details-cover {
    align-items: center;
    aspect-ratio: 2 / 3;
    background: var(--reader-stage);
    border-radius: 6px;
    display: flex;
    justify-content: center;
    overflow: hidden;
    width: 100%;
}

.details-cover img {
    height: 100%;
    object-fit: cover;
    width: 100%;
}

.reader-details-header {
    align-items: flex-start;
}

.reader-details-cover {
    align-items: center;
    aspect-ratio: 2 / 3;
    background: var(--reader-stage);
    border-radius: 6px;
    display: flex;
    flex: 0 0 112px;
    justify-content: center;
    overflow: hidden;
    width: 112px;
}

.reader-details-cover img {
    height: 100%;
    object-fit: cover;
    width: 100%;
}

.reader-details-title {
    min-width: 0;
}

.reader-page {
    min-height: 100vh;
    background: var(--reader-stage);
    color: var(--text);
    overflow: hidden;
    position: relative;
    --reader-page-transition-duration: 260ms;
}

.reader-stage {
    height: 100dvh;
    overflow: auto;
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    padding: 0;
    background: var(--reader-stage);
    overscroll-behavior: contain;
    position: relative;
    touch-action: pan-y pinch-zoom;
    -webkit-overflow-scrolling: touch;
}

.reader-stage.direction-rtl {
    direction: rtl;
}

.reader-stage.epub-stage {
    overflow-x: auto;
    overflow-y: hidden;
    align-items: stretch;
    scroll-snap-type: none;
    touch-action: pan-x pinch-zoom;
}

.reader-stage.image-stage {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.reader-stage.image-stage::-webkit-scrollbar {
    width: 0;
    height: 0;
    display: none;
}

.reader-image {
    display: block;
    object-fit: contain;
    background: var(--reader-stage);
    pointer-events: none;
    will-change: transform, opacity;
}

.reader-image-spread {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    gap: 0;
    width: 100%;
    min-height: 100%;
    background: var(--reader-stage);
    will-change: transform, opacity;
}

.reader-image-spread .reader-image {
    flex: 0 1 50%;
    max-width: 50%;
}

.reader-image-spread .reader-image.fit-width {
    width: 50%;
    height: auto;
    margin: 0;
}

.reader-image-spread .reader-image.fit-height {
    width: auto;
    max-width: 50%;
    height: 100%;
    margin: 0;
}

.reader-image-spread .reader-image.actual-size {
    max-width: none;
    max-height: none;
}

/*
    A single page in two-page view, of which there are two kinds.

    GetImageSpreadPages returns one page in three cases: the page is a splash, the *next* page is a splash,
    or it is the last page of an odd count. Every rule above pins a child to half the width, because that is
    what one page of a pair is -- so all three drew at half the stage, pinned to the top, with dead space
    below. That is what "not aligned in any way" looked like.

    Only a splash should take the whole stage: it is one wide image standing in for both pages. The other two
    are ordinary portrait pages, and stretching those to double width would be worse than the misalignment --
    hence the splash-spread class, which the component sets because CSS cannot tell the cases apart.

    Both are centred with auto block margins rather than align-items on the container, deliberately: auto
    margins collapse to zero when there is no free space, so an image taller than the viewport still starts at
    the top and scrolls. align-items: center would centre the overflow instead and cut the top off, which is
    why the container is flex-start to begin with.

    Each selector names its fit class so it outranks the half-width rules above whatever the order.
*/
.reader-image-spread .reader-image:only-child,
.reader-image-spread .reader-image.fit-width:only-child,
.reader-image-spread .reader-image.fit-height:only-child,
.reader-image-spread .reader-image.actual-size:only-child {
    margin-block: auto;
}

.reader-image-spread.splash-spread .reader-image:only-child {
    flex: 0 1 100%;
    max-width: 100%;
}

.reader-image-spread.splash-spread .reader-image.fit-width:only-child {
    width: 100%;
    max-width: 100%;
}

.reader-image-spread.splash-spread .reader-image.fit-height:only-child {
    width: auto;
    max-width: 100%;
    height: 100%;
}

.reader-image-spread.splash-spread .reader-image.actual-size:only-child {
    max-width: none;
    max-height: none;
}

.reader-transition-layer {
    position: fixed;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    overflow: hidden;
    background: var(--reader-stage);
    pointer-events: none;
    will-change: transform, opacity;
}

.reader-transition-layer.slide-next-out {
    animation: reader-slide-next-out var(--reader-page-transition-duration) cubic-bezier(0.4, 0, 0.8, 0.3) both;
}

.reader-transition-layer.slide-previous-out {
    animation: reader-slide-previous-out var(--reader-page-transition-duration) cubic-bezier(0.4, 0, 0.8, 0.3) both;
}

.reader-image.slide-next,
.epub-reader-page.slide-next,
.reader-image-spread.slide-next {
    animation: reader-slide-next var(--reader-page-transition-duration) cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

.reader-image.slide-previous,
.epub-reader-page.slide-previous,
.reader-image-spread.slide-previous {
    animation: reader-slide-previous var(--reader-page-transition-duration) cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

@keyframes reader-slide-next {
    from {
        opacity: 0.55;
        transform: translateX(18vw);
    }

    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes reader-slide-previous {
    from {
        opacity: 0.55;
        transform: translateX(-18vw);
    }

    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes reader-slide-next-out {
    from {
        opacity: 1;
        transform: translateX(0);
    }

    to {
        opacity: 0.38;
        transform: translateX(-18vw);
    }
}

@keyframes reader-slide-previous-out {
    from {
        opacity: 1;
        transform: translateX(0);
    }

    to {
        opacity: 0.38;
        transform: translateX(18vw);
    }
}

.reader-image.fit-width {
    width: 100%;
    height: auto;
    margin: 0 auto;
}

.reader-image.fit-height {
    width: auto;
    height: 100%;
    margin: 0 auto;
}

.reader-image.actual-size {
    max-width: none;
    max-height: none;
}

.epub-reader-page {
    --epub-page-padding-x: clamp(28px, 7vw, 92px);
    --epub-column-gap: var(--epub-page-padding-x);
    box-sizing: border-box;
    flex: 0 0 100vw;
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    padding: 42px var(--epub-page-padding-x) 64px;
    background: var(--epub-reader-bg, color-mix(in srgb, #12071c, #050007 22%));
    color: var(--epub-reader-color, #f8f2ff);
    font-family: var(--epub-reader-font-family, Inter, sans-serif);
    font-size: var(--epub-reader-font-size, 18px);
    line-height: 1.72;
    overflow-wrap: anywhere;
    column-width: calc((100vw - (var(--epub-page-padding-x) * 2) - ((var(--epub-reader-page-columns, 1) - 1) * var(--epub-column-gap))) / var(--epub-reader-page-columns, 1));
    column-gap: var(--epub-column-gap);
    column-fill: auto;
    overflow-x: hidden;
    overflow-y: hidden;
    scroll-snap-align: start;
    pointer-events: none;
    scrollbar-width: none;
}

.epub-reader-page::-webkit-scrollbar {
    display: none;
}

.epub-reader-page h1,
.epub-reader-page h2,
.epub-reader-page h3,
.epub-reader-page h4 {
    line-height: 1.22;
    margin: 1.4em 0 .6em;
}

.epub-reader-page p {
    margin: 0 0 1em;
}

.epub-reader-page img,
.epub-reader-page svg,
.epub-reader-page video {
    display: block;
    max-width: min(100%, 720px);
    max-height: calc(100dvh - 132px);
    width: auto;
    height: auto;
    margin: 1.2rem auto;
    break-inside: avoid;
}

.epub-reader-page a {
    color: var(--mud-palette-primary);
}

.epub-reader-page table {
    max-width: 100%;
    border-collapse: collapse;
    break-inside: avoid;
}

.epub-reader-page pre {
    white-space: pre-wrap;
}

.pdf-frame {
    width: 100%;
    height: 100%;
    border: 0;
    background: white;
}

.immersive-reader-header,
.immersive-reader-footer {
    position: fixed;
    left: 0;
    right: 0;
    z-index: 30;
    display: flex;
    align-items: center;
    gap: 10px;
    background: color-mix(in srgb, var(--surface-card) 84%, transparent);
    border-color: var(--divider);
    backdrop-filter: blur(14px);
}

/*
    The "still caching this issue" mark in the reader header. Deliberately quiet: it reports work
    nobody asked to watch, and it is next to controls that do want the eye. The count is tabular so
    the width does not twitch as it climbs, and min-width holds the row steady when it disappears.
*/
.reader-cache-indicator {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 64px;
    font-size: 11.5px;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

.reader-side-drawer {
    width: min(420px, 92vw);
    background: var(--mud-palette-background);
    border-left: 1px solid var(--mud-palette-lines-default);
}

.reader-side-drawer .mud-drawer-content,
.reader-side-drawer .mud-stack {
    height: 100%;
}

.reader-toc-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    padding-right: 2px;
}

.reader-toc-item {
    appearance: none;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--mud-palette-text-primary);
    cursor: pointer;
    display: grid;
    gap: 2px;
    padding: 8px 10px 8px calc(10px + (var(--toc-level, 0) * 16px));
    text-align: left;
    width: 100%;
}

.reader-toc-item:hover,
.reader-toc-item.active {
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 84%);
    border-color: color-mix(in srgb, var(--mud-palette-primary), transparent 48%);
}

.reader-toc-item span {
    font-weight: 650;
    line-height: 1.25;
}

.reader-toc-item small {
    color: var(--mud-palette-text-secondary);
}

.reader-page-slider {
    margin-top: 4px;
    min-height: 42px;
    touch-action: pan-y;
}

.reader-page-slider .mud-slider-container {
    min-height: 42px;
    padding-block: 12px;
}

.reader-page-slider .mud-slider-track,
.reader-page-slider .mud-slider-rail {
    height: 8px;
    border-radius: 999px;
}

.reader-page-slider .mud-slider-rail {
    background-color: color-mix(in srgb, var(--text) 28%, transparent);
}

.reader-page-slider .mud-slider-track {
    box-shadow: 0 0 14px color-mix(in srgb, var(--mud-palette-primary), transparent 45%);
}

.reader-page-slider .mud-slider-thumb {
    width: 28px;
    height: 28px;
    border: 3px solid var(--text);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.55), 0 0 0 8px color-mix(in srgb, var(--text) 14%, transparent);
}

.reader-page-slider .mud-slider-thumb:hover,
.reader-page-slider .mud-slider-thumb:focus-visible,
.reader-page-slider .mud-slider-thumb:active {
    box-shadow: 0 2px 14px rgba(0, 0, 0, 0.65), 0 0 0 12px color-mix(in srgb, var(--text) 20%, transparent);
}

.reader-page-slider input[type="range"] {
    min-height: 44px;
}

.immersive-reader-header {
    top: 0;
    min-height: 60px;
    padding: 8px 12px;
    border-bottom: 1px solid;
}

.immersive-reader-footer {
    bottom: 0;
    flex-direction: column;
    align-items: stretch;
    padding: 10px 18px 14px;
    border-top: 1px solid;
}

.reader-footer-controls {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 8px;
    width: 100%;
}

.reader-footer-controls.text-reader-controls {
    grid-template-columns: auto minmax(0, 1fr) auto;
}

.reader-footer-controls.image-reader-controls > :nth-child(3) {
    justify-self: center;
}

.reader-footer-progress {
    min-width: 0;
    overflow: hidden;
    text-align: center;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.reader-issue-list-panel {
    position: absolute;
    right: 18px;
    bottom: calc(100% + 10px);
    z-index: 35;
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: min(420px, calc(100vw - 36px));
    max-height: min(64vh, 620px);
    overflow: auto;
    padding: 10px;
    background: color-mix(in srgb, var(--surface-card) 96%, transparent);
    border: 1px solid var(--divider);
    border-radius: 8px;
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.46);
    backdrop-filter: blur(14px);
}

.reader-issue-list-item {
    appearance: none;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--text);
    cursor: pointer;
    display: grid;
    grid-template-columns: 48px minmax(0, 1fr);
    align-items: center;
    gap: 10px;
    min-height: 72px;
    padding: 6px 8px;
    text-align: left;
}

.reader-issue-list-item img {
    width: 48px;
    height: 66px;
    object-fit: cover;
    border-radius: 4px;
    background: color-mix(in srgb, var(--text) 10%, transparent);
}

.reader-issue-list-item span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.reader-issue-list-item:hover,
.reader-issue-list-item.active {
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 76%);
    border-color: color-mix(in srgb, var(--mud-palette-primary), transparent 38%);
}

.reader-issue-list-item.active {
    cursor: default;
    font-weight: 700;
}

.reader-click-zones {
    display: none;
    position: fixed;
    inset: 0 14px 14px 0;
    z-index: 20;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    pointer-events: none;
}

.reader-click-zone {
    appearance: none;
    border: 0;
    background: transparent;
    cursor: pointer;
    pointer-events: auto;
}

.reader-click-zone:focus {
    outline: none;
}

.reader-click-zone-center {
    cursor: default;
}

.reader-title {
    max-width: min(48vw, 620px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fit-select {
    width: 128px;
}

.direction-select {
    width: 96px;
}

.page-size-select {
    width: 104px;
}

/*
    The browse pages' letter rail.

    It is a flex sibling of the browse content rather than a floating overlay, so it can never sit on top of
    a card, and it sticks below the app bar so it stays reachable while the grid scrolls past. 27 keys at
    18px plus the gaps is about 540px, which fits a 768px-high window under the 64px app bar; the
    short-viewport rule below keeps it fitting on anything smaller.
*/
.browse-body {
    display: flex;
    align-items: flex-start;
    gap: 14px;
}

.browse-body-main {
    /* Load-bearing: without it the card grids refuse to shrink and the rail is pushed off the page. */
    flex: 1 1 auto;
    min-width: 0;
}

.letter-rail {
    position: sticky;
    top: calc(var(--mud-appbar-height, 64px) + 20px);
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 6px 4px;
    border: 1px solid var(--mud-palette-divider);
    border-radius: 999px;
    background: color-mix(in srgb, var(--mud-palette-surface), transparent 25%);
}

.letter-rail-key {
    appearance: none;
    width: 24px;
    height: 20px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: none;
    color: var(--mud-palette-text-secondary);
    font: inherit;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease;
}

.letter-rail-key:hover:not(:disabled) {
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 82%);
    color: var(--mud-palette-primary);
}

.letter-rail-key:disabled {
    color: color-mix(in srgb, var(--mud-palette-text-secondary), transparent 62%);
    cursor: default;
}

.letter-rail-key.is-current {
    background: var(--mud-palette-primary);
    color: var(--mud-palette-background);
}

@media (max-height: 780px) {
    .letter-rail-key {
        height: 17px;
        font-size: 0.66rem;
    }
}

.empty-state,
.not-found {
    padding-top: 72px;
}

.auth-shell {
    min-height: 100vh;
    display: grid;
    align-items: center;
}

.auth-label {
    display: grid;
    gap: 6px;
    color: var(--mud-palette-text-secondary);
    font-size: .875rem;
    font-weight: 500;
}

.auth-input {
    width: 100%;
    min-height: 48px;
    border: 1px solid var(--mud-palette-lines-inputs);
    border-radius: 6px;
    padding: 0 14px;
    background: var(--mud-palette-surface);
    color: var(--mud-palette-text-primary);
    font: inherit;
}

.auth-input:focus {
    border-color: var(--mud-palette-primary);
    outline: 2px solid color-mix(in srgb, var(--mud-palette-primary), transparent 70%);
}

.scan-log-viewer {
    max-height: 62vh;
    overflow: auto;
    border: 1px solid var(--mud-palette-divider);
    border-radius: 6px;
    padding: 12px;
    background: var(--mud-palette-background);
    color: var(--mud-palette-text-primary);
    font-family: Consolas, "Courier New", monospace;
    font-size: .84rem;
    white-space: pre-wrap;
}

.admin-log-viewer {
    min-height: 56vh;
    margin: 0;
    word-break: break-word;
}

.log-viewer-select {
    min-width: min(360px, 42vw);
}

.comic-manager-main {
    min-width: 0;
}

.comic-manager-toolbar {
    flex-wrap: wrap;
}

.comic-manager-toolbar .mud-button-root {
    min-height: 40px;
    height: 40px;
    white-space: nowrap;
}

.library-actions-header {
    min-width: 172px;
    text-align: right;
}

.library-actions-cell {
    min-width: 172px;
}

.library-action-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    white-space: nowrap;
}

.library-action-bar .mud-icon-button {
    border: 1px solid color-mix(in srgb, var(--mud-palette-primary), transparent 62%);
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 90%);
}

.library-action-bar .mud-icon-button:hover {
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 78%);
}

.path-input-row {
    gap: 8px;
}

.metadata-source-list {
    margin-top: 4px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
}

.metadata-source-rank {
    width: 1.5em;
    text-align: center;
    color: var(--mud-palette-text-secondary);
}

.path-input {
    flex: 1 1 auto;
}

.path-browse-button {
    flex: 0 0 auto;
    margin-top: 7px;
    border: 1px solid color-mix(in srgb, var(--mud-palette-primary), transparent 62%);
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 90%);
}

.folder-picker-panel {
    border: 1px solid var(--mud-palette-divider);
    background: color-mix(in srgb, var(--mud-palette-surface), transparent 6%);
}

.folder-browser-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1400;
    display: grid;
    place-items: center;
    padding: 24px;
    background: rgba(0, 0, 0, .58);
}

.folder-browser-dialog {
    width: min(760px, calc(100vw - 32px));
    max-height: calc(100vh - 48px);
    overflow: hidden;
    border: 1px solid var(--mud-palette-divider);
}

.folder-browser-path-row {
    min-height: 42px;
    border: 1px solid var(--mud-palette-divider);
    border-radius: 6px;
    padding: 4px 8px;
}

.stats-period-select {
    width: 180px;
}

.stats-chart-header {
    gap: 12px;
    flex-wrap: wrap;
}

.stats-line-chart {
    min-height: 320px;
    width: 100%;
}

.stats-line-chart svg {
    display: block;
    height: 320px;
    overflow: visible;
    width: 100%;
}

.stats-chart-axis {
    stroke: var(--mud-palette-lines-default);
    stroke-width: 1.5;
}

.stats-chart-grid {
    stroke: var(--mud-palette-divider);
    stroke-width: 1;
}

.stats-chart-line {
    fill: none;
    stroke: var(--mud-palette-primary);
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 3;
}

.stats-chart-point {
    cursor: default;
    fill: var(--mud-palette-primary);
    stroke: var(--mud-palette-surface);
    stroke-width: 2;
}

.stats-chart-point:hover {
    fill: var(--mud-palette-secondary);
}

.stats-chart-x-label,
.stats-chart-y-label {
    fill: var(--mud-palette-text-secondary);
    font-size: 12px;
}

.stats-kpi {
    border: 1px solid var(--mud-palette-divider);
    border-radius: 6px;
    padding: 12px;
    background: color-mix(in srgb, var(--mud-palette-surface), transparent 6%);
}

.admin-stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px;
}

.media-setting-row {
    border-bottom: 1px solid var(--mud-palette-divider);
    padding-bottom: 16px;
}

.media-setting-row:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

.media-setting-editor {
    max-width: 520px;
}

.task-interval-select {
    min-width: 170px;
}

.backup-location-row {
    max-width: 360px;
}

.task-action-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    white-space: nowrap;
}

.search-panel,
.search-result {
    border: 1px solid var(--mud-palette-divider);
    background: color-mix(in srgb, var(--mud-palette-surface), transparent 6%);
}

.search-form-grid {
    align-items: center;
}

.search-button-cell {
    display: flex;
    align-items: center;
}

.search-submit-button {
    min-height: 54px;
    margin-top: 0;
}

.search-result-link {
    display: block;
    color: inherit;
    text-decoration: none;
}

.search-result {
    transition: border-color .16s ease, background .16s ease, transform .16s ease;
}

.search-result:hover {
    border-color: color-mix(in srgb, var(--mud-palette-primary), transparent 28%);
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 88%);
    transform: translateY(-1px);
}

.search-result-body {
    min-width: 0;
}

.search-match {
    overflow-wrap: anywhere;
}

.metadata-field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 16px;
}

/* Story arc overview cards */
.reader-arc-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 24px;
}

.reader-arc-card {
    border: 1px solid var(--mud-palette-divider);
    border-radius: 12px;
    overflow: hidden;
    background: var(--mud-palette-surface);
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    display: flex;
    flex-direction: column;
}

.reader-arc-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

.reader-arc-card-cover {
    width: 100%;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    background: color-mix(in srgb, var(--mud-palette-primary) 8%, var(--mud-palette-surface));
    flex-shrink: 0;
}

.reader-arc-card-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.reader-arc-card-cover-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--mud-palette-primary) 20%, transparent);
    font-size: 2.5rem;
    font-weight: 700;
    color: var(--mud-palette-primary);
    letter-spacing: 0.05em;
}

.reader-arc-card-body {
    padding: 20px;
    display: flex;
    flex-direction: column;
    flex: 1;
}

.reader-arc-card-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 6px;
}

.reader-arc-publisher {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--mud-palette-primary);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.reader-arc-chip {
    margin: 0 !important;
    height: 22px !important;
}

.reader-arc-card-title {
    font-size: 1rem;
    font-weight: 700;
    margin: 0 0 6px;
    line-height: 1.3;
    color: var(--mud-palette-text-primary);
}

.reader-arc-card-desc {
    font-size: 0.8rem;
    color: var(--mud-palette-text-secondary);
    margin: 0 0 10px;
    line-height: 1.5;
    flex: 1;
}

.reader-arc-progress {
    margin-bottom: 10px !important;
}

.reader-arc-card-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.reader-arc-footer-meta {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

.reader-arc-card-actions {
    display: flex;
    gap: 4px;
    margin-top: 8px;
    border-top: 1px solid var(--mud-palette-divider);
    padding-top: 8px;
}

/* Story arc detail page */
.reader-arc-detail-header {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 40px;
    align-items: start;
    margin-bottom: 40px;
}

.reader-arc-detail-cover {
    width: 220px;
    aspect-ratio: 2 / 3;
    border-radius: 10px;
    overflow: hidden;
    background: color-mix(in srgb, var(--mud-palette-primary) 8%, var(--mud-palette-surface));
    flex-shrink: 0;
}

.reader-arc-detail-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.reader-arc-detail-eyebrow {
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-primary);
    margin: 0 0 8px;
}

.reader-arc-detail-title {
    font-size: 2rem;
    font-weight: 700;
    margin: 0 0 16px;
    line-height: 1.2;
    color: var(--mud-palette-text-primary);
}

.reader-arc-detail-description {
    color: var(--mud-palette-text-secondary);
    line-height: 1.7;
    max-width: 640px;
    margin: 0 0 20px;
}

.reader-arc-source-link {
    display: inline-block;
    margin-bottom: 16px;
    font-size: 0.85rem;
    color: var(--mud-palette-primary);
    text-decoration: none;
    opacity: 0.85;
}

.reader-arc-source-link:hover {
    opacity: 1;
    text-decoration: underline;
}

.reader-arc-detail-stats {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

.reader-arc-detail-progress {
    max-width: 400px;
    margin-bottom: 20px;
}

.reader-arc-detail-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.reader-arc-section-heading {
    font-size: 1.2rem;
    font-weight: 700;
    margin: 0 0 16px;
    color: var(--mud-palette-text-primary);
}

@media (max-width: 640px) {
    .reader-arc-detail-header {
        grid-template-columns: 1fr;
    }

    .reader-arc-detail-cover {
        width: 100%;
        aspect-ratio: 3 / 2;
    }
}

.metadata-loader,
.page-loader {
    min-height: 320px;
    display: grid;
    place-items: center;
    align-content: center;
    text-align: center;
}

.metadata-controls {
    border: 1px solid var(--mud-palette-divider);
    background: color-mix(in srgb, var(--mud-palette-surface), transparent 6%);
}

.metadata-field-card,
.metadata-value-tile {
    border: 1px solid var(--mud-palette-divider);
    background: color-mix(in srgb, var(--mud-palette-surface), transparent 6%);
}

.metadata-value-link,
.metadata-value-tile {
    color: inherit;
    text-decoration: none;
    transition: border-color .16s ease, background .16s ease, transform .16s ease;
}

.metadata-value-row {
    display: flex;
    align-items: center;
    gap: 4px;
}

.metadata-value-row .metadata-value-link {
    flex: 1 1 auto;
    min-width: 0;
}

.metadata-value-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    border-radius: 6px;
    padding: 8px 10px;
    overflow-wrap: anywhere;
}

.metadata-value-link:hover,
.metadata-value-tile:hover {
    background: color-mix(in srgb, var(--mud-palette-primary), transparent 88%);
}

.metadata-value-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
}

.metadata-value-tile {
    display: block;
    border-radius: 6px;
    padding: 14px;
    overflow-wrap: anywhere;
}

.metadata-value-tile-shell {
    position: relative;
}

.metadata-value-tile:hover {
    border-color: color-mix(in srgb, var(--mud-palette-primary), transparent 28%);
    transform: translateY(-1px);
}

@media (max-width: 760px) {
    .page-shell {
        padding: 18px;
    }

    /* Narrower keys and a tighter gap: the card grid's 220px minimum still fits beside it on a phone. */
    .browse-body {
        gap: 8px;
    }

    .letter-rail {
        padding: 6px 2px;
    }

    .letter-rail-key {
        width: 20px;
    }

    .reader-stage {
        height: 100vh;
        padding: 0;
    }

    .immersive-reader-header {
        flex-wrap: wrap;
    }

    .reader-title {
        max-width: calc(100vw - 80px);
        flex: 1 1 calc(100vw - 80px);
    }
}

/* API Docs */
.api-code-block {
    background: var(--mud-palette-background-grey);
    border-radius: 4px;
    padding: 12px 16px;
    margin: 4px 0;
    overflow-x: auto;
    font-size: 0.85em;
    line-height: 1.5;
}

.endpoint-path {
    font-size: 0.95em;
    font-weight: 600;
}

.method-chip {
    font-weight: 700;
    letter-spacing: 0.05em;
}

/* ── Theme picker ─────────────────────────────────── */

.theme-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 10px;
}

.recommendation-field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    gap: 2px 12px;
}

.theme-card {
    display: flex;
    flex-direction: column;
    background: var(--mud-palette-surface);
    border: 2px solid var(--mud-palette-divider);
    border-radius: 10px;
    cursor: pointer;
    overflow: hidden;
    transition: border-color 0.15s, box-shadow 0.15s, transform 0.12s;
    text-align: left;
    position: relative;
}

.theme-card:hover {
    border-color: var(--mud-palette-primary);
    box-shadow: 0 4px 16px color-mix(in srgb, var(--mud-palette-primary) 25%, transparent);
    transform: translateY(-2px);
}

.theme-card--active {
    border-color: var(--mud-palette-primary) !important;
    box-shadow: 0 0 0 1px var(--mud-palette-primary), 0 4px 16px color-mix(in srgb, var(--mud-palette-primary) 30%, transparent);
}

.theme-card__colors {
    display: flex;
    height: 56px;
    width: 100%;
}

.theme-card__colors--custom {
    align-items: center;
    justify-content: center;
    background: var(--mud-palette-background);
    color: var(--mud-palette-text-secondary);
    font-size: 24px;
}

.theme-card__col-bg   { flex: 3; height: 100%; }
.theme-card__col-pri  { flex: 2; height: 100%; }
.theme-card__col-sec  { flex: 1; height: 100%; }

.theme-card__body {
    padding: 8px 10px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
}

.theme-card__name {
    font-size: 11px;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}

.theme-card__check {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid var(--mud-palette-divider);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, border-color 0.15s;
    font-size: 10px;
    color: transparent;
}

.theme-card--active .theme-card__check {
    background: var(--mud-palette-primary);
    border-color: var(--mud-palette-primary);
    color: #fff;
}

/* ── Theme card wrapper (saved themes with actions) ─ */

.theme-card-wrapper {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.theme-card-wrapper .theme-card {
    width: 100%;
}

.theme-card-actions {
    display: flex;
    justify-content: center;
    gap: 0;
    opacity: 0;
    transition: opacity 0.15s;
}

.theme-card-wrapper:hover .theme-card-actions {
    opacity: 1;
}

/* ── Theme builder preview ────────────────────────── */

.theme-preview {
    position: relative;
    overflow: hidden;
}

.theme-preview-nav-item {
    padding: 7px 14px;
    font-size: 12px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: default;
    border-radius: 4px;
    margin: 0 4px;
}

.theme-preview-nav-item:hover {
    background: rgba(255, 255, 255, 0.05);
}

.theme-preview-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 5px 14px;
    border-radius: 6px;
    cursor: default;
}

.theme-color-picker .mud-picker-inline-container {
    width: 100% !important;
}

.theme-color-picker {
    width: 100%;
}

/* Story arc issue cards */
.arc-issue-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 16px;
}

.arc-issue-card {
    border: 1px solid transparent !important;
    border-radius: 6px !important;
    overflow: hidden;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease, background-color .15s ease;
}

.arc-issue-card:hover {
    border-color: var(--mud-palette-primary) !important;
    box-shadow: 0 10px 28px rgba(123, 47, 214, .2);
    transform: translateY(-2px);
    background: color-mix(in srgb, var(--mud-palette-primary), var(--mud-palette-surface) 88%) !important;
}

.arc-issue-card-cover {
    position: relative;
    aspect-ratio: 2 / 3;
    display: grid;
    place-items: center;
    background: linear-gradient(150deg, rgba(123, 47, 214, .24), rgba(0, 108, 103, .16));
    border-bottom: 1px solid var(--mud-palette-divider);
    overflow: hidden;
}

.arc-issue-card-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.arc-issue-card-num {
    position: absolute;
    top: 5px;
    left: 6px;
    font-size: 11px;
    font-weight: 700;
    color: #fff;
    background: rgba(0,0,0,.55);
    border-radius: 4px;
    padding: 1px 5px;
    line-height: 1.5;
}


.arc-issue-card-body {
    padding: 8px 12px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* 8px either side, which is MudBlazor's my-2 -- the spacing the Home cards give the same bar. */
.arc-issue-card-progress {
    margin: 8px 0 !important;
}

.arc-issue-card-link-wrap {
    display: block;
    height: 100%;
    text-decoration: none;
    color: inherit;
}

/*
    The menu sits beside the caption line, not over the progress bar -- the same order the Home cards use,
    where the bar runs full width and the short "Page 3 of 28" line shares its row with the menu. Only the
    caption needs to keep clear of it: .card-menu pins 4px from the corner and a MudBlazor icon button is a
    24px icon in 6px of padding, so it occupies roughly 4-40px from the edge. Scoped to the shell because the
    unmatched cards have no menu and no progress bar.
*/
.arc-issue-card-shell .arc-issue-card-meta {
    padding-right: 36px;
}

.arc-issue-card-unmatched {
    font-size: 10px;
    color: var(--mud-palette-text-secondary);
}

.arc-issue-card-unmatched-item {
    opacity: 0.45;
    filter: grayscale(0.6);
}


.plugin-upload {
    border: 1px dashed color-mix(in srgb, var(--mud-palette-primary), transparent 50%);
}

.plugin-upload-text {
    flex: 1 1 420px;
    min-width: 0;
}

.plugin-upload-list {
    margin: 8px 0 0 18px;
    padding: 0;
    font-size: 0.875rem;
    line-height: 1.6;
}
