:root {
    --ink: #1b1b1b;
    --muted: #6b6b6b;
    --bg: #ffffff;
    --accent: #2c5f6f;
    --border: #e3e3e3;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: var(--ink);
    background: var(--bg);
}

.page { position: relative; display: flex; flex-direction: column; min-height: 100vh; }

/* Non-scrolling, single-viewport home page while a hero slideshow is showing.
   Pure CSS (":has") so it follows whatever page is actually on screen - it
   used to be a flag MainLayout set once at startup, which stayed stuck on
   after leaving the front page and took the scrollbar off every other page.
   Caps .page at exactly 100vh and hides the footer; .content (flex:1 below)
   stretches to fill whatever the header doesn't take, and the hero
   slideshow stretches to fill .content in turn. */
.page:has(.hero-slideshow) { height: 100vh; overflow: hidden; }
.page:has(.hero-slideshow) .site-footer { display: none; }
.page:has(.hero-slideshow) .content {
    padding: 0;
    max-width: none;
    margin: 0;
    display: flex;
    flex-direction: column;
}
.page:has(.hero-slideshow) .hero-slideshow {
    flex: 1;
    height: auto;
    min-height: 0;
    max-height: none;
    margin-bottom: 0;
}

.breadcrumb {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.15rem;
    font-size: 0.85rem;
    margin-bottom: 1rem;
    color: var(--muted);
}
.bc-item { color: var(--muted); text-decoration: none; }
.bc-item:hover { color: var(--accent); }
.bc-current { color: var(--ink); }
.bc-sep { color: var(--muted); padding: 0 0.1rem; }

.site-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 2rem;
    border-bottom: 1px solid var(--border);
}

.brand { font-size: 1.25rem; font-weight: 600; color: var(--ink); text-decoration: none; }
.brand-sub { font-size: 0.75rem; color: var(--muted); font-weight: 400; }

/* Uploaded logo (SiteSettings.LogoPath) in place of the text brand. Height
   comes from SiteSettings.LogoHeight as an inline style. */
.brand--logo { display: inline-flex; align-items: center; line-height: 0; }
.brand-logo { display: block; width: auto; max-width: min(60vw, 420px); object-fit: contain; }
.page:has(.hero-slideshow--flush-top) .site-header .brand-logo { filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.5)); }

/* Admin: Branding & SEO block (Components/Shared/BrandingSeoSettings.razor) */
.field-help { font-size: 0.8rem; color: var(--muted); margin: 0.3rem 0 0; }
.field-help--warn { color: #8a5a00; }
.branding-preview {
    margin: 0.4rem 0;
    padding: 0.75rem;
    border: 1px dashed var(--border);
    border-radius: 6px;
    background: repeating-conic-gradient(#f2f2f2 0% 25%, #ffffff 0% 50%) 50% / 16px 16px;
}
.branding-preview--logo { background-color: #444; background-image: none; }
.branding-preview img { display: block; max-width: 100%; }
form.upload-form .button-secondary {
    margin: 0.25rem 0 0.5rem;
    padding: 0.35rem 0.8rem;
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--border);
}

.site-header nav {
    display: flex;
    align-items: center;
}

.site-header nav a {
    margin-left: 1.25rem;
    color: var(--ink);
    text-decoration: none;
    font-size: 0.95rem;
}
.site-header nav a:hover { color: var(--accent); }

/* "Overlay" header style (SiteSettings.HeaderStyle) - applies only while a
   hero slideshow rendered with FlushTop (Home.razor sets that exactly when
   the Overlay style is chosen) is on the page. Takes the header out of flow
   so the hero slideshow below fills the space it would have used. */
.page:has(.hero-slideshow--flush-top) .site-header {
    position: absolute;
    top: 0; left: 0; right: 0;
    z-index: 20;
    background: transparent;
    border-bottom: none;
}
.page:has(.hero-slideshow--flush-top) .site-header .brand,
.page:has(.hero-slideshow--flush-top) .site-header .brand-sub,
.page:has(.hero-slideshow--flush-top) .site-header nav a,
.page:has(.hero-slideshow--flush-top) .site-header .link-button {
    color: #fff;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.65);
}
.page:has(.hero-slideshow--flush-top) .site-header nav a:hover { opacity: 0.8; }

/* Front-page hero slideshow (SiteSettings.HeroSourceType, rendered by
   Components/Shared/HeroSlideshow.razor) - breaks out of .content's centered
   max-width to span the full viewport width regardless of theme/padding.
   Which slide shows is server-driven (currentIndex -> .active / .previous /
   .enter-next / .enter-prev, see HeroSlideshow.SlideClass), so prev/next/
   pause/swipe just change C# state; the CSS below only animates it. */
.hero-slideshow {
    position: relative;
    left: 50%;
    right: 50%;
    width: 100vw;
    margin-left: -50vw;
    margin-right: -50vw;
    height: 78vh;
    min-height: 420px;
    max-height: 900px;
    overflow: hidden;
    background: #111;
    margin-bottom: 2rem;
    /* Horizontal finger swipes go to the slideshow (next/prev), vertical
       ones still scroll the page. */
    touch-action: pan-y;
}
/* Cancels .content's top padding so the image sits flush at y:0, directly
   behind the transparent overlay header above it. */
.hero-slideshow--flush-top { margin-top: -2rem; }

.hero-slide-link {
    position: absolute;
    inset: 0;
    display: block;
    /* Own stacking context, so the slides' z-indexes below stay inside it
       and the nav/pause buttons (later siblings) always paint on top. */
    z-index: 0;
    -webkit-user-drag: none;
}

/* "Push" transition: the incoming photo (.active) slides in from the right
   edge while the outgoing one (.previous) slides out the left, moving
   together side by side (mirrored when going back).
   Hidden slides use visibility (not display:none) so their background
   images still preload. */
.hero-slide {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    visibility: hidden;
    z-index: 0;
}
.hero-slide.previous { visibility: visible; z-index: 1; }
.hero-slide.active { visibility: visible; z-index: 2; }
.hero-slide.active.enter-next { animation: hero-slide-in-from-right 0.9s cubic-bezier(0.25, 0.8, 0.3, 1) both; }
.hero-slide.active.enter-prev { animation: hero-slide-in-from-left 0.9s cubic-bezier(0.25, 0.8, 0.3, 1) both; }
.hero-slide.previous.exit-next { animation: hero-slide-out-to-left 0.9s cubic-bezier(0.25, 0.8, 0.3, 1) both; }
.hero-slide.previous.exit-prev { animation: hero-slide-out-to-right 0.9s cubic-bezier(0.25, 0.8, 0.3, 1) both; }

@keyframes hero-slide-in-from-right {
    from { transform: translate3d(100%, 0, 0); }
    to   { transform: translate3d(0, 0, 0); }
}
@keyframes hero-slide-in-from-left {
    from { transform: translate3d(-100%, 0, 0); }
    to   { transform: translate3d(0, 0, 0); }
}
@keyframes hero-slide-out-to-left {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-100%, 0, 0); }
}
@keyframes hero-slide-out-to-right {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(100%, 0, 0); }
}
@keyframes hero-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
/* Visitors who've asked their OS for less motion get a gentle fade instead. */
@media (prefers-reduced-motion: reduce) {
    .hero-slide.active.enter-next,
    .hero-slide.active.enter-prev { animation: hero-fade-in 0.6s ease both; }
    .hero-slide.previous.exit-next,
    .hero-slide.previous.exit-prev { animation: none; }
}

/* Prev/next + pause controls - siblings of .hero-slide-link (not nested
   inside it), so clicking a control can't also trigger the click-through
   navigation and vice versa.
   Like Zenfolio, they stay out of the way until the pointer is over the
   slideshow; on touch screens (no hover) they're always shown. */
.hero-nav {
    position: absolute;
    z-index: 5;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    color: #fff;
    border: none;
    font-size: 3.25rem;
    font-weight: 200;
    line-height: 1;
    width: 3rem;
    height: 4rem;
    cursor: pointer;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
    opacity: 0;
    transition: opacity 0.25s ease;
}
.hero-nav:hover { opacity: 1 !important; }
.hero-nav-prev { left: 1rem; }
.hero-nav-next { right: 1rem; }

.hero-pause {
    position: absolute;
    z-index: 5;
    opacity: 0;
    transition: opacity 0.25s ease;
    bottom: 1rem;
    right: 1rem;
    background: rgba(0, 0, 0, 0.35);
    color: #fff;
    border: none;
    font-size: 0.85rem;
    padding: 0.4rem 0.6rem;
    border-radius: 4px;
    cursor: pointer;
}
.hero-pause:hover { background: rgba(0, 0, 0, 0.55); }

.hero-slideshow:hover .hero-nav,
.hero-slideshow:hover .hero-pause,
.hero-nav:focus-visible,
.hero-pause:focus-visible { opacity: 0.85; }
@media (hover: none) {
    .hero-nav, .hero-pause { opacity: 0.85; }
}

.nav-search {
    margin-left: 1.25rem;
    display: inline-flex;
}
.nav-search input[type="search"] {
    width: 10rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.85rem;
    font-family: inherit;
}
.nav-search input[type="search"]:focus {
    outline: none;
    border-color: var(--accent);
}

.search-box {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
    max-width: 32rem;
}
.search-box input[type="search"] {
    flex: 1;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 0.95rem;
    font-family: inherit;
}
.search-box input[type="search"]:focus {
    outline: none;
    border-color: var(--accent);
}
.search-box button {
    padding: 0.5rem 1rem;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: #fff;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.9rem;
}
.search-box button:hover { opacity: 0.9; }

.link-button {
    margin-left: 1.25rem;
    background: none;
    border: none;
    padding: 0;
    color: var(--ink);
    text-decoration: none;
    font-size: 0.95rem;
    font-family: inherit;
    cursor: pointer;
}
.link-button:hover { color: var(--accent); }

.content { flex: 1; padding: 2rem; max-width: 1100px; margin: 0 auto; width: 100%; }

.site-footer {
    padding: 1rem 2rem;
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-size: 0.85rem;
    text-align: center;
}

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

.gallery-card, .image-card, .post-card {
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    text-decoration: none;
    color: var(--ink);
    display: block;
}

.gallery-card img, .image-card img, .post-card img { width: 100%; height: 160px; object-fit: cover; display: block; }

.gallery-card .caption, .post-card .caption { padding: 0.75rem; }
.gallery-card h3, .post-card h3 { margin: 0 0 0.25rem 0; font-size: 1rem; }
.gallery-card p, .post-card p { margin: 0; font-size: 0.85rem; color: var(--muted); }

.image-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1rem;
    margin-top: 1.5rem;
}

.blog-cover {
    width: 100%;
    max-height: 420px;
    object-fit: cover;
    border-radius: 8px;
    margin: 1rem 0;
    display: block;
}

.blog-image-grid { margin-top: 2rem; }
.blog-image { margin: 0; }
.blog-image img {
    width: 100%;
    height: 220px;
    object-fit: cover;
    border-radius: 8px;
    display: block;
    transition: opacity 0.15s ease;
}
.blog-image a { display: block; }
.blog-image a:hover img { opacity: 0.85; }
.blog-image figcaption {
    font-size: 0.85rem;
    color: var(--muted);
    margin-top: 0.35rem;
}

/* --- Lightbox --- */

@keyframes slide-from-right {
    from { transform: translateX(60px); opacity: 0; }
    to   { transform: translateX(0);    opacity: 1; }
}
@keyframes slide-from-left {
    from { transform: translateX(-60px); opacity: 0; }
    to   { transform: translateX(0);     opacity: 1; }
}

.lightbox-img.slide-from-right { animation: slide-from-right 0.25s ease-out; }
.lightbox-img.slide-from-left  { animation: slide-from-left  0.25s ease-out; }

.lightbox-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.92);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.lightbox {
    position: relative;
    display: flex;
    flex-direction: column;
    /* Wide cap (not just a fixed px value) so a wide/panorama photo - which is
       constrained by width long before it hits the 76vh height cap on
       .lightbox-img below - has real room to grow on large screens instead
       of always topping out at a fairly modest fixed width. Normal/portrait
       photos are governed by the height cap instead, so they're unaffected. */
    width: min(1800px, 97vw);
    max-height: 96vh;
    background: var(--card-bg, var(--bg));
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 24px 80px rgba(0,0,0,0.6);
}
/* The lightbox is focused programmatically (tabindex="-1", see GalleryDetail.razor)
   purely so arrow-key/Escape navigation works without an extra click - not a
   "tab stop" a keyboard user would land on, so it doesn't need a focus ring
   for that case. :focus-visible still shows one for real keyboard tabbing. */
.lightbox:focus { outline: none; }
.lightbox:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.lightbox-close {
    position: absolute;
    top: 0.5rem;
    right: 0.75rem;
    background: none;
    border: none;
    color: #fff;
    font-size: 1.6rem;
    cursor: pointer;
    z-index: 10;
    opacity: 0.7;
    line-height: 1;
    text-shadow: 0 1px 4px rgba(0,0,0,0.8);
}
.lightbox-close:hover { opacity: 1; }

.lightbox-body {
    display: flex;
    align-items: center;
    background: #000;
    min-height: 0;
    flex-shrink: 1;
}

.lightbox-image-wrap {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    max-height: 76vh;
}
.lightbox-img {
    max-width: 100%;
    max-height: 76vh;
    object-fit: contain;
    display: block;
}

.lightbox-nav {
    font-size: 3.5rem;
    background: none;
    border: none;
    color: #fff;
    cursor: pointer;
    padding: 0 0.75rem;
    opacity: 0.5;
    line-height: 1;
    flex-shrink: 0;
    transition: opacity 0.15s;
    user-select: none;
}
.lightbox-nav:hover:not(:disabled) { opacity: 1; }
.lightbox-nav:disabled { opacity: 0.12; cursor: default; }

.lightbox-panel {
    position: relative;
    padding: 0.75rem 1.25rem 0.5rem;
    border-top: 1px solid var(--border);
    background: var(--card-bg, var(--bg));
    flex-shrink: 0;
    z-index: 5;
}

/* Photo-info panel: retracted to just the title bar by default, expands on
   hover. No manual toggle - the heading row (title/counter/camera icon)
   always stays visible. .lightbox-panel-extra is pulled OUT of normal flow
   (position: absolute, anchored above the title bar) so opening it never
   resizes/shrinks the image above it - it slides up and overlays the bottom
   of the photo instead. That also means its height is capped independently
   of document flow, so a long product list scrolls internally rather than
   growing the panel (and covering more of the image) without bound. On
   touch devices there's no real hover, so the media query below just leaves
   it expanded in normal flow instead of hiding content behind a gesture
   that doesn't discover well. */
.lightbox-panel-extra {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    max-height: 0;
    overflow: hidden;
    padding: 0 1.25rem;
    background: var(--card-bg, var(--bg));
    border-top: 1px solid var(--border);
    box-shadow: 0 -12px 24px -8px rgba(0,0,0,0.35);
    opacity: 0;
    pointer-events: none;
    transition: max-height 0.25s ease, opacity 0.2s ease, padding 0.25s ease;
}

.lightbox-panel:hover .lightbox-panel-extra {
    max-height: min(300px, 42vh);
    overflow-y: auto;
    padding: 0.6rem 1.25rem;
    opacity: 1;
    pointer-events: auto;
}

@media (hover: none) {
    .lightbox-panel-extra {
        position: static;
        max-height: min(300px, 42vh);
        overflow-y: auto;
        padding: 0.6rem 1.25rem;
        opacity: 1;
        pointer-events: auto;
        box-shadow: none;
        border-top: none;
    }
}

.lightbox-panel-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 0.4rem;
}

.lightbox-panel-heading {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.lightbox-title { margin: 0; font-size: 1.05rem; }
.lightbox-counter { color: var(--muted); font-size: 0.8rem; }

/* Camera icon: hovering it reveals the EXIF popover below, no click needed */
.exif-hover-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.exif-toggle-btn {
    display: inline-block;
    padding: 0.1rem 0.2rem;
    font-size: 0.9rem;
    line-height: 1;
    opacity: 0.5;
    border-radius: 4px;
    cursor: default;
    transition: opacity 0.15s, background 0.15s;
}
.exif-hover-wrap:hover .exif-toggle-btn { opacity: 0.9; background: rgba(0,0,0,0.06); }

/* EXIF popover: hidden until the wrapper (icon) is hovered. On touch devices
   there's no real hover, so it's left visible there instead of hiding info
   behind a gesture that doesn't discover well. */
.lightbox-exif {
    position: absolute;
    top: 100%;
    left: 0;
    margin-top: 0.35rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.5rem 0.75rem;
    background: var(--card-bg, var(--bg));
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.25);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-4px);
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 20;
    white-space: nowrap;
}
.exif-hover-wrap:hover .lightbox-exif {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}
@media (hover: none) {
    .lightbox-exif {
        position: static;
        opacity: 1;
        pointer-events: auto;
        transform: none;
        box-shadow: none;
        flex-direction: row;
        flex-wrap: wrap;
        margin: 0.35rem 0 0;
    }
}

.exif-item {
    font-size: 0.8rem;
    color: var(--muted);
    white-space: nowrap;
}
.exif-icon { margin-right: 0.2rem; }

/* Hint that hovering the panel reveals pricing/downloads - sits in the
   always-visible title bar (unlike the content it's pointing at), since that
   content is otherwise hidden with no other clue it exists. The gentle
   bounce on the chevron is there for the same reason: nothing else about a
   plain title bar suggests "there's more below if you linger here." Not
   shown on touch devices (see media query) since there the purchase panel
   is just always open already - the hint would be pointing at nothing. */
.lightbox-buy-hint {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.72rem;
    color: var(--muted);
    padding: 0.15rem 0.55rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    cursor: default;
    user-select: none;
    white-space: nowrap;
}
.lightbox-buy-hint-icon { font-size: 0.8rem; }
.lightbox-buy-hint-chevron {
    display: inline-block;
    font-size: 0.6rem;
    animation: buy-hint-bounce 1.6s ease-in-out infinite;
}
@keyframes buy-hint-bounce {
    0%, 100% { transform: translateY(0);    opacity: 0.5; }
    50%      { transform: translateY(-3px); opacity: 1;   }
}
@media (hover: none) {
    .lightbox-buy-hint { display: none; }
}

/* Keyword tags */
.lightbox-keywords {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin: 0.35rem 0;
}
.keyword-tag {
    font-size: 0.75rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    background: #eef3f4;
    color: var(--accent);
    text-decoration: none;
    transition: background 0.15s;
}
a.keyword-tag:hover { background: var(--accent); color: #fff; }

/* gallery page inline editing */
.editable-heading, .editable-desc {
    cursor: pointer;
    border-radius: 4px;
    transition: background 0.15s;
}
.editable-heading:hover, .editable-desc:hover { background: rgba(0,0,0,0.04); }
.editable-desc--empty { color: var(--muted); font-style: italic; }

.gallery-heading-edit {
    font-size: 2rem;
    font-weight: 700;
    font-family: inherit;
    border: none;
    border-bottom: 2px solid var(--accent);
    background: transparent;
    color: var(--ink);
    width: 100%;
    outline: none;
    padding: 0;
    margin-bottom: 0.5rem;
}
.gallery-desc-edit {
    font-size: 1rem;
    font-family: inherit;
    border: 1px solid var(--accent);
    border-radius: 4px;
    background: transparent;
    color: var(--ink);
    width: 100%;
    outline: none;
    padding: 0.4rem 0.5rem;
    resize: vertical;
    margin-bottom: 0.5rem;
}

/* editable title */
.lightbox-title.editable { cursor: pointer; }
.lightbox-title.editable:hover { text-decoration: underline; text-underline-offset: 3px; }
.lightbox-caption {
    margin: 0.1rem 0 0.25rem;
    font-size: 0.85rem;
    color: var(--muted);
    cursor: default;
}
.lightbox-caption.editable { cursor: pointer; }
.lightbox-caption.editable:hover { text-decoration: underline; text-underline-offset: 3px; }
.lightbox-caption--empty { font-style: italic; opacity: 0.6; }
.lightbox-caption-edit {
    display: block;
    font-size: 0.85rem;
    font-family: inherit;
    color: var(--muted);
    border: none;
    border-bottom: 1px solid var(--accent);
    background: transparent;
    width: 100%;
    outline: none;
    padding: 0;
    margin: 0.1rem 0 0.25rem;
}

.lightbox-title-edit {
    font-size: 1.05rem;
    font-weight: 600;
    font-family: inherit;
    border: none;
    border-bottom: 2px solid var(--accent);
    background: transparent;
    color: var(--ink);
    padding: 0 0.1rem;
    width: 100%;
    outline: none;
    margin-bottom: 0.15rem;
}

/* editable keyword tags (admin) */
.keyword-tag--edit {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    font-size: 0.75rem;
    padding: 0.1rem 0.35rem 0.1rem 0.5rem;
    border-radius: 999px;
    background: #eef3f4;
}
.keyword-tag-link { color: var(--accent); text-decoration: none; }
.keyword-tag-link:hover { text-decoration: underline; }
.keyword-remove-btn {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--muted);
    font-size: 0.7rem;
    line-height: 1;
}
.keyword-remove-btn:hover { color: #c0392b; }

/* add tag input */
.keyword-add-wrap { display: inline-flex; align-items: center; gap: 0.2rem; }
.keyword-add-input {
    font-size: 0.75rem;
    padding: 0.1rem 0.4rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    width: 90px;
    outline: none;
    font-family: inherit;
    background: transparent;
    color: var(--ink);
}
.keyword-add-input:focus { border-color: var(--accent); }
.keyword-add-btn {
    background: none;
    border: 1px solid var(--border);
    border-radius: 999px;
    width: 1.4rem;
    height: 1.4rem;
    cursor: pointer;
    font-size: 0.9rem;
    line-height: 1;
    color: var(--accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.keyword-add-btn:hover { background: var(--accent); color: #fff; border-color: var(--accent); }

.lightbox-actions { margin-top: 0.4rem; }

/* Thumbnail strip */
.lightbox-thumbstrip {
    display: flex;
    gap: 0.35rem;
    padding: 0.5rem 1rem;
    overflow-x: auto;
    background: rgba(0,0,0,0.15);
    border-top: 1px solid var(--border);
    flex-shrink: 0;
    scrollbar-width: thin;
}
.lbstrip-thumb {
    width: 60px;
    height: 44px;
    object-fit: cover;
    border-radius: 3px;
    cursor: pointer;
    opacity: 0.55;
    border: 2px solid transparent;
    flex-shrink: 0;
    transition: opacity 0.15s;
}
.lbstrip-thumb:hover { opacity: 0.85; }
.lbstrip-thumb.active { opacity: 1; border-color: var(--accent); }

/* --- Gallery layout variants --- */

/* Masonry: CSS multi-column */
.image-grid--masonry {
    columns: 3 220px;
    column-gap: 1rem;
    display: block; /* override grid */
}
.image-grid--masonry .image-card {
    break-inside: avoid;
    margin-bottom: 1rem;
    display: block;
}
.image-grid--masonry .image-card img {
    height: auto; /* let natural height show */
}

/* Justified: rows where images share a fixed row height */
.image-grid--justified {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: flex-start;
}
.image-grid--justified .image-card {
    flex: 1 1 220px;
    max-width: 400px;
}
.image-grid--justified .image-card img {
    height: 200px;
    object-fit: cover;
    width: 100%;
}

/* Slideshow */
.image-grid--slideshow {
    display: block;
}
.slideshow-wrapper {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.slideshow-image-wrap {
    flex: 1;
    text-align: center;
}
.slideshow-image-wrap img {
    max-width: 100%;
    max-height: 70vh;
    object-fit: contain;
    border-radius: 4px;
}
.slideshow-caption {
    margin-top: 0.5rem;
    text-align: left;
    padding: 0 0.5rem;
}
.slideshow-nav {
    font-size: 2.5rem;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--accent);
    padding: 0 0.5rem;
    line-height: 1;
}
.slideshow-nav:disabled { opacity: 0.2; cursor: default; }
.slideshow-counter {
    text-align: center;
    color: var(--muted);
    font-size: 0.85rem;
    margin: 0.5rem 0;
}
.slideshow-thumbs {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
}
.slideshow-thumb {
    width: 72px;
    height: 52px;
    object-fit: cover;
    cursor: pointer;
    border: 2px solid transparent;
    border-radius: 3px;
    opacity: 0.7;
    transition: opacity 0.15s;
}
.slideshow-thumb:hover { opacity: 1; }
.slideshow-thumb.active { border-color: var(--accent); opacity: 1; }

.badge {
    display: inline-block;
    font-size: 0.75rem;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: #eef3f4;
    color: var(--accent);
    margin-right: 0.4rem;
}
/* Galleries page, admin only: marks galleries visitors can't see in the list. */
.badge--hidden { background: #fdf3e0; color: #8a5a00; }
.admin-only-note {
    font-size: 0.88rem;
    padding: 0.6rem 0.8rem;
    border-radius: 8px;
    border: 1px dashed var(--border);
    color: var(--muted);
}

/* Photo count / view count line under a gallery's badges (GalleryDetail.razor)
   and admin Galleries.razor's equivalent - deliberately understated, same
   treatment as the lightbox/slideshow counters. */
.gallery-stats { color: var(--muted); font-size: 0.8rem; margin-top: -0.5rem; }

/* Grid pagination controls (GalleryDetail.razor) - Grid/Masonry/Justified
   layouts only, below the image grid. */
.gallery-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin: 1.5rem 0;
}
.gallery-pagination button {
    background: none;
    border: 1px solid #ddd;
    border-radius: 6px;
    padding: 0.4rem 0.9rem;
    cursor: pointer;
    color: var(--accent);
    font-size: 0.9rem;
}
.gallery-pagination button:hover:not(:disabled) { background: #f5f5f5; }
.gallery-pagination button:disabled { opacity: 0.35; cursor: default; }
.gallery-pagination-status { color: var(--muted); font-size: 0.85rem; }

form.upload-form { max-width: 480px; }
form.upload-form label { display: block; margin-top: 1rem; font-weight: 600; }
form.upload-form select, form.upload-form input { width: 100%; padding: 0.5rem; margin-top: 0.25rem; }
form.upload-form button { margin-top: 1.25rem; padding: 0.6rem 1.2rem; background: var(--accent); color: white; border: none; border-radius: 6px; cursor: pointer; }

.status-message { margin-top: 1rem; padding: 0.75rem; border-radius: 6px; background: #eef7ee; color: #2a662a; }

/* Partial-failure variant (e.g. some uploaded files failed to process) - same
   shape as .status-message, amber instead of green so it reads as "needs a
   look" without being as alarming as a full error. */
.status-message--warning { background: #fdf3e0; color: #8a5a00; }

/* Toast: self-dismisses (see GalleryDetail.razor's ShowToast/DismissToastAfterDelay
   timer), so the animation's fade-out just needs to roughly track that same
   ~2.5s window - no close button, nothing to click. Fixed above the lightbox
   backdrop (z-index 1000) since "Add to Cart" is most often clicked from there. */
@keyframes toast-in-out {
    0%   { opacity: 0; transform: translateY(12px); }
    8%   { opacity: 1; transform: translateY(0); }
    85%  { opacity: 1; transform: translateY(0); }
    100% { opacity: 0; transform: translateY(-6px); }
}
.toast-notification {
    position: fixed;
    bottom: 1.5rem;
    right: 1.5rem;
    max-width: 320px;
    padding: 0.75rem 1.1rem;
    background: #2a662a;
    color: #fff;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.3);
    font-size: 0.9rem;
    z-index: 2000;
    pointer-events: none;
    animation: toast-in-out 2.5s ease forwards;
}

.download-links-box {
    margin-top: 1.5rem;
    padding: 1rem 1.25rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg, var(--bg));
}
.download-links-box ul { margin: 0.25rem 0; }
.download-links-box li { margin-bottom: 0.3rem; }

.btn-danger {
    padding: 0.3rem 0.75rem;
    background: #c0392b;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.85rem;
}
.btn-danger:hover { background: #a93226; }

/* Gallery cover picking (Gallery.CoverImageId) - lightbox admin button and
   the "Cover" column in the admin gallery image tables. */
.btn-secondary {
    padding: 0.3rem 0.75rem;
    margin-right: 0.4rem;
    background: transparent;
    color: inherit;
    border: 1px solid currentColor;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.85rem;
    opacity: 0.85;
}
.btn-secondary:hover { opacity: 1; }
.cover-badge { margin-right: 0.6rem; font-size: 0.85rem; color: #d4a017; white-space: nowrap; }
.cover-cell { text-align: center; white-space: nowrap; }
.cover-cell input[type="radio"] { width: auto; cursor: pointer; transform: scale(1.2); }
.cover-cell .cover-default { display: block; font-size: 0.7rem; color: var(--muted); }
.cover-reset { font-size: 0.85rem; margin: 0.25rem 0 0.75rem; }
.cover-reset button { background: none; border: none; padding: 0; color: var(--accent); text-decoration: underline; cursor: pointer; font-size: inherit; }

/* ── Admin tabs ──────────────────────────────────── */
.admin-tabs {
    display: flex;
    gap: 0.1rem;
    border-bottom: 2px solid var(--border);
    margin-bottom: 1.5rem;
}
.admin-tab {
    padding: 0.5rem 1.2rem;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    cursor: pointer;
    font-size: 0.95rem;
    color: var(--muted);
    font-family: inherit;
    transition: color 0.15s;
}
.admin-tab:hover { color: var(--ink); }
.admin-tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
    font-weight: 600;
}
.admin-tab-panel { min-height: 200px; }

.create-gallery-details summary {
    cursor: pointer;
    color: var(--accent);
    font-weight: 600;
    font-size: 0.95rem;
    user-select: none;
    list-style: none;
}
.create-gallery-details summary::marker,
.create-gallery-details summary::-webkit-details-marker { display: none; }
.create-gallery-details[open] summary { margin-bottom: 0.75rem; }
.create-gallery-form {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.5rem 1rem;
    align-items: center;
    max-width: 520px;
}
.create-gallery-form label { font-weight: 600; font-size: 0.9rem; white-space: nowrap; }
.create-gallery-form input,
.create-gallery-form select { padding: 0.4rem 0.6rem; width: 100%; }
.create-gallery-form button {
    grid-column: 2;
    padding: 0.5rem 1rem;
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.9rem;
    width: fit-content;
}
.create-gallery-form button:disabled { opacity: 0.5; cursor: default; }

.admin-table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
.admin-table th, .admin-table td { text-align: left; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); vertical-align: middle; }
.admin-table th { font-size: 0.8rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em; }
.admin-table button { margin-right: 0.4rem; padding: 0.3rem 0.6rem; cursor: pointer; }


/* ══════════════════════════════════════════════════════════════════════
   Admin area (/admin/*) - MainLayout adds .content--admin and the side
   menu (Layout/AdminNav.razor). Everything below is scoped to it, and
   mostly wrapped in :where() so any page's own classes/inline styles still
   win. Colours come from the theme variables, so it reads well on every
   theme, dark included.
   ══════════════════════════════════════════════════════════════════════ */
.content--admin {
    --card-bg-fallback: var(--card-bg, var(--bg));
    --field-bg: var(--card-bg, var(--bg));
    max-width: 1320px;
    padding: 1.5rem 2rem 3rem;
    line-height: 1.5;
}

.admin-shell {
    display: grid;
    grid-template-columns: 200px minmax(0, 1fr);
    gap: 2.25rem;
    align-items: start;
}
.admin-main { min-width: 0; overflow-x: auto; }

/* Side menu */
.admin-nav {
    position: sticky;
    top: 1rem;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
    padding: 1rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--card-bg-fallback);
    font-size: 0.92rem;
}
.admin-nav-group { display: flex; flex-direction: column; gap: 0.1rem; }
.admin-nav-heading {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
    padding: 0 0.6rem 0.3rem;
}
.admin-nav-link {
    display: block;
    padding: 0.4rem 0.6rem;
    border-radius: 6px;
    color: var(--ink);
    text-decoration: none;
}
.admin-nav-link:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.admin-nav-link.active {
    background: color-mix(in srgb, var(--accent) 20%, transparent);
    color: var(--accent);
    font-weight: 600;
}

/* Headings and the intro text under each page title */
:where(.content--admin) h1 { font-size: 1.7rem; margin: 0 0 0.4rem; letter-spacing: -0.01em; }
:where(.content--admin) h1 + p {
    color: var(--muted);
    font-size: 0.92rem;
    max-width: 72ch;
    margin: 0 0 1.75rem;
}
:where(.content--admin) h2 { font-size: 1.3rem; margin: 2.25rem 0 0.75rem; }
:where(.content--admin) h3 { font-size: 1.1rem; margin: 1.75rem 0 0.6rem; }
:where(.content--admin) h4 { font-size: 0.95rem; margin: 1.5rem 0 0.6rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); }
:where(.content--admin) hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; }
:where(.content--admin) a { color: var(--accent); }
:where(.content--admin) code {
    font-size: 0.85em;
    padding: 0.1em 0.35em;
    border-radius: 4px;
    background: color-mix(in srgb, var(--ink) 8%, transparent);
}

/* Form fields: themed, readable, consistent size */
:where(.content--admin) :is(input:not([type="checkbox"], [type="radio"], [type="file"], [type="range"], [type="color"]), select, textarea) {
    font: inherit;
    font-size: 0.92rem;
    color: var(--ink);
    background-color: var(--field-bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.45rem 0.65rem;
    max-width: 100%;
    transition: border-color 0.15s, box-shadow 0.15s;
}
:where(.content--admin) select { min-width: 14rem; cursor: pointer; }
:where(.content--admin) :is(input, select, textarea):hover:not(:disabled) { border-color: color-mix(in srgb, var(--accent) 50%, var(--border)); }
:where(.content--admin) :is(input, select, textarea, button):focus-visible {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent);
}
:where(.content--admin) input[type="file"] { font-size: 0.88rem; color: var(--muted); }
:where(.content--admin) input[type="file"]::file-selector-button {
    font: inherit;
    margin-right: 0.75rem;
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--field-bg);
    color: var(--ink);
    cursor: pointer;
}
:where(.content--admin) :is(input[type="checkbox"], input[type="radio"]) {
    accent-color: var(--accent);
    width: 1.05rem;
    height: 1.05rem;
    margin: 0;
    cursor: pointer;
    flex: none;
}

/* Labels: field labels sit above their field; checkbox labels stay inline */
:where(.content--admin) label { font-weight: 600; font-size: 0.86rem; }
:where(.content--admin) label:not(:has(input, select, textarea)) {
    display: block;
    margin-bottom: 0.3rem;
}
:where(.content--admin) label:has(> input[type="checkbox"], > input[type="radio"]) {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
}

/* Buttons without their own class: quiet secondary style. Primary (submit)
   buttons in .upload-form / .create-gallery-form keep their accent colour. */
:where(.content--admin) button:not([class]) {
    font: inherit;
    font-size: 0.88rem;
    padding: 0.4rem 0.85rem;
    color: var(--ink);
    background: var(--field-bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
:where(.content--admin) button:not([class]):hover:not(:disabled) {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 10%, var(--field-bg));
}
:where(.content--admin) button[type="submit"]:not([class]) {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
:where(.content--admin) button:not([class]):hover:not(:disabled)[type="submit"] { filter: brightness(1.1); background: var(--accent); }
:where(.content--admin) button:disabled { opacity: 0.45; cursor: not-allowed; }
.content--admin .btn-danger { border-radius: 6px; padding: 0.4rem 0.85rem; font-size: 0.85rem; }

/* Pages lay out settings as inline-styled flex rows of <div><label/><field/></div>;
   give those a little more room and keep each field from collapsing. */
:where(.content--admin) div[style*="display:flex"] > div { min-width: 12rem; }
:where(.content--admin) form.upload-form { max-width: 560px; }
:where(.content--admin) form.upload-form label:not(:has(input)) { margin-top: 1.1rem; }

/* Tables: roomier rows, subtle header, row hover; scroll sideways if wide */
.content--admin .admin-table {
    border: 1px solid var(--border);
    border-radius: 8px;
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
    font-size: 0.9rem;
}
.content--admin .admin-table th {
    background: color-mix(in srgb, var(--ink) 5%, transparent);
    padding: 0.6rem 0.8rem;
}
.content--admin .admin-table td { padding: 0.6rem 0.8rem; }
.content--admin .admin-table tbody tr:last-child td { border-bottom: none; }
.content--admin .admin-table tbody tr:hover td { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.content--admin .admin-table img { border-radius: 4px; display: block; }

/* Photo grids (collections, blog images): card per photo, smaller thumbs */
.content--admin .image-grid {
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 0.9rem;
    margin-top: 0.75rem;
}
.content--admin .blog-image {
    display: flex;
    flex-direction: column;
    padding: 0.5rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg-fallback);
}
.content--admin .blog-image img { height: 140px; border-radius: 5px; }
.content--admin .blog-image p { line-height: 1.35; }
.content--admin .blog-image > div:last-child { margin-top: auto !important; padding-top: 0.4rem; }

/* "+ New ..." expanders and status messages */
.content--admin .create-gallery-details {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.75rem 1rem;
    background: var(--card-bg-fallback);
}
.content--admin .create-gallery-details[open] summary { margin-bottom: 1rem; }
.content--admin .status-message { border-radius: 8px; font-size: 0.9rem; }

/* Dashboard tabs: wrap instead of overflowing on narrow screens */
.content--admin .admin-tabs { flex-wrap: wrap; }

/* Narrow screens: side menu becomes a scrollable strip above the page */
@media (max-width: 860px) {
    .content--admin { padding: 1rem; }
    .admin-shell { grid-template-columns: minmax(0, 1fr); gap: 1.25rem; }
    .admin-nav {
        position: static;
        flex-direction: row;
        overflow-x: auto;
        gap: 0.75rem;
        padding: 0.5rem;
    }
    .admin-nav-group { flex-direction: row; align-items: center; }
    .admin-nav-heading { display: none; }
    .admin-nav-link { white-space: nowrap; }
    :where(.content--admin) select { min-width: 0; width: 100%; }
}

/* Per-photo "Remove" buttons in admin photo grids: outlined, so a row of
   them doesn't shout; fills red on hover. */
.content--admin .blog-image .btn-danger {
    background: transparent;
    color: #e0675a;
    border: 1px solid currentColor;
}
.content--admin .blog-image .btn-danger:hover { background: #c0392b; border-color: #c0392b; color: #fff; }

/* Small screens: let the top bar wrap onto two lines instead of running
   off the right edge (which also gave every page a sideways scroll). */
@media (max-width: 700px) {
    .site-header { flex-wrap: wrap; gap: 0.5rem 1rem; padding: 0.75rem 1rem; }
    .site-header nav { flex-wrap: wrap; gap: 0.4rem 1rem; }
    .site-header nav a, .site-header .link-button, .nav-search { margin-left: 0; }
    .nav-search input[type="search"] { width: 8rem; }
}

/* Theme chooser (Components/Shared/ThemePicker.razor): a mini mock-up of the
   site per theme. ".theme-picker .theme-card" (two classes) so it beats
   "form.upload-form button", which would otherwise paint these as accent-
   coloured submit buttons. */
.theme-picker {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 0.75rem;
    margin-top: 0.4rem;
}
.theme-picker .theme-card {
    position: relative;
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    text-align: left;
    font: inherit;
    color: var(--ink);
    background: var(--card-bg, var(--bg));
    border: 2px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
    cursor: pointer;
    transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.theme-picker .theme-card:hover { border-color: color-mix(in srgb, var(--accent) 60%, var(--border)); transform: translateY(-2px); }
.theme-picker .theme-card--selected {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}
.theme-card-preview { height: 112px; overflow: hidden; font-size: 9px; line-height: 1.3; pointer-events: none; }
.tc-header { display: flex; justify-content: space-between; align-items: center; padding: 6px 8px; }
.tc-brand { font-weight: 700; font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 60%; }
.tc-nav { opacity: 0.8; white-space: nowrap; }
.tc-body { padding: 6px 8px; }
.tc-title { font-weight: 700; font-size: 10px; margin-bottom: 4px; }
.tc-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.tc-card { display: block; border: 1px solid; border-radius: 3px; overflow: hidden; }
.tc-photo { display: block; height: 26px; }
.tc-photo--0 { background: linear-gradient(160deg, #e9a87c 0%, #b56a7a 45%, #4d4a6b 100%); }
.tc-photo--1 { background: linear-gradient(160deg, #8fb3d9 0%, #6b7f99 50%, #c79a4b 100%); }
.tc-photo--2 { background: linear-gradient(160deg, #cfd8dc 0%, #90a4ae 50%, #455a64 100%); }
.tc-line { display: block; height: 3px; width: 70%; margin: 3px 4px 4px; border-radius: 2px; opacity: 0.6; }
.tc-link { margin-top: 5px; font-weight: 600; }
.theme-card-label { display: flex; flex-direction: column; gap: 1px; padding: 0.45rem 2rem 0.55rem 0.6rem; font-size: 0.82rem; border-top: 1px solid var(--border); }
.theme-card-label span { color: var(--muted); font-size: 0.75rem; line-height: 1.3; }
.theme-card-check {
    position: absolute;
    bottom: 10px;
    right: 8px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-size: 12px;
    line-height: 20px;
    text-align: center;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.theme-picker-note { font-size: 0.85rem; color: var(--accent); margin: 0.5rem 0 0; }
/* The settings form is narrow by default - give the picker room for all five. */
:where(.content--admin) form.upload-form:has(.theme-picker) { max-width: 880px; }

/* /admin/backups status card (Components/Pages/Admin/Backups.razor) */
.backup-status {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 1rem 1.25rem;
    margin: 0 0 1rem;
    border: 1px solid var(--border);
    border-left-width: 5px;
    border-radius: 10px;
    background: var(--card-bg, var(--bg));
}
.backup-status--ok   { border-left-color: #3c9a5f; }
.backup-status--warn { border-left-color: #d4a017; }
.backup-status--bad  { border-left-color: #c0392b; }
.backup-status-title { font-weight: 700; font-size: 1.1rem; }
.backup-status-detail { color: var(--muted); font-size: 0.88rem; margin-top: 0.2rem; }
.backup-status-error { color: #e0675a; font-size: 0.88rem; margin-top: 0.4rem; }
.backup-now {
    padding: 0.55rem 1.1rem;
    border: none;
    border-radius: 6px;
    background: var(--accent);
    color: #fff;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.backup-now:disabled { opacity: 0.6; cursor: wait; }
.backup-restore { padding-left: 1.25rem; max-width: 72ch; }
.backup-restore li { margin-bottom: 0.4rem; }
