/* =========================================================
   NovelSite — "Reading Room After Midnight"
   A dim, lamplit reading-room theme: deep ink surfaces, warm
   gold for actions and coins, rose for hearts and highlights.
   Signature device: a folded dog-ear corner + colored "spine"
   edge on every novel cover, and ribbon-shaped tags for badges.
   ========================================================= */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,600;0,9..144,700;1,9..144,500&family=Manrope:wght@400;500;600;700;800&display=swap');

:root {
    /* Ink & surfaces */
    --dark: #15121F;
    --bg: #1B1730;
    --card-bg: #241F3B;
    --card-bg-2: #2C2648;
    --border: #362F52;

    /* Text */
    --text: #F1ECE4;
    --muted: #A79FC0;

    /* Accents */
    --primary: #E8607C;   /* rose — CTAs, likes, premium */
    --gold: #E8A33D;      /* lamplight gold — coins, ratings, signature */
    --success-text: #6FC495;
    --success-bg: rgba(111, 196, 149, 0.14);
    --error-text: #FF8A93;
    --error-bg: rgba(232, 96, 107, 0.14);

    /* Type */
    --font-display: 'Fraunces', Georgia, serif;
    --font-body: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

    /* Admin panel — compact, data-dense design tokens */
    --admin-radius: 8px;
    --admin-radius-sm: 5px;
    --admin-gap: 10px;
    --admin-pad-x: 10px;
    --admin-pad-y: 7px;
    --admin-font-size: 12.5px;
    --admin-shadow: 0 1px 2px rgba(0,0,0,0.25);
    --admin-shadow-raised: 0 4px 16px rgba(0,0,0,0.35);
}

/* ---------------------------------------------------------
   Site-wide Day/Night mode — dark ("Reading Room After
   Midnight") is the default signature look; this is the
   alternative a visitor can switch to, applied via a class on
   <body> so every existing component automatically re-themes
   through the same CSS variables it already uses.
   --------------------------------------------------------- */
body.light-mode {
    --dark: #2B2B3A;
    --bg: #FAF7F1;
    --card-bg: #FFFFFF;
    --card-bg-2: #F5F1E8;
    --border: #E0DCD0;
    --text: #2B2620;
    --muted: #6B6478;
    --gold: #C6841F;
    --success-text: #2F8F5C;
    --success-bg: rgba(47, 143, 92, 0.1);
    --error-text: #C6303B;
    --error-bg: rgba(198, 48, 59, 0.08);
}

/* Header and footer specifically keep their dark-mode look even
   while the rest of the site is in light mode — but only on
   mobile, where this was asked for; desktop's light mode is
   unaffected, and dark mode itself is unaffected everywhere, since
   this only ever overrides the LIGHT-mode variable values. Every
   button and link inside these two elements already colors itself
   via these same var() names, so re-declaring the values here is
   all that's needed — nothing about the buttons/links themselves
   has to change. */
@media (max-width: 780px) {
    body.light-mode .site-header,
    body.light-mode .site-footer {
        --dark: #15121F;
        --bg: #1B1730;
        --card-bg: #241F3B;
        --card-bg-2: #2C2648;
        --border: #362F52;
        --text: #F1ECE4;
        --muted: #A79FC0;
        --gold: #E8A33D;
        --success-text: #6FC495;
        --success-bg: rgba(111, 196, 149, 0.14);
        --error-text: #FF8A93;
        --error-bg: rgba(232, 96, 107, 0.14);
    }
}

* { box-sizing: border-box; margin: 0; padding: 0; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}

html {
    /* overflow-x: hidden was here to fix the back-to-top button
       getting pushed off-screen on mobile — but ANY non-visible
       overflow value on an ancestor also disables position:sticky
       for every descendant, including the site header, which is
       exactly why it stopped sticking on scroll. The original bug's
       actual source (pasted chapter images with no max-width, long
       unbroken words/URLs) was fixed properly at the content level
       since then, so this broad safety net is no longer needed and
       was doing more harm than good. */
    width: 100%;
}

body {
    font-family: var(--font-body);
    background: var(--bg);
    color: var(--text);
    line-height: 1.6;
    width: 100%;
}

a { color: inherit; text-decoration: none; }

.container {
    max-width: 1100px;
    margin: 0 auto;
    padding: 0 20px;
}
/* Admin/author pages need much more horizontal room than the
   reading-focused pages (a sidebar plus wide data tables) — this
   widened container is what actually fixes tables needing to
   scroll sideways on desktop; 1100px total was nowhere near
   enough once a 210px sidebar was subtracted from it. */
.admin-page-container {
    max-width: 1600px;
}

/* ---------------------------------------------------------
   Header
   --------------------------------------------------------- */
.sitewide-banner {
    background: var(--gold);
    color: #1B1730;
    font-size: 13px;
    font-weight: 600;
    text-align: center;
    padding: 9px 20px;
}
.sitewide-banner-inner { max-width: 1100px; margin: 0 auto; }

.site-header {
    background: rgba(21, 18, 31, 0.85);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    color: #fff;
    position: sticky;
    top: 0;
    z-index: 10;
    border-bottom: 1px solid var(--border);
}
.site-header::after {
    content: '';
    position: absolute;
    bottom: -1px;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(232,163,61,0.5), transparent);
}
.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 20px;
    flex-wrap: wrap;
    gap: 10px;
    max-width: 1100px;
    margin: 0 auto;
}
#theme-mode-toggle {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--card-bg);
    border: 1px solid var(--border);
    color: var(--text);
    font-size: 15px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: border-color 0.15s ease, transform 0.15s ease;
}
#theme-mode-toggle:hover { border-color: var(--gold); transform: scale(1.08); }

.logo {
    font-family: var(--font-display);
    font-size: 24px;
    font-weight: 700;
    font-style: italic;
    color: var(--gold);
    text-decoration: none;
    letter-spacing: 0.3px;
    text-shadow: 0 0 20px rgba(232,163,61,0.25);
    flex-shrink: 0;
}
.logo-img { max-height: 40px; display: block; }
.site-header nav { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }

/* Row 2 (desktop only) — Browse/Categories/Advanced Search/
   Pricing/Leaderboard, separated out from the account/status row
   above. The same links stay inside #site-nav for mobile's
   hamburger panel; .nav-primary-link just hides those specific
   duplicates from the desktop row so they don't show twice. */
.site-header nav .nav-primary-link { display: none; }
.site-header nav .mobile-nav-2col { display: none; }
.site-header-row2 {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 24px;
    max-width: 1100px;
    margin: 0 auto;
    padding: 8px 20px;
    border-top: 1px solid rgba(255,255,255,0.08);
    flex-wrap: wrap;
}
.site-header-row2 a { color: #cfc7e0; text-decoration: none; font-size: 13.5px; font-weight: 600; transition: color 0.15s ease; }
.site-header-row2 a:hover { color: var(--gold); }
.site-header nav a {
    color: #d8d3e6;
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    transition: color 0.15s ease;
    position: relative;
}
.site-header nav a:hover { color: var(--gold); }
.coins { color: var(--gold) !important; font-weight: 700; font-size: 14px; text-decoration: none; }
.online-count-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: rgba(111,196,149,0.12);
    border: 1px solid rgba(111,196,149,0.3);
    color: var(--success-text) !important;
    padding: 5px 12px;
    border-radius: 999px;
    font-size: 12.5px !important;
    font-weight: 700 !important;
    text-decoration: none;
    transition: border-color 0.15s ease;
}
.online-count-badge:hover { border-color: var(--success-text); }
.username { color: #fff !important; font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.header-avatar { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; }

.nav-btn {
    padding: 7px 16px;
    border-radius: 6px;
    font-weight: 700 !important;
    font-size: 13px !important;
    color: #fff !important;
    text-decoration: none;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.nav-btn:hover { transform: translateY(-1px); }
.nav-btn-login { background: var(--success-text); color: #0e2116 !important; }
.nav-btn-logout, .nav-btn-signup { background: var(--primary); }
.nav-btn-login:hover { background: #5cb583; box-shadow: 0 4px 14px rgba(111,196,149,0.35); }
.nav-btn-logout:hover, .nav-btn-signup:hover { background: #d94f6a; box-shadow: 0 4px 14px rgba(232,96,124,0.35); }
.nav-btn-gossip { background: var(--gold); color: #1B1730 !important; }
.nav-btn-gossip:hover { background: #f2b457; box-shadow: 0 4px 14px rgba(232,163,61,0.35); }

main { min-height: 70vh; padding: 34px 0; }

h1 { font-family: var(--font-display); font-weight: 700; font-size: 32px; letter-spacing: 0.2px; }
h2 { font-family: var(--font-display); font-weight: 600; font-size: 22px; }

/* ---------------------------------------------------------
   Hero (homepage) — soft atmospheric glow behind the heading
   --------------------------------------------------------- */
.hero {
    padding: 44px 0 8px;
    animation: heroRise 0.6s ease both;
    position: relative;
}
.hero::before {
    content: '';
    position: absolute;
    top: -60px;
    left: -10%;
    width: 480px;
    height: 320px;
    background: radial-gradient(ellipse at center, rgba(232,163,61,0.14), transparent 70%);
    pointer-events: none;
    z-index: -1;
}
@keyframes heroRise {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}
.hero-eyebrow {
    display: inline-block;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--gold);
    margin-bottom: 14px;
}
.hero h1 {
    font-size: 44px;
    line-height: 1.15;
    max-width: 620px;
    margin-bottom: 10px;
}
.hero h1 em { color: var(--primary); font-style: italic; }
.hero-sub {
    color: var(--muted);
    font-size: 16px;
    max-width: 520px;
    margin-bottom: 24px;
}

/* ---------------------------------------------------------
   Novel grid + card (signature: dog-ear fold + spine edge)
   --------------------------------------------------------- */
.novel-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 22px;
    margin-top: 20px;
}
@media (max-width: 780px) {
    /* Horizontal swipe carousel on mobile — desktop keeps the
       normal wrapping grid above untouched. */
    .more-like-this-grid {
        display: flex;
        overflow-x: auto;
        overflow-y: hidden;
        gap: 14px;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 6px;
    }
    .more-like-this-grid .novel-card {
        flex: 0 0 auto;
        width: 130px;
        scroll-snap-align: start;
    }
}
.novel-list-row {
    display: flex;
    align-items: center;
    gap: 14px;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 14px;
    margin-bottom: 8px;
}
.novel-list-thumb {
    width: 50px;
    height: 66px;
    object-fit: cover;
    border-radius: 4px;
    flex-shrink: 0;
}
.novel-list-thumb-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--card-bg-2);
    color: var(--muted);
    font-family: var(--font-display);
    font-size: 20px;
    font-weight: 700;
}
.novel-list-info { flex: 1; min-width: 180px; }
.novel-list-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.novel-card {
    position: relative;
    background: var(--card-bg);
    border-radius: 2px 4px 4px 2px;
    overflow: hidden;
    box-shadow: 0 2px 10px rgba(0,0,0,0.35);
    text-decoration: none;
    color: var(--text);
    display: block;
    transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
    border-left: 4px solid var(--gold);
    /* A thin 1px reveal of the card's own background around the
       cover, so the image reads as gently inset rather than
       flush against the card edges — a soft frame, not a border. */
    padding: 2px 2px 0;
}
.novel-card:nth-child(3n+2) { border-left-color: var(--primary); }
.novel-card:nth-child(3n+3) { border-left-color: #7C9CE0; }
.novel-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 14px 30px rgba(232, 163, 61, 0.22);
}
/* Site logo watermark, bottom-right corner of the cover image
   itself — the actual DOM element (.novel-cover-watermark) is
   inserted by assets/js/cover-watermark.js, not by this rule alone,
   since an <img> can't host a visible ::before/::after and the
   cover's own height varies by its image's aspect ratio (no fixed
   height to position against from CSS alone). This rule only styles
   that inserted element; the JS decides where it goes. */
.novel-cover-wrap {
    position: relative;
    display: block;
    /* Prevents stretching to fill a taller flex row — .novel-detail
       (the individual novel page's hero layout) is display:flex with
       the browser's own default align-items:stretch, and unlike the
       plain <img> this wrapper replaces, a generic <div> DOES stretch
       to match its much-taller sibling (the title/info panel) under
       that default. That left this wrapper far taller than the cover
       image actually visible inside it, which is exactly why the
       watermark — positioned relative to the wrapper's own bottom
       edge — was appearing in the empty stretched space below the
       image instead of on the image itself. align-self overrides
       that default just for this element, keeping it sized to its
       own content (the image) regardless of its neighbor's height. */
    align-self: flex-start;
}
.novel-cover-watermark {
    position: absolute;
    right: 6px;
    bottom: 6px;
    width: 15%;
    max-width: 46px;
    min-width: 22px;
    aspect-ratio: 1 / 1;
    background-image: var(--site-logo-url, none);
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    opacity: 0.5;
    pointer-events: none;
    z-index: 2;
}
.novel-cover {
    position: relative;
    width: 100%;
    /* No forced aspect-ratio here anymore — a square-format cover
       displays square, a horizontal one displays horizontal, each
       at its own actual uploaded shape. The text-only fallback
       below (no image uploaded) is the one case with nothing to
       derive a natural shape from, so it alone keeps a fixed ratio. */
    height: auto;
    background: linear-gradient(135deg, var(--primary), #6B4FA0);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 15px;
    text-align: center;
    padding: 2px;
}
img.novel-cover { display: block; }
div.novel-cover { aspect-ratio: 1/1; }
/* dog-ear fold — the signature */
.novel-cover::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 22px 22px 0;
    border-color: transparent rgba(21,18,31,0.75) transparent transparent;
    filter: drop-shadow(-2px 2px 3px rgba(0,0,0,0.25));
}
.novel-info { padding: 12px 14px; }
.novel-title { font-family: var(--font-display); font-size: 15px; font-weight: 600; margin-bottom: 4px; line-height: 1.3; }
.novel-meta { font-size: 12px; color: var(--muted); }
/* A modest bump over the base .novel-meta size — this is the
   Home › Novel › Chapter breadcrumb line at the top of the chapter
   page, easy to under-read at the smaller default size. */
.chapter-breadcrumb { font-size: 14px; }
/* The "← Novel Title" link back to the novel page, just below the
   breadcrumb — same modest desktop bump, with a further increase on
   mobile specifically, since it's a primary navigation link readers
   tap often and the smaller default size makes it an easy miss to
   tap accurately on a phone screen. */
.chapter-back-to-novel { font-size: 14px; }
.chapter-back-to-novel a { display: inline-block; padding: 2px 0; }
@media (max-width: 780px) {
    .chapter-back-to-novel { font-size: 16px; }
}

/* ---------------------------------------------------------
   Categories
   --------------------------------------------------------- */
.category-grid { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.category-pill {
    position: relative;
    background: var(--card-bg);
    border: 1px solid var(--border);
    padding: 9px 18px 9px 22px;
    border-radius: 3px 14px 14px 3px;
    text-decoration: none;
    color: var(--text);
    font-weight: 600;
    font-size: 13px;
    transition: border-color 0.15s ease, color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.category-pill::before {
    content: '';
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 4px;
    background: var(--gold);
    border-radius: 3px 0 0 3px;
}
.category-pill:hover { border-color: var(--gold); color: var(--gold); transform: translateY(-2px); box-shadow: 0 4px 12px rgba(232,163,61,0.15); }

/* ---------------------------------------------------------
   /categories page — icon-led cards, distinct from the small
   homepage pills above.
   --------------------------------------------------------- */
.category-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 16px;
    margin-top: 20px;
}
.category-icon-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 6px;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 26px 12px 20px;
    text-decoration: none;
    color: var(--text);
    transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.category-icon-card:hover {
    border-color: var(--gold);
    transform: translateY(-4px);
    box-shadow: 0 8px 20px rgba(232,163,61,0.18);
}
.category-icon-card-icon { font-size: 34px; line-height: 1; margin-bottom: 4px; }
.category-icon-card-name { font-weight: 700; font-size: 14.5px; }
.category-icon-card-count { font-size: 12px; color: var(--muted); }

/* ---------------------------------------------------------
   Forms & cards
   --------------------------------------------------------- */
.form-card {
    max-width: 420px;
    margin: 40px auto;
    background: var(--card-bg);
    padding: 30px;
    border-radius: 10px;
    box-shadow: 0 8px 30px rgba(0,0,0,0.35);
    border: 1px solid var(--border);
    border-top: 2px solid var(--gold);
    animation: formCardRise 0.3s ease both;
}

/* Reading Streak / Weekly Goal / Invite Friends / Wallet cards on
   the account page — 2 columns on desktop so they sit side by
   side instead of stacking one under another; back to a single
   column on narrow screens. Cards inside deliberately override
   .form-card's own max-width/auto-margin, which would otherwise
   cap each one at 420px and center it oddly within its grid cell
   instead of filling it. */
.account-stats-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
    margin-top: 20px;
}
.account-stats-grid .form-card {
    max-width: none;
    margin: 0;
}
@media (max-width: 780px) {
    .account-stats-grid { grid-template-columns: 1fr; }
}

.add-novel-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 28px;
    align-items: start;
}
@media (max-width: 800px) {
    .add-novel-grid { grid-template-columns: 1fr; }
}
@keyframes formCardRise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.form-card h1 { font-size: 24px; margin-bottom: 20px; }
.form-group { margin-bottom: 16px; }
.form-group label { display: block; font-size: 13px; font-weight: 700; margin-bottom: 6px; color: var(--muted); }
.form-group input, .form-group select, .form-group textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 14px;
    background: #FAF7F1;
    color: #241F3B;
    font-family: var(--font-body);
}
.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
    outline: 2px solid var(--gold);
    outline-offset: 1px;
}
.btn {
    display: inline-block;
    background: var(--gold);
    color: #1B1730;
    border: none;
    padding: 11px 22px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    text-decoration: none;
    transition: transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
    font-family: var(--font-body);
    box-shadow: 0 2px 8px rgba(232,163,61,0.15);
}
.btn:hover { background: #F2B457; transform: translateY(-1px); box-shadow: 0 6px 16px rgba(232,163,61,0.3); }
.btn:active { transform: translateY(0); }
.error-box {
    background: var(--error-bg);
    color: var(--error-text);
    padding: 10px 14px;
    border-radius: 6px;
    font-size: 13px;
    margin-bottom: 16px;
    border: 1px solid rgba(255,138,147,0.25);
}
.success-box {
    background: var(--success-bg);
    color: var(--success-text);
    padding: 10px 14px;
    border-radius: 6px;
    font-size: 13px;
    margin-bottom: 16px;
    border: 1px solid rgba(111,196,149,0.25);
}

/* ---------------------------------------------------------
   Wallet & Subscription page — summary card + "already
   subscribed" callout, so both read as proper sections instead
   of plain inline text.
   --------------------------------------------------------- */
.wallet-summary-card {
    display: flex;
    gap: 24px;
    flex-wrap: wrap;
    background: linear-gradient(135deg, rgba(232,163,61,0.14), rgba(232,96,124,0.1));
    border: 1px solid rgba(232,163,61,0.3);
    border-radius: 10px;
    padding: 20px 24px;
    margin-top: 16px;
}
.wallet-summary-item { flex: 1; min-width: 180px; }
.wallet-summary-label { display: block; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px; color: var(--muted); margin-bottom: 6px; }
.wallet-summary-value { font-family: var(--font-display); font-size: 22px; font-weight: 700; color: var(--gold); }
.wallet-summary-unit { font-family: var(--font-body); font-size: 13px; font-weight: 500; color: var(--muted); margin-left: 6px; }

/* ---------------------------------------------------------
   Pricing page — intro message and the bottom call-to-action
   both get their own proper section instead of floating as
   plain inline text.
   --------------------------------------------------------- */
.pricing-intro-box {
    background: linear-gradient(135deg, rgba(232,163,61,0.14), rgba(232,96,124,0.1));
    border: 1px solid rgba(232,163,61,0.3);
    border-radius: 10px;
    padding: 16px 20px;
    margin-top: 16px;
}
.pricing-intro-box p { font-size: 14.5px; line-height: 1.6; margin: 0; }
.pricing-intro-box a { color: var(--gold); font-weight: 600; }

.pricing-cta-section {
    margin-top: 40px;
    padding: 28px 20px;
    text-align: center;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
}
.pricing-cta-section p { font-size: 15px; color: var(--muted); margin-bottom: 14px; }
.pricing-cta-section .btn { display: inline-block; }

.already-subscribed-box {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    background: var(--success-bg);
    border: 1px solid rgba(111,196,149,0.3);
    border-radius: 10px;
    padding: 18px 20px;
}
.already-subscribed-icon {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--success-text);
    color: #0e2116;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    font-size: 16px;
}
.already-subscribed-box strong:first-child { display: block; font-size: 15px; margin-bottom: 4px; color: var(--success-text); }
.already-subscribed-box p { font-size: 13.5px; color: var(--text); line-height: 1.6; margin: 0; }

/* ---------------------------------------------------------
   Novel detail
   --------------------------------------------------------- */
.novel-detail { display: flex; gap: 28px; flex-wrap: wrap; margin-bottom: 30px; }
.novel-detail .novel-cover { width: 260px; border-radius: 2px 4px 4px 2px; border-left: 4px solid var(--gold); }
.novel-detail-info { flex: 1; min-width: 260px; }
.novel-detail-info h1 { font-size: 28px; margin-bottom: 10px; }
.chapter-list { list-style: none; margin-top: 20px; }
/* A fixed, scrollable area for the chapter list on the novel
   page — so the page's overall height stays sane and predictable
   even with "100 per page" or "View All" selected, instead of the
   page potentially growing to list hundreds of chapters inline. */
.chapter-list-fixed-area {
    max-height: 620px;
    overflow-y: auto;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card-bg);
    padding: 10px;
}
.chapter-list-fixed-area::-webkit-scrollbar { width: 8px; }
.chapter-list-fixed-area::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }
.chapter-list-fixed-area::-webkit-scrollbar-thumb:hover { background: var(--gold); }
.chapter-list li {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 8px;
}
.chapter-list a:hover { color: var(--gold); }
.lock {
    display: inline-block;
    color: #1B1730;
    background: var(--gold);
    font-size: 11px;
    font-weight: 700;
    padding: 3px 10px 3px 14px;
    border-radius: 2px 10px 10px 2px;
    position: relative;
    white-space: nowrap;
    margin-left: 8px;
}
.free-badge {
    display: inline-block;
    color: var(--success-text);
    background: none;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.3px;
    white-space: nowrap;
    margin-left: 8px;
}
.listen-icon { padding: 0 14px; font-size: 16px; text-decoration: none; flex-shrink: 0; transition: transform 0.15s ease; }
.listen-icon:hover { transform: scale(1.15); }

/* ---------------------------------------------------------
   Chapter reader
   --------------------------------------------------------- */
.reader-box {
    background: #FBF7EF;
    color: #2B2B3A;
    padding: 34px;
    border-radius: 10px;
    max-width: 100%;
    margin: 0 auto;
    font-size: 17px;
    line-height: 1.9;
    box-shadow: 0 4px 20px rgba(0,0,0,0.3);
    /* No overflow-x:hidden here — like html/body, it would silently
       break position:sticky for the toolbar below (any non-visible
       overflow on an ancestor disables sticky for descendants).
       The original overflow risk (a pasted image or long word
       spilling past the edge) is already handled at the content
       level by #reader-content's own max-width/word-wrap rules. */
}
.reader-box h1 { font-size: 23px; margin-bottom: 20px; color: #2B2B3A; }
.chapter-ad-slot { margin: 20px 0; text-align: center; overflow: hidden; }
#reader-content {
    /* Constrains whatever admin pastes into the chapter editor —
       an image with no width set, or one long unbroken word/URL,
       would otherwise overflow this box horizontally and spill
       past the right edge instead of resizing or wrapping to fit. */
    overflow-wrap: break-word;
    word-wrap: break-word;
    max-width: 100%;
}
#reader-content img, #reader-content video, #reader-content iframe {
    max-width: 100%;
    height: auto;
    display: block;
    margin: 16px auto;
}
#reader-content table { max-width: 100%; display: block; overflow-x: auto; }
#reader-content p { margin-bottom: 1.1em; }
#reader-content p:last-child { margin-bottom: 0; }

/* Shared styling for any area that renders admin/author-authored
   rich-text HTML (Quill-generated) for display — static pages,
   novel synopses, and anywhere else editor content shows up
   read-only. Without this, headings render the same size as body
   text, paragraphs run together with no spacing, lists lose their
   bullets/numbers visually, and links look like plain text —
   exactly the "not good looking" complaint this fixes. */
.rich-content { line-height: 1.8; }
.rich-content h1, .rich-content h2, .rich-content h3,
.rich-content h4, .rich-content h5, .rich-content h6 {
    font-family: var(--font-display);
    margin: 1.2em 0 0.5em;
    line-height: 1.3;
    color: var(--text);
}
.rich-content h1 { font-size: 26px; }
.rich-content h2 { font-size: 22px; }
.rich-content h3 { font-size: 19px; }
.rich-content h4, .rich-content h5, .rich-content h6 { font-size: 16px; }
.rich-content p { margin-bottom: 1em; }
.rich-content p:last-child { margin-bottom: 0; }
.rich-content ul, .rich-content ol { margin: 0 0 1em; padding-left: 1.6em; }
.rich-content li { margin-bottom: 0.4em; }
.rich-content a { color: var(--gold); text-decoration: underline; }
.rich-content a:hover { color: var(--primary); }
.rich-content blockquote {
    margin: 1em 0;
    padding: 10px 18px;
    border-left: 3px solid var(--gold);
    background: var(--card-bg-2);
    color: var(--muted);
    font-style: italic;
}
.rich-content img { max-width: 100%; height: auto; border-radius: 6px; margin: 0.8em 0; display: block; }
.rich-content table { width: 100%; border-collapse: collapse; margin: 1em 0; }
.rich-content table td, .rich-content table th {
    border: 1px solid var(--border);
    padding: 8px 12px;
    text-align: left;
}
.rich-content table th { background: var(--card-bg-2); font-weight: 700; }
.rich-content strong { font-weight: 700; }
.rich-content em { font-style: italic; }
.reader-box .novel-meta a { color: var(--primary); text-decoration: none; }
.reader-nav {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    align-items: center;
    gap: 10px;
    margin-top: 30px;
}
.reader-nav .btn, .reader-nav .toolbar-btn {
    width: 100%;
    text-align: center;
    box-sizing: border-box;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
@media (max-width: 480px) {
    /* Very narrow phones — smaller text and padding so all three
       fit comfortably on the one line rather than getting cramped. */
    .reader-nav { gap: 6px; }
    .reader-nav .btn, .reader-nav .toolbar-btn { font-size: 12.5px; padding-left: 8px; padding-right: 8px; }
}
.reader-toolbar {
    display: flex;
    gap: 10px;
    margin-bottom: 18px;
    flex-wrap: wrap;
    position: sticky;
    top: var(--header-height, 64px);
    z-index: 8;
    background: #FBF7EF;
    padding: 10px 0;
    margin-top: -4px;
}
.toolbar-group-primary, .toolbar-group-secondary { display: contents; }

@media (max-width: 780px) {
    /* Mobile only — desktop keeps all 5 buttons together in the one
       sticky row above, completely untouched. On mobile: Like/
       Bookmark/Report stay in that same sticky-below-header bar as
       an even 3-column row, while Chapter List/Listen move out into
       their own bar fixed to the very bottom of the screen — both
       laid out to exactly fit the viewport width rather than wrap
       or overflow. */
    .toolbar-group-primary, .toolbar-group-secondary { display: flex; }
    .toolbar-group-secondary {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 8px;
        width: 100%;
    }
    .toolbar-group-secondary .toolbar-btn {
        width: 100%;
        justify-content: center;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .toolbar-group-primary {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 30;
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        gap: 0;
        background: #FBF7EF;
        border-top: 1px solid rgba(0,0,0,0.12);
        box-shadow: 0 -4px 14px rgba(0,0,0,0.15);
        padding: 10px max(10px, env(safe-area-inset-left)) calc(10px + env(safe-area-inset-bottom)) max(10px, env(safe-area-inset-right));
        transition: transform 0.2s ease;
    }
    .toolbar-group-primary.toolbar-hidden { transform: translateY(100%); }
    .toolbar-group-primary .toolbar-btn {
        width: 100%;
        justify-content: center;
        border-radius: 8px;
    }
    /* Icon-only — Prev/Chapter List/Next/Listen/Settings all fit in
       one row this way; text labels wouldn't fit five across at
       this width. */
    .toolbar-icon-btn { font-size: 30px; padding: 12px 0; }
    .toolbar-icon-btn .toolbar-btn-label { display: none; }
    .toolbar-btn-disabled { opacity: 0.3; pointer-events: none; }
    /* This bar's own Settings icon replaces the floating one on
       mobile — both exist in the DOM and open the identical panel
       (see the shared toggleSettingsPanel() function), so hiding
       one here is purely which button is visible, not a second,
       separate settings feature to keep in sync. */
    .settings-fab { display: none; }
    /* The sticky top bar no longer needs to reserve space for the
       buttons that moved to the bottom bar, and the page itself
       needs bottom padding so the fixed bar never covers the last
       lines of the chapter or the reader-nav buttons beneath it. */
    .reader-toolbar { padding-bottom: 10px; }
    #reader-box { padding-bottom: 92px; }
    /* This page's own back-to-top button sits at exactly the same
       bottom-right corner the 5-icon bar's rightmost icon (Reading
       Settings) occupies, and above it (higher z-index) — silently
       intercepting every tap meant for that icon once scrolling
       makes the back-to-top button appear. Pushed up above the bar
       here, scoped to this page specifically via body.chapter-
       reading-page so every other page's back-to-top position is
       untouched. */
    body.chapter-reading-page #back-to-top-btn { bottom: 90px; }
}
.toolbar-btn {
    background: #F0E9DA;
    border: 1px solid #E0D6C0;
    padding: 8px 14px;
    border-radius: 6px;
    font-size: 13px;
    cursor: pointer;
    color: #2B2B3A;
    font-family: var(--font-body);
    font-weight: 600;
}
.toolbar-btn:hover { background: #E5DAC4; }
/* Desktop only (hidden on mobile within the 780px breakpoint above,
   where all 5 icons need to stay icon-only to fit one row) — gives
   the Listen/Previous/Chapter List/Next/Settings buttons a visible
   name alongside their icon, rather than relying on a hover tooltip
   alone to say what each one does. */
.toolbar-btn-label { margin-left: 5px; }

/* Locked chapter panel — wax-seal styling */
.lock-panel {
    margin-top: 10px;
    padding: 34px 20px;
    text-align: center;
    background: linear-gradient(180deg, rgba(251,247,239,0) 0%, #F3ECDC 15%, #F3ECDC 100%);
    border-top: 1px solid #E0D6C0;
    border-radius: 0 0 10px 10px;
}
.lock-icon {
    font-size: 26px;
    width: 54px;
    height: 54px;
    line-height: 54px;
    border-radius: 50%;
    background: var(--primary);
    color: #fff;
    margin: 0 auto 14px;
    box-shadow: 0 3px 10px rgba(232,96,124,0.4);
}
.lock-title { font-family: var(--font-display); font-size: 19px; font-weight: 600; margin-bottom: 6px; color: #2B2B3A; }
.lock-sub { font-size: 14px; color: #6b6478; max-width: 420px; margin: 0 auto 18px; }
.lock-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.btn-outline { background: transparent; border: 1px solid var(--primary); color: var(--primary); }
.btn-outline:hover { background: var(--primary); color: #fff; }
.latest-chapter-notice {
    margin-top: 20px;
    padding: 16px;
    text-align: center;
    background: rgba(232,163,61,0.12);
    border: 1px solid rgba(180,130,30,0.3);
    border-radius: 8px;
    color: #2B2B3A;
}
/* The reader has separate Light/Dark/Gray reading themes — this
   notice's text color was hardcoded for the light paper theme
   only, making it unreadable (dark text on a dark background)
   whenever a reader picked Dark mode. Now it follows suit. */
.reader-box.theme-dark .latest-chapter-notice {
    background: rgba(232,163,61,0.16);
    border-color: rgba(232,163,61,0.4);
    color: #e4e4ef;
}
.reader-box.theme-gray .latest-chapter-notice {
    background: rgba(232,163,61,0.18);
    border-color: rgba(180,130,30,0.4);
    color: #262a2e;
}

/* ---------------------------------------------------------
   Batched import progress bar
   --------------------------------------------------------- */
.import-progress-bar-track {
    width: 100%;
    height: 16px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}
.import-progress-bar-fill {
    height: 100%;
    background: var(--gold);
    transition: width 0.2s ease;
}

/* Reading themes (user-selected — independent of site chrome) */
.reader-box.theme-dark { background: #1e1e2b; color: #e4e4ef; }
.reader-box.theme-dark h1, .reader-box.theme-dark .lock-title { color: #e4e4ef; }
.reader-box.theme-dark .lock-panel { background: linear-gradient(180deg, rgba(30,30,43,0) 0%, #17171f 15%, #17171f 100%); border-color: #333; }
.reader-box.theme-dark .lock-sub { color: #a79fc0; }
.reader-box.theme-dark .toolbar-btn { background: #2a2a3a; border-color: #3a3a4a; color: #e4e4ef; }
.reader-box.theme-dark .reader-toolbar { background: #1e1e2b; }
.reader-box.theme-gray { background: #eef0f2; color: #333; }
.reader-box.theme-gray .toolbar-btn { background: #dfe3e6; border-color: #c8ccd0; color: #333; }
.reader-box.theme-gray .reader-toolbar { background: #eef0f2; }

/* Sepia — classic warm e-reader tone, easy on the eyes for long
   sessions, familiar from Kindle/most reading apps. */
.reader-box.theme-sepia { background: #f4ecd8; color: #5b4636; }
.reader-box.theme-sepia h1, .reader-box.theme-sepia .lock-title { color: #4a3728; }
.reader-box.theme-sepia .lock-panel { background: linear-gradient(180deg, rgba(244,236,216,0) 0%, #f4ecd8 15%, #f4ecd8 100%); border-color: #d9c9a3; }
.reader-box.theme-sepia .lock-sub { color: #7a6551; }
.reader-box.theme-sepia .toolbar-btn { background: #ebe0c4; border-color: #d9c9a3; color: #5b4636; }
.reader-box.theme-sepia .reader-toolbar { background: #f4ecd8; }
.reader-box.theme-sepia .latest-chapter-notice { background: rgba(180,130,30,0.14); border-color: rgba(180,130,30,0.35); color: #4a3728; }

/* Night — near-pure black, for OLED screens and reading in the
   dark without any glow; noticeably darker than the Dark theme. */
.reader-box.theme-night { background: #000000; color: #cfcfd6; }
.reader-box.theme-night h1, .reader-box.theme-night .lock-title { color: #e8e8ee; }
.reader-box.theme-night .lock-panel { background: linear-gradient(180deg, rgba(0,0,0,0) 0%, #000 15%, #000 100%); border-color: #2a2a2a; }
.reader-box.theme-night .lock-sub { color: #8a8a94; }
.reader-box.theme-night .toolbar-btn { background: #141414; border-color: #2a2a2a; color: #cfcfd6; }
.reader-box.theme-night .reader-toolbar { background: #000000; }
.reader-box.theme-night .latest-chapter-notice { background: rgba(232,163,61,0.1); border-color: rgba(232,163,61,0.3); color: #d8d8de; }

/* Forest — soft green-tinted background, an alternative some
   readers find gentler on the eyes than plain white or gray. */
.reader-box.theme-forest { background: #e9f0e6; color: #33402f; }
.reader-box.theme-forest h1, .reader-box.theme-forest .lock-title { color: #2a3527; }
.reader-box.theme-forest .lock-panel { background: linear-gradient(180deg, rgba(233,240,230,0) 0%, #e9f0e6 15%, #e9f0e6 100%); border-color: #c3d4bc; }
.reader-box.theme-forest .lock-sub { color: #5a6b54; }
.reader-box.theme-forest .toolbar-btn { background: #dde8d8; border-color: #c3d4bc; color: #33402f; }
.reader-box.theme-forest .reader-toolbar { background: #e9f0e6; }
.reader-box.theme-forest .latest-chapter-notice { background: rgba(111,196,149,0.16); border-color: rgba(111,196,149,0.35); color: #2a3527; }

/* Mobile sticky bottom bar (Chapter List/Listen) — matches
   whichever reader theme is active rather than staying the
   default light cream color, which read as "just white" and
   out of place against a dark/night/gray reading background. */
@media (max-width: 780px) {
    .reader-box.theme-dark .toolbar-group-primary { background: #1e1e2b; border-top-color: #3a3a4a; }
    .reader-box.theme-gray .toolbar-group-primary { background: #eef0f2; }
    .reader-box.theme-sepia .toolbar-group-primary { background: #f4ecd8; border-top-color: #d9c9a3; }
    .reader-box.theme-night .toolbar-group-primary { background: #000000; border-top-color: #2a2a2a; }
    .reader-box.theme-forest .toolbar-group-primary { background: #e9f0e6; border-top-color: #c3d4bc; }
}
.reader-box.font-serif #reader-content { font-family: Georgia, 'Times New Roman', serif; }
.reader-box.font-sans #reader-content { font-family: Arial, Helvetica, sans-serif; }
.reader-box.font-georgia #reader-content { font-family: Georgia, serif; }
.reader-box.font-system #reader-content { font-family: var(--font-body); }

/* ---------------------------------------------------------
   Ratings, likes, favorites
   --------------------------------------------------------- */
.rating-row { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.stars { font-size: 21px; cursor: pointer; }
.stars .star { color: #443a63; transition: color 0.15s ease, transform 0.15s ease; display: inline-block; }
.stars .star.filled { color: var(--gold); }
.stars .star:hover { color: var(--gold); transform: scale(1.15); }
.action-row { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.action-btn {
    background: var(--card-bg);
    border: 1px solid var(--border);
    padding: 9px 16px;
    border-radius: 6px;
    font-size: 13px;
    cursor: pointer;
    color: var(--text);
    font-family: var(--font-body);
    font-weight: 600;
    text-decoration: none;
    display: inline-block;
    transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.action-btn:hover { border-color: var(--primary); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(232,96,124,0.15); }

.social-share-section {
    margin-top: 20px;
    max-width: 100%;
}
.social-share-heading {
    font-size: 15px;
    font-weight: 800;
    margin-bottom: 10px;
}
.social-share-icons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    max-width: 100%;
}
.social-share-icon {
    width: 38px;
    height: 38px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--card-bg);
    border: 1px solid var(--border);
    color: var(--text);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
    transition: border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.social-share-icon span { line-height: 1; }
.social-share-icon:hover {
    background: var(--brand-color, var(--gold));
    color: #fff;
    border-color: var(--brand-color, var(--gold));
    transform: translateY(-2px);
}
.social-share-more-btn {
    display: inline-block;
    margin: 10px 0;
    background: none;
    border: none;
    color: var(--gold);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    padding: 0;
}
.social-share-more-btn:hover { text-decoration: underline; }
#social-share-secondary { margin-top: 2px; }

@media (max-width: 780px) {
    .social-share-icon { width: 42px; height: 42px; font-size: 14px; }
}

.continue-reading-box {
    margin-top: 18px;
    padding: 16px 18px;
    background: linear-gradient(135deg, rgba(232,163,61,0.14), rgba(232,96,124,0.1));
    border: 1px solid rgba(232,163,61,0.3);
    border-radius: 8px;
    transition: border-color 0.2s ease;
}
.continue-reading-box .novel-meta { color: var(--gold); font-weight: 700; }
.continue-reading-box:hover { border-color: rgba(232,163,61,0.55); }

.novel-reading-buttons { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.novel-reading-buttons .btn { font-size: 13px; }

.upcoming-chapter-banner {
    margin: 14px 0 0;
    padding: 12px 16px;
    background: linear-gradient(135deg, rgba(232,163,61,0.14), rgba(232,96,124,0.1));
    border: 1px solid rgba(232,163,61,0.3);
    border-radius: 8px;
    font-size: 13.5px;
    color: var(--text);
}
.upcoming-chapter-banner #upcoming-chapter-countdown { color: var(--gold); font-weight: 700; font-variant-numeric: tabular-nums; }

/* "Ways to Read" — shown on both desktop and mobile. */
.ways-to-read-mobile { margin-top: 36px; }

/* Password visibility toggle */
.password-field { position: relative; display: flex; }
.password-field .pw-input { flex: 1; padding-right: 44px; }
.pw-toggle {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    cursor: pointer;
    font-size: 15px;
    padding: 4px 8px;
}

/* ---------------------------------------------------------
   Modal (chapter list, reader settings)
   --------------------------------------------------------- */
.modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(10,8,18,0.75);
    backdrop-filter: blur(3px);
    z-index: 100;
    align-items: center;
    justify-content: center;
    padding: 20px;
    animation: modalFadeIn 0.15s ease;
}
@keyframes modalFadeIn { from { opacity: 0; } to { opacity: 1; } }
.modal-overlay.open { display: flex; }
.modal-box {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    max-width: 480px;
    width: 100%;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0,0,0,0.5);
    animation: modalRise 0.2s ease;
}
@keyframes modalRise { from { opacity: 0; transform: translateY(12px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } }
.modal-header { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; border-bottom: 1px solid var(--border); }
.modal-header h3 { font-family: var(--font-display); font-size: 17px; }
/* Chapters list specifically, not every modal on the site — it
   holds a 5-column grid per row (title, NEW/lock badge, status,
   time, listen icon) that benefits from real room on a wide screen,
   unlike simpler dialogs (e.g. the report modal) that stay fine at
   the shared, narrower default. */
#chapter-list-modal .modal-box { max-width: 760px; }

/* Homepage popup — deliberately more decorative than the standard
   modal-box above, since this is a promotional/announcement
   moment rather than a functional dialog. */
.homepage-popup-box {
    position: relative;
    background: linear-gradient(160deg, var(--card-bg) 0%, var(--dark) 100%);
    border: 1px solid var(--gold);
    border-radius: 16px;
    max-width: 420px;
    width: 100%;
    padding: 36px 30px 30px;
    text-align: center;
    box-shadow: 0 24px 70px rgba(0,0,0,0.55), 0 0 0 1px rgba(232,163,61,0.15);
    animation: modalRise 0.25s ease;
}
.homepage-popup-close {
    position: absolute;
    top: 12px;
    right: 14px;
    background: none;
    border: none;
    color: var(--muted);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    padding: 4px;
    transition: color 0.15s ease;
}
.homepage-popup-close:hover { color: var(--gold); }
.homepage-popup-icon {
    font-size: 46px;
    margin-bottom: 12px;
    filter: drop-shadow(0 4px 12px rgba(232,163,61,0.4));
}
.homepage-popup-message {
    font-size: 15px;
    line-height: 1.7;
    color: var(--text);
}
.homepage-popup-got-it {
    margin-top: 22px;
    padding: 10px 32px;
    border-radius: 24px;
}
.modal-close { background: none; border: none; font-size: 22px; cursor: pointer; color: var(--muted); line-height: 1; }
.modal-search { margin: 14px 20px 0; padding: 10px 12px; border: 1px solid var(--border); border-radius: 6px; font-size: 14px; background: #FAF7F1; color: #241F3B; transition: box-shadow 0.15s ease; }
.modal-search:focus { outline: none; box-shadow: 0 0 0 3px rgba(232,163,61,0.35); }

/* Gallery picker — wider than the default modal so a desktop
   screen actually gets used well (more thumbnails visible at once,
   less scrolling to find an image), with its own more prominent
   search field. */
.gallery-picker-box {
    max-width: min(92vw, 1100px);
    max-height: 88vh;
}
.gallery-picker-search-wrap {
    position: relative;
    margin: 14px 20px 0;
}
.gallery-picker-search-wrap .gallery-picker-search-icon {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 14px;
    opacity: 0.6;
    pointer-events: none;
}
.gallery-picker-search {
    margin: 0;
    width: 100%;
    padding: 12px 14px 12px 36px;
    font-size: 15px;
}
.gallery-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 16px;
    margin: 16px 20px;
    max-height: 65vh;
    overflow-y: auto;
}
.gallery-picker-thumb {
    padding: 0;
    border: 2px solid transparent;
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    background: var(--card-bg-2);
    transition: border-color 0.15s ease, transform 0.15s ease;
    display: flex;
    flex-direction: column;
}
.gallery-picker-thumb:hover { border-color: var(--gold); transform: translateY(-2px); }
.gallery-picker-thumb-imgwrap {
    width: 100%;
    aspect-ratio: 4/3;
    background: var(--card-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}
/* object-fit: contain — shows the WHOLE image at a large, readable
   size rather than cropping it to fill a fixed box, so admin can
   actually see what each image looks like before picking it. */
.gallery-picker-thumb img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; display: block; }
.gallery-picker-thumb-title {
    padding: 7px 9px;
    font-size: 11px;
    color: var(--muted);
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    border-top: 1px solid var(--border);
}
.gallery-picker-load-more-wrap { text-align: center; margin: 16px 20px 4px; }

@media (max-width: 780px) {
    .gallery-picker-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); margin: 14px; gap: 10px; }
}
.chapter-list-results { overflow-y: auto; padding: 10px 20px; flex: 1; }
.chapter-list-item.current { color: var(--gold); font-weight: 700; }

/* Chapter list rows — both the novel page's own list and the chapter
   reading page's Chapters modal share this exact structure, so a
   badge's presence or absence in one column never shifts anything
   in another. Nested grid: the outer row is [main content | listen
   icon], and the link itself is a 4-column grid of its own
   [title | unlock badge | status badge | time] so every row's
   columns land in the same place regardless of which optional
   badges that particular chapter actually has. */
.chapter-row { display: grid; grid-template-columns: 1fr 34px; align-items: center; }
.chapter-row-link {
    display: grid;
    grid-template-columns: 70% 15% 15%;
    align-items: center;
    gap: 8px;
    padding: 13px 16px;
    text-decoration: none;
    color: var(--text);
    font-size: 14px;
}
.chapter-row-link:hover { color: var(--gold); }
.chapter-row-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chapter-row-col { text-align: center; }
.chapter-row-badge { text-align: left; }
/* Plain icon + text, no pill background — scoped to this context
   only, so the lock badge elsewhere on the site (novel cards, the
   full locked-chapter notice) keeps its original gold pill style. */
.chapter-row-badge .lock {
    background: none;
    color: var(--gold);
    padding: 0;
    border-radius: 0;
    margin-left: 0;
}
@media (max-width: 560px) {
    /* Fixed, smaller pixel widths here rather than the same
       percentages as above — on a narrow phone screen, 15% can come
       out too tight for badge text like "🔒 50 coins" to fit without
       wrapping. With only these two small fixed columns left (the
       date/time column that used to sit here is gone entirely), the
       title still naturally ends up occupying the large majority of
       the row's width either way. */
    .chapter-row-link { grid-template-columns: 1fr 60px 55px; gap: 4px; font-size: 13px; }
    /* Forces exactly 2 columns on mobile instead of the auto-fill
       minmax(220px,...) pattern collapsing to 1 — 220px is simply
       wider than half of most phone screens, so auto-fill alone
       never gets a second column to fit. */
    .gallery-grid { grid-template-columns: repeat(2, 1fr) !important; gap: 10px !important; }
}

.pagination { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; padding: 14px 20px; border-top: 1px solid var(--border); justify-content: center; }
.page-btn { border: 1px solid var(--border); background: var(--card-bg); color: var(--text); border-radius: 4px; padding: 5px 11px; font-size: 12px; cursor: pointer; min-width: 30px; }
.page-btn.active { background: var(--gold); color: #1B1730; border-color: var(--gold); font-weight: 700; }
.page-btn-nav { font-weight: 600; }
.page-ellipsis { color: var(--muted); font-size: 12px; padding: 0 2px; user-select: none; }

/* Settings panel */
.settings-group { padding: 14px 20px; border-bottom: 1px solid var(--border); }
.settings-group label { display: block; font-size: 12px; font-weight: 700; color: var(--muted); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.settings-row { display: flex; gap: 8px; }
.settings-row.settings-row-wrap { flex-wrap: wrap; }
.settings-row.settings-row-wrap .settings-option { flex: 1 1 calc(33.333% - 6px); min-width: 80px; }
.settings-option { flex: 1; border: 1px solid var(--border); background: var(--card-bg); color: var(--text); border-radius: 6px; padding: 8px; font-size: 13px; cursor: pointer; }
.settings-option.active { background: var(--gold); color: #1B1730; border-color: var(--gold); font-weight: 700; }
.settings-select { width: 100%; padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; font-size: 13px; background: #FAF7F1; color: #241F3B; }

/* ---------------------------------------------------------
   Plans / pricing
   --------------------------------------------------------- */
.plan-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; margin-top: 20px; }
.plan-card { background: var(--card-bg); border-radius: 10px; padding: 26px 20px; text-align: center; box-shadow: 0 2px 10px rgba(0,0,0,0.3); border: 2px solid var(--border); }
.plan-card.active-plan { border-color: var(--gold); }
.plan-name { font-family: var(--font-display); font-size: 17px; font-weight: 600; margin-bottom: 8px; }
.plan-price { font-size: 25px; font-weight: 800; color: var(--gold); margin-bottom: 4px; }
.plan-duration { font-size: 12px; color: var(--muted); margin-bottom: 16px; }

/* ---------------------------------------------------------
   Admin tables
   --------------------------------------------------------- */
table { color: var(--text); }
table thead tr { background: var(--dark) !important; }
table tbody tr { border-bottom: 1px solid var(--border) !important; }
table a { color: var(--gold); }

/* ---------------------------------------------------------
   Footer
   --------------------------------------------------------- */
/* ---------------------------------------------------------
   Homepage FAQ + Quick Contact — sit just above the footer.
   --------------------------------------------------------- */
.faq-section, .quick-contact-section {
    max-width: 100%;
    margin: 48px auto 0;
    padding: 0 20px;
}
.faq-section-title { font-family: var(--font-display); font-size: 24px; margin-bottom: 18px; text-align: center; }
.faq-accordion {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    align-items: start;
}
@media (max-width: 780px) {
    .faq-accordion { grid-template-columns: 1fr; }
}
.faq-item { background: var(--card-bg); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.faq-question {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    background: none;
    border: none;
    color: var(--text);
    text-align: left;
    padding: 14px 16px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    font-family: var(--font-body);
}
.faq-question:hover { color: var(--gold); }
.faq-toggle-icon { flex-shrink: 0; font-size: 18px; color: var(--gold); transition: transform 0.2s ease; }
.faq-item.open .faq-toggle-icon { transform: rotate(45deg); }
.faq-answer {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease, padding 0.25s ease;
    padding: 0 16px;
    color: var(--muted);
    font-size: 13.5px;
    line-height: 1.7;
}
.faq-item.open .faq-answer { max-height: 500px; padding: 0 16px 16px; }

.quick-contact-section { text-align: center; margin-top: 40px; margin-bottom: 20px; }
.quick-contact-text { color: var(--muted); font-size: 14px; margin-bottom: 14px; }
.quick-contact-email {
    display: inline-block;
    background: var(--gold);
    color: #1B1730;
    font-weight: 700;
    padding: 12px 24px;
    border-radius: 6px;
    text-decoration: none;
    font-size: 15px;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    box-shadow: 0 2px 8px rgba(232,163,61,0.15);
}
.quick-contact-email:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(232,163,61,0.3); }

.site-footer { background: var(--dark); color: var(--muted); padding: 40px 0 0; font-size: 13px; border-top: 1px solid var(--border); }

.footer-columns {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
    padding-bottom: 30px;
    text-align: left;
}
.footer-col { min-width: 0; }
.footer-logo { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 10px; text-decoration: none; }
.footer-logo-text { font-family: var(--font-display); font-size: 19px; font-weight: 700; color: #F1ECE4; }
.footer-logo .logo-img { height: 32px; width: auto; }
.footer-col-text { font-size: 13px; line-height: 1.7; color: #B8AFC9; max-width: 320px; }
.footer-col-heading {
    font-size: 12px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--gold);
    margin: 0 0 12px;
}
.footer-app-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px;
    border-radius: 24px;
    background: var(--gold);
    border: 1px solid var(--gold);
    color: #1B1730;
    text-decoration: none;
    font-size: 13px;
    font-weight: 700;
    transition: background 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.footer-app-btn:hover { background: #F2B457; border-color: #F2B457; transform: translateY(-1px); box-shadow: 0 4px 12px rgba(232,163,61,0.3); }

.footer-social-icons { display: flex; gap: 10px; }
.footer-social-icon {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--card-bg);
    border: 1px solid var(--border);
    color: #cfc7e0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.footer-social-icon:hover {
    background: var(--brand-color, var(--gold));
    color: #fff;
    border-color: var(--brand-color, var(--gold));
    transform: translateY(-2px);
}

.footer-links { display: flex; flex-direction: column; gap: 9px; }
.footer-links a { color: #cfc7e0; text-decoration: none; font-size: 13px; }
.footer-links a:hover { color: var(--gold); }

.footer-copyright {
    text-align: center;
    padding: 16px 20px;
    border-top: 1px solid var(--border);
    font-size: 12.5px;
    color: var(--muted);
}

@media (max-width: 780px) {
    .footer-columns {
        grid-template-columns: 1fr;
        gap: 28px;
        text-align: center;
    }
    .footer-col-text { max-width: none; margin-left: auto; margin-right: auto; }
    .footer-links {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 8px;
        align-items: stretch;
    }
    .footer-links a {
        background: var(--card-bg);
        border: 1px solid var(--border);
        border-radius: 8px;
        padding: 12px 10px;
        text-align: center;
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 44px;
        transition: border-color 0.15s ease, color 0.15s ease;
    }
    .footer-links a:hover { border-color: var(--gold); }
    .footer-social-icons { justify-content: center; }
    .footer-social-icon { width: 44px; height: 44px; }
}

#back-to-top-btn {
    position: fixed;
    right: 20px;
    bottom: 20px;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: var(--gold);
    color: #1B1730;
    border: none;
    font-size: 18px;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 4px 14px rgba(0,0,0,0.35);
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px);
    transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s;
    z-index: 90;
}
#back-to-top-btn.visible { opacity: 1; visibility: visible; transform: translateY(0); }
#back-to-top-btn:hover { background: #F2B457; }

/* ---------------------------------------------------------
   Responsive
   --------------------------------------------------------- */
@media (max-width: 640px) {
    .hero h1 { font-size: 32px; }
    .header-inner { padding: 12px 16px; }
    .site-header nav { gap: 12px; }
    .novel-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
    .reader-box { padding: 22px 16px; }
}

/* ---------------------------------------------------------
   Accessibility & mobile navigation
   --------------------------------------------------------- */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--gold);
    color: #1B1730;
    padding: 10px 18px;
    font-weight: 700;
    z-index: 200;
    border-radius: 0 0 6px 0;
}
.skip-link:focus { left: 0; }

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

.nav-toggle { display: none; flex-direction: column; justify-content: center; gap: 5px; width: 40px; height: 40px; background: none; border: 1px solid var(--border); border-radius: 6px; cursor: pointer; flex-shrink: 0; }
.nav-toggle span { display: block; width: 20px; height: 2px; background: #fff; margin: 0 auto; }

/* Mobile-only always-visible info grid (Online / Let's Gossip /
   Subscribed / Coins) and standalone avatar — hidden on desktop,
   where this same info already lives in the horizontal nav. */
.mobile-info-grid, .mobile-avatar-link { display: none; }

/* Secondary mobile-only search bar — hidden by default (desktop/
   tablet), only switched to display:block inside the mobile
   breakpoint just below. This must stay BEFORE that media query
   in the file: CSS gives the later rule priority when specificity
   is equal, so if this "none" appeared after the mobile "block"
   rule instead, it would incorrectly win on mobile too and hide
   the search bar there — exactly the bug this comment exists to
   prevent reintroducing. */
.mobile-search-bar { display: none; }

/* ---------------------------------------------------------
   Quick notification ticker — a brief "someone replied to you"
   banner, shown once per new event, then fades itself out. Lives
   inside <header> (not after it) so it inherits the header's own
   sticky positioning and stays pinned in view for as long as it's
   showing, even if the page is scrolled.
   --------------------------------------------------------- */
#quick-notification-bar {
    background: linear-gradient(135deg, rgba(232,163,61,0.22), rgba(232,96,124,0.14));
    border-bottom: 2px solid var(--gold);
}
#quick-notification-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 6px 16px;
    max-width: 1100px;
    margin: 0 auto;
    padding: 11px 20px;
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity 0.3s ease, transform 0.3s ease;
}
#quick-notification-bar.show #quick-notification-inner { opacity: 1; transform: translateY(0); }
#quick-notification-inner a, #quick-notification-inner span {
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text);
    text-decoration: none;
}
#quick-notification-inner a:hover { color: var(--gold); }
#quick-notification-dnd {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    font-weight: 500;
    color: var(--muted);
    cursor: pointer;
    white-space: nowrap;
    flex-shrink: 0;
}
#quick-notification-dnd input { width: auto; margin: 0; cursor: pointer; }

@media (max-width: 780px) {
    .nav-toggle { display: flex; order: 5; }
    /* wrap (not nowrap) is what actually lets the search bar and
       nav panel break onto their own full-width rows below — the
       previous nowrap silently blocked that regardless of the
       flex-basis/order settings below it. */
    .header-inner { flex-wrap: wrap; align-items: center; gap: 8px; }
    .logo { flex-shrink: 0; order: 1; }
    #theme-mode-toggle { order: 2; }

    .mobile-info-grid { order: 3; }
    .mobile-avatar-link { order: 4; }

    /* The desktop-inline search box is hidden on mobile entirely —
       replaced by the dedicated secondary search bar below the
       header (see .mobile-search-bar), which is its own genuinely
       separate block rather than a reflowed row, so it can't be
       knocked out of position by an unrelated rule elsewhere. */
    .header-search { display: none; }

    .mobile-info-grid {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 3px;
        flex: 1;
        min-width: 0;
    }
    .mig-cell {
        background: var(--card-bg);
        border: 1px solid var(--border);
        border-radius: 5px;
        padding: 4px 6px;
        font-size: 10.5px;
        font-weight: 600;
        color: var(--text);
        text-decoration: none;
        text-align: center;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        transition: border-color 0.15s ease;
    }
    .mig-cell:hover, .mig-cell:active { border-color: var(--gold); }
    .mig-gossip { color: var(--gold); }
    .mig-subscribed { color: #7dd3a0; border-color: rgba(125,211,160,0.4); }

    .mobile-avatar-link { display: flex; flex-direction: column; align-items: center; gap: 2px; flex-shrink: 0; }
    .mobile-avatar-link .header-avatar { width: 32px; height: 32px; }
    .mobile-avatar-username {
        font-size: 10px;
        font-weight: 600;
        color: #fff;
        max-width: 56px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* These already appear in the always-visible info grid above —
       don't show them a second time inside the hamburger menu. */
    .mobile-hide-dupe { display: none !important; }

    /* Secondary mobile header — search only, full width, its own
       row directly below the primary header. Both live inside the
       same sticky <header>, so they scroll together as one unit. */
    .mobile-search-bar {
        display: block;
        width: 100%;
        padding: 10px 16px 12px;
        border-top: 1px solid var(--border);
        position: relative;
    }
    .mobile-search-bar input {
        width: 100%;
        padding: 10px 14px;
        border: 1.5px solid rgba(232,163,61,0.1);
        border-radius: 6px;
        font-size: 14px;
        background: var(--dark);
        color: #fff;
    }
    .mobile-search-bar input::placeholder { color: #fff; opacity: 1; }
    .mobile-search-bar input:focus { outline: none; border-color: rgba(232,163,61,0.25); box-shadow: none; }
    .mobile-search-bar .header-search-results { left: 16px; right: 16px; width: auto; }

    /* The desktop-only second row never shows on mobile — these
       same links are still reachable via the hamburger panel below,
       where .nav-primary-link is restored to visible. */
    .site-header-row2 { display: none; }
    .site-header nav .nav-primary-link { display: block; }
    .site-header nav .mobile-nav-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; width: 100%; }

    /* Button-styled instead of plain text links — Browse/Categories
       sit two-up in a row (via .mobile-nav-2col above); Advanced
       Search/Pricing/Leaderboard are each their own full-width row. */
    .nav-primary-btn {
        display: block !important;
        text-align: center;
        padding: 11px 12px;
        border: 1px solid var(--border);
        border-radius: 8px;
        background: var(--card-bg);
        font-weight: 600;
        font-size: 13.5px;
    }
    .nav-primary-btn-full { width: 100%; }

    /* The logged-in name + avatar already shows in the mobile
       header itself (.mobile-avatar-link, next to the hamburger
       button) — showing it a second time inside the opened menu
       would just be a duplicate. Desktop is untouched: #site-nav's
       .username link is its only such display there. */
    .site-header nav .username { display: none; }

    /* Row 3: the hamburger's panel — its own full-width row below
       the search bar, hidden until opened. Still inside the same
       sticky <header>, so it scrolls together with the rest; capped
       height + scroll so a long link list never pushes the page's
       actual content off screen on a short phone. */
    .site-header nav {
        display: none;
        order: 6;
        flex-basis: 100%;
        flex-direction: column;
        align-items: flex-start;
        width: 100%;
        gap: 14px;
        padding: 16px 4px 4px;
        max-height: calc(100vh - 140px);
        overflow-y: auto;
    }
    .site-header nav.open { display: flex; }

    /* Login/Logout/Sign Up sit at the bottom of the opened menu,
       visually separated from the links above them. */
    .nav-bottom-link { margin-top: 10px; padding-top: 14px; border-top: 1px solid var(--border); width: 100%; text-align: center; }
}

/* Comfortable touch targets */
.toolbar-btn, .action-btn, .page-btn, .settings-option, .btn {
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.chapter-list-item, .category-pill { min-height: 40px; }

/* Prevent iOS Safari auto-zoom on form focus */
@media (max-width: 640px) {
    .form-group input, .form-group select, .form-group textarea, .modal-search, .settings-select {
        font-size: 16px;
    }
}

/* ---------------------------------------------------------
   Header live search
   --------------------------------------------------------- */
.header-search { position: relative; flex: 1; max-width: 320px; min-width: 140px; }
.header-search input {
    width: 100%;
    padding: 9px 14px;
    border-radius: 6px;
    border: 1px solid var(--border);
    background: rgba(255,255,255,0.06);
    color: #fff;
    font-size: 14px;
    font-family: var(--font-body);
}
.header-search input::placeholder { color: #9a92b3; }
.header-search input:focus { background: #FAF7F1; color: #241F3B; }
.header-search-results {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    right: 0;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.4);
    z-index: 50;
    overflow: hidden;
}
.header-search-results.open { display: block; }
.header-search-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    text-decoration: none;
    color: var(--text);
    border-bottom: 1px solid var(--border);
    font-size: 13px;
}
.header-search-item:hover { background: var(--card-bg-2); }
.header-search-item img, .hsr-cover-fallback {
    width: 34px; height: 45px; border-radius: 3px; object-fit: cover; flex-shrink: 0;
}
.hsr-cover-fallback {
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--primary), #6B4FA0);
    color: #fff; font-family: var(--font-display); font-weight: 700;
}
.header-search-viewall { display: block; padding: 10px 14px; text-align: center; color: var(--gold); text-decoration: none; font-size: 13px; font-weight: 600; }
.header-search-empty { padding: 14px; font-size: 13px; color: var(--muted); }

/* ---------------------------------------------------------
   Enhanced novel card badges (rating, likes, category, status)
   --------------------------------------------------------- */
.card-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.card-category, .card-status, .card-rating, .card-likes, .card-views {
    font-size: 10px;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 3px 8px 8px 3px;
}
.card-category { background: rgba(232,163,61,0.15); color: var(--gold); }
.card-status { background: rgba(255,255,255,0.06); color: var(--muted); }
.card-status.status-ongoing { background: rgba(111,196,149,0.16); color: var(--success-text); }
.card-status.status-completed { background: rgba(232,96,124,0.16); color: var(--primary); }
.card-status.status-hiatus { background: rgba(255,255,255,0.06); color: var(--muted); }

/* ---------------------------------------------------------
   Novel detail page — author badge, latest updates, mobile centering
   --------------------------------------------------------- */
.novel-meta-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.author-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text);
    font-weight: 600;
}

@media (max-width: 640px) {
    .novel-detail { flex-direction: column; align-items: center; text-align: center; }
    .novel-detail .novel-cover { width: 230px; }
    .novel-meta-row, .rating-row, .action-row { justify-content: center; }
    /* Overrides the global align-self:flex-start on .novel-cover-wrap
       (added for a different, desktop-only stretching issue — see
       that rule's own comment) back to centered here, matching
       .novel-detail's own align-items:center above. That flex-start
       value only ever mattered for the row layout's cross-axis
       (vertical stretch); once the layout stacks into a column on
       mobile, the exact same value instead pins the cover to the
       left edge of the column, which is a different, unwanted
       effect in this direction — not something the original fix
       intended at all. */
    .novel-cover-wrap { align-self: center; }
}

/* ---------------------------------------------------------
   Ranking carousels (New Arrivals, Top 10, Mostly Viewed, Popular)
   Manual swipe/scroll — no auto-animation.
   --------------------------------------------------------- */
.rank-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    background: var(--gold);
    color: #1B1730;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 13px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 6px rgba(0,0,0,0.4);
    z-index: 2;
}
.ranked-card { position: relative; flex: 0 0 195px; }
.rank-carousel-viewport {
    display: flex;
    gap: 16px;
    overflow-x: auto;
    margin-top: 12px;
    padding-bottom: 10px;
    scroll-snap-type: x proximity;
}
.rank-carousel-viewport .ranked-card { scroll-snap-align: start; }
.rank-carousel-viewport::-webkit-scrollbar { height: 6px; }
.rank-carousel-viewport::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

/* ---------------------------------------------------------
   Latest Chapters section (above the footer)
   --------------------------------------------------------- */
.latest-chapters-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 10px; margin-top: 16px; }
.latest-chapter-item {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 12px 14px;
    text-decoration: none;
    color: var(--text);
    font-size: 13px;
    display: flex;
    align-items: center;
    gap: 12px;
}
.latest-chapter-item .latest-chapter-cover {
    width: 42px;
    height: 58px;
    object-fit: cover;
    border-radius: 4px;
    flex-shrink: 0;
}
.latest-chapter-item:hover { border-color: var(--gold); }
.latest-chapter-item strong { color: var(--gold); }

/* ---------------------------------------------------------
   Profile page horizontal sliders (Bookmarks, Favorites,
   Reading History) — manual left-to-right scroll/swipe, no
   auto-animation (unlike the homepage ranking carousels).
   --------------------------------------------------------- */
.profile-slider {
    display: flex;
    gap: 14px;
    overflow-x: auto;
    padding-bottom: 10px;
    margin-top: 12px;
    scroll-snap-type: x proximity;
}
.profile-slider-card { flex: 0 0 140px; scroll-snap-align: start; }
.profile-slider::-webkit-scrollbar { height: 6px; }
.profile-slider::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
.card-rating { background: rgba(232,163,61,0.15); color: var(--gold); }
.card-likes { background: rgba(232,96,124,0.15); color: var(--primary); }
.card-views { background: rgba(255,255,255,0.06); color: var(--muted); }
.card-synopsis {
    font-size: 12px;
    color: var(--muted);
    margin-top: 8px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ---------------------------------------------------------
   Curated homepage sections (grid, 6 per section + View More)
   --------------------------------------------------------- */
.novel-section { margin-top: 40px; }
.section-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 14px; }
.section-more { color: var(--gold); text-decoration: none; font-size: 13px; font-weight: 600; }

/* ---------------------------------------------------------
   Admin navigation — categorized accordion groups.
   Right sidebar on desktop, full-width panel on mobile (both use
   the same vertical accordion layout, just different width).
   --------------------------------------------------------- */
/* ---------------------------------------------------------
   Admin panel — WordPress-style layout: a thin top admin bar,
   plus a dark icon+label sidebar with expandable groups. Every
   color below reuses this site's own existing variables — the
   admin/author color scheme is unchanged, only rearranged.
   --------------------------------------------------------- */
.wp-admin-bar {
    display: flex;
    align-items: center;
    gap: 4px;
    height: 34px;
    padding: 0 14px;
    background: var(--dark);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 50;
    font-size: 12.5px;
}
.wp-admin-bar a { color: #cfc7e0; text-decoration: none; padding: 0 10px; height: 100%; display: flex; align-items: center; }
.wp-admin-bar a:hover { color: var(--gold); background: rgba(255,255,255,0.05); }
.wp-admin-bar-spacer { flex: 1; }
.wp-admin-bar-howdy { color: var(--muted); padding: 0 10px; }
.wp-admin-bar-logout:hover { color: var(--primary) !important; }

.admin-layout { display: flex; gap: 0; flex-direction: row; align-items: flex-start; }
.admin-content { flex: 1; min-width: 0; padding: 20px var(--admin-pad-x, 20px); }
/* Hidden by default (desktop) — the mobile media query below
   switches these on and defines their actual mobile appearance. */
.admin-mobile-nav-toggle, .admin-mobile-nav-backdrop { display: none; }
.admin-nav {
    flex: 0 0 190px;
    position: sticky;
    /* The site's own header no longer renders on admin pages at
       all (see includes/header.php) — only the 34px top admin bar
       sits above this now, so that's the only offset needed. */
    top: 34px;
    max-height: calc(100vh - 34px);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 0;
    background: var(--dark);
    border-right: 1px solid var(--border);
    padding: 6px 0;
}

.admin-nav-group summary {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 16px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
    user-select: none;
    color: #cfc7e0;
    border-left: 3px solid transparent;
}
.admin-nav-icon { font-size: 15px; flex-shrink: 0; width: 18px; text-align: center; }
.admin-nav-label { flex: 1; }
.admin-nav-group summary::-webkit-details-marker { display: none; }
.admin-nav-group summary::after { content: '▸'; color: var(--muted); font-size: 10px; margin-left: auto; transition: transform 0.15s ease; }
.admin-nav-group[open] summary::after { transform: rotate(90deg); }
.admin-nav-group summary:hover { background: rgba(255,255,255,0.05); color: #fff; }
.admin-nav-group.has-active summary { border-left-color: var(--gold); color: #fff; background: rgba(232,163,61,0.08); }

.admin-nav-group-items { display: flex; flex-direction: column; padding: 2px 0 6px; background: rgba(0,0,0,0.15); }
.admin-nav-group-items a {
    padding: 8px 16px 8px 44px;
    color: var(--muted);
    text-decoration: none;
    font-size: 12.5px;
    border-left: 3px solid transparent;
}
.admin-nav-group-items a:hover { background: rgba(255,255,255,0.04); color: #fff; }
.admin-nav-group-items a.active { color: var(--gold); font-weight: 700; border-left-color: var(--gold); background: rgba(232,163,61,0.08); }

/* ---------------------------------------------------------
   Admin design system — compact, data-dense.
   Retrofit target: replace repeated inline table/card styles
   across admin pages with these shared classes.
   --------------------------------------------------------- */
.admin-h1 {
    font-family: var(--font-body);
    font-size: 19px;
    font-weight: 800;
    letter-spacing: -0.2px;
}
.admin-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--admin-radius);
    box-shadow: var(--admin-shadow);
    padding: 14px;
}
.admin-card h2 { font-size: 14px; font-weight: 700; margin-bottom: 10px; }

.admin-table-wrap { overflow-x: auto; border-radius: var(--admin-radius); border: 1px solid var(--border); box-shadow: var(--admin-shadow); }
.admin-table { width: 100%; border-collapse: collapse; background: var(--card-bg); font-size: var(--admin-font-size); }
.admin-table thead tr { background: var(--dark); color: #fff; text-align: left; }
.admin-table th { padding: 8px var(--admin-pad-x); font-weight: 700; font-size: 11px; text-transform: uppercase; letter-spacing: 0.4px; color: var(--muted); position: sticky; top: 0; background: var(--dark); z-index: 1; }
.admin-table td { padding: var(--admin-pad-y) var(--admin-pad-x); border-bottom: 1px solid var(--border); vertical-align: middle; }
.admin-table tbody tr:hover { background: var(--card-bg-2); }
.admin-table tbody tr:last-child td { border-bottom: none; }

/* Responsive tables — below this width, an admin table with
   several inline mini-forms per cell stops being usable even with
   horizontal scroll (you'd have to scroll sideways mid-edit). Turn
   each row into a labeled stacked card instead: add this class to
   any admin-table you want this treatment for, and a data-label
   attribute on each <td> naming its column. */
@media (max-width: 780px) {
    .admin-table.admin-table-responsive-cards thead { display: none; }
    .admin-table.admin-table-responsive-cards, .admin-table.admin-table-responsive-cards tbody { display: block; width: 100%; }
    .admin-table.admin-table-responsive-cards tr {
        display: block;
        background: var(--card-bg);
        border: 1px solid var(--border);
        border-radius: var(--admin-radius);
        margin-bottom: 10px;
        padding: 4px 0;
    }
    .admin-table.admin-table-responsive-cards td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        padding: 8px 12px;
        border-bottom: 1px solid var(--border);
        text-align: right;
        white-space: normal;
    }
    .admin-table.admin-table-responsive-cards tr td:last-child { border-bottom: none; }
    .admin-table.admin-table-responsive-cards td::before {
        content: attr(data-label);
        font-size: 10.5px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.4px;
        color: var(--muted);
        flex-shrink: 0;
        text-align: left;
    }
    /* Inline forms inside a cell (price editors, action buttons)
       need to wrap and use the space naturally instead of being
       squeezed to fixed pixel widths meant for a wide desktop cell. */
    .admin-table.admin-table-responsive-cards td form { flex-wrap: wrap; justify-content: flex-end; }
    .admin-table.admin-table-responsive-cards td input[type="number"],
    .admin-table.admin-table-responsive-cards td input[type="text"] { width: 64px !important; }
}

.admin-stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px; }
.admin-stat-card { background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--admin-radius-sm); box-shadow: var(--admin-shadow); padding: 12px 14px; }
.admin-stat-card .admin-stat-label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.3px; }
.admin-stat-card .admin-stat-value { font-size: 20px; font-weight: 800; margin-top: 2px; font-family: var(--font-body); }

/* Dashboard section layout — the toggle only applies on desktop
   (per spec); mobile always stacks single-column regardless of
   the chosen mode, since there's no room for a real grid there. */
.dashboard-sections { margin-top: 20px; }
.dashboard-sections section {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--admin-radius);
    padding: 16px 18px;
    margin-bottom: 18px;
}
/* The toggle itself only matters once the grid layout can
   actually apply — below that width it would show as clickable
   with no visible effect, which just looks broken. Hiding it here
   keeps the control honest about what it can currently do. */
@media (max-width: 899px) {
    .dashboard-view-toggle { display: none; }
}
@media (min-width: 900px) {
    .dashboard-sections.dashboard-grid-mode {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 18px;
    }
    .dashboard-sections.dashboard-grid-mode section { margin-bottom: 0; }
}

.admin-btn-sm {
    border: 1px solid var(--border);
    background: var(--card-bg-2);
    color: var(--text);
    border-radius: var(--admin-radius-sm);
    padding: 4px 10px;
    font-size: 11.5px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.admin-btn-sm:hover { background: var(--card-bg); border-color: var(--gold); }
.admin-btn-sm.danger { color: var(--primary); border-color: transparent; background: none; padding: 4px 6px; }
.admin-btn-sm.danger:hover { background: var(--error-bg); }
.admin-btn-sm.gold { color: var(--gold); border-color: transparent; background: none; padding: 4px 6px; }
.admin-btn-sm.gold:hover { background: rgba(232,163,61,0.12); }

.admin-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 700;
}
.admin-badge.on { background: var(--success-bg); color: var(--success-text); }
.admin-badge.off { background: var(--error-bg); color: var(--error-text); }
.admin-badge.neutral { background: rgba(255,255,255,0.06); color: var(--muted); }

.admin-toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.admin-toolbar input[type="text"], .admin-toolbar input[type="search"] {
    padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--admin-radius-sm);
    background: var(--bg); color: var(--text); font-size: 12.5px;
}

@media (max-width: 900px) {
    .admin-layout { flex-direction: column; }

    /* Top admin bar: drop the "Howdy" greeting on narrow screens to
       keep the essential links (View Site, Dashboard, Log Out) from
       wrapping or overflowing. */
    .wp-admin-bar-howdy { display: none; }
    .wp-admin-bar { overflow-x: auto; }

    /* Hamburger toggle — visible on mobile only, sits inline at
       the top of the page (not fixed), so it can never overlap the
       site's own sticky header or any admin page content below it. */
    .admin-mobile-nav-toggle {
        display: flex;
        align-items: center;
        gap: 8px;
        width: fit-content;
        background: var(--card-bg);
        border: 1px solid var(--border);
        border-radius: var(--admin-radius-sm);
        box-shadow: var(--admin-shadow);
        color: var(--text);
        font-size: 13px;
        font-weight: 700;
        padding: 9px 14px;
        margin-bottom: 12px;
        cursor: pointer;
    }
    .admin-mobile-nav-toggle span {
        display: block;
        width: 18px;
        height: 2px;
        background: var(--text);
        border-radius: 1px;
    }
    /* Stack the three hamburger lines instead of the row layout the
       flex container would otherwise give a bare <span> sequence. */
    .admin-mobile-nav-toggle { flex-wrap: wrap; }
    .admin-mobile-nav-toggle span:nth-child(1) { margin-bottom: -6px; }
    .admin-mobile-nav-toggle span:nth-child(2) { margin: 4px 0 -6px; }

    /* The sidebar becomes a fixed slide-out drawer, off-screen by
       default so it never pushes or overlaps page content — only
       the .open state (toggled by the hamburger) brings it on
       screen, above everything else via z-index. */
    .admin-nav {
        position: fixed;
        top: 0;
        left: -300px;
        bottom: 0;
        width: 280px;
        max-height: 100vh;
        height: 100vh;
        z-index: 310;
        border-radius: 0;
        box-shadow: 4px 0 24px rgba(0,0,0,0.4);
        transition: left 0.25s ease;
        overflow-y: auto;
    }
    .admin-nav.open { left: 0; }

    .admin-mobile-nav-backdrop {
        display: none;
        position: fixed;
        inset: 0;
        background: rgba(0,0,0,0.55);
        z-index: 300;
    }
    .admin-mobile-nav-backdrop.open { display: block; }

    /* Content fills the full width underneath — the drawer overlays
       it rather than sharing space with it. */
    .admin-content { width: 100%; }
}

/* ---------------------------------------------------------
   Text-to-Speech player — fixed audiobook-style bar at the
   bottom of the viewport while active. Only ever rendered for
   an unlocked chapter (see chapter.php's $isUnlocked check) —
   there is no client-side path to show this for locked content.
   --------------------------------------------------------- */
.tts-player {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 95;
    background: var(--card-bg);
    border-top: 1px solid var(--border);
    box-shadow: 0 -6px 24px rgba(0,0,0,0.35);
    padding: 10px 16px 12px;
}
.tts-player-inner { max-width: 720px; margin: 0 auto; }
.tts-progress-row { display: flex; align-items: center; gap: 10px; }
.tts-time { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 34px; }
.tts-time:last-child { text-align: right; }
.tts-progress-track {
    flex: 1;
    height: 6px;
    background: var(--border);
    border-radius: 3px;
    cursor: pointer;
    position: relative;
}
.tts-progress-fill {
    height: 100%;
    width: 0%;
    background: var(--gold);
    border-radius: 3px;
    transition: width 0.15s linear;
}
.tts-controls-row { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.tts-btn {
    background: none;
    border: 1px solid var(--border);
    color: var(--text);
    width: 34px;
    height: 34px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.tts-btn:hover { border-color: var(--gold); }
.tts-btn-play { background: var(--gold); color: #1B1730; border: none; width: 40px; height: 40px; font-size: 16px; }
.tts-btn-play:hover { background: #F2B457; }
.tts-btn-close { margin-left: auto; }
.tts-volume-row { display: flex; align-items: center; gap: 6px; flex: 1; max-width: 140px; font-size: 13px; }
.tts-volume-row input[type="range"] { flex: 1; }
body.tts-player-open { padding-bottom: 88px; }

.tts-resume-banner {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 96;
    width: 100%;
    background: var(--gold);
    color: #1B1730;
    border: none;
    padding: 16px;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 -6px 24px rgba(0,0,0,0.35);
    animation: ttsResumePulse 1.6s ease-in-out infinite;
}
@keyframes ttsResumePulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.85; }
}

@media (max-width: 640px) {
    .tts-volume-row { display: none; }
}

/* ---------------------------------------------------------
   Reading settings — small button fixed to the right edge,
   opens a slide-in panel. Stays accessible after closing.
   --------------------------------------------------------- */
.settings-fab {
    position: fixed;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    z-index: 120;
    background: var(--gold);
    color: #1B1730;
    border: none;
    width: 42px;
    height: 52px;
    border-radius: 8px 0 0 8px;
    font-size: 18px;
    cursor: pointer;
    box-shadow: -2px 2px 10px rgba(0,0,0,0.25);
    transition: width 0.15s ease, box-shadow 0.15s ease;
}
.settings-fab:hover { width: 46px; box-shadow: -4px 4px 16px rgba(232,163,61,0.3); }
.settings-slide-panel {
    position: fixed;
    top: 0;
    right: -320px;
    width: 300px;
    max-width: 85vw;
    height: 100vh;
    background: var(--card-bg);
    border-left: 1px solid var(--border);
    box-shadow: -6px 0 24px rgba(0,0,0,0.35);
    z-index: 130;
    overflow-y: auto;
    transition: right 0.25s ease;
}
.settings-slide-panel.open { right: 0; }
.settings-slide-panel .modal-header { border-bottom: 1px solid var(--border); }

/* Voice Library — the richer voice picker modal, opened from the
   "Choose Voice" button in Reading Settings. Deliberately built in
   this site's own existing gold/dark palette (not a separate theme)
   so it reads as part of the same product, not a bolted-on widget. */
.voice-library-box { max-width: 900px; width: 100%; height: 90vh; max-height: 880px; }
.voice-library-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding: 18px 22px;
    border-bottom: 1px solid var(--border);
}
.voice-library-header h3 { font-family: var(--font-display); font-size: 18px; }
.voice-library-body { display: flex; flex: 1; overflow: hidden; }
.voice-library-sidebar {
    width: 240px;
    flex-shrink: 0;
    border-right: 1px solid var(--border);
    padding: 14px;
    overflow-y: auto;
}
.voice-library-lang-list-heading {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--muted);
    font-weight: 700;
    margin: 14px 0 6px;
    padding: 0 4px;
}
.voice-library-lang-list-heading:first-child { margin-top: 0; }
.voice-library-lang-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    padding: 9px 10px;
    border-radius: 6px;
    border: none;
    background: none;
    color: var(--text);
    font-size: 13.5px;
    text-align: left;
    cursor: pointer;
}
.voice-library-lang-btn:hover { background: var(--card-bg-2); }
.voice-library-lang-btn.active { background: var(--gold); color: #1B1730; font-weight: 700; }
.voice-library-lang-btn .lang-count { font-size: 11px; opacity: 0.75; }
.voice-library-main { flex: 1; display: flex; flex-direction: column; padding: 16px 20px; overflow: hidden; }
.voice-library-gender-tabs { display: flex; gap: 10px; margin-bottom: 14px; flex-shrink: 0; }
.voice-library-gender-tab {
    padding: 8px 16px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--card-bg-2);
    color: var(--text);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.voice-library-gender-tab.active { background: var(--gold); color: #1B1730; border-color: var(--gold); }
.voice-library-cards { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
.voice-library-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--card-bg-2);
    cursor: pointer;
}
.voice-library-card:hover { border-color: var(--gold); }
.voice-library-card.selected { border-color: var(--gold); background: rgba(212, 175, 55, 0.12); }
.voice-library-card-avatar {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--gold);
    color: #1B1730;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 14px;
    flex-shrink: 0;
}
.voice-library-card-info { flex: 1; min-width: 0; }
.voice-library-card-name { font-weight: 700; font-size: 14px; }
.voice-library-card-meta { font-size: 12px; color: var(--muted); }
.voice-library-card-preview-btn {
    flex-shrink: 0;
    background: none;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 7px 12px;
    color: var(--text);
    font-size: 12.5px;
    cursor: pointer;
}
.voice-library-card-preview-btn:hover { border-color: var(--gold); color: var(--gold); }
.voice-library-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 14px 20px;
    border-top: 1px solid var(--border);
    flex-wrap: wrap;
}
@media (max-width: 720px) {
    .voice-library-box { height: 92vh; max-height: none; }
    .voice-library-body { flex-direction: column; }
    .voice-library-sidebar {
        width: 100%;
        max-height: 160px;
        border-right: none;
        border-bottom: 1px solid var(--border);
    }
}
@media (max-width: 480px) {
    .settings-fab { height: 46px; width: 38px; }
}

/* ---------------------------------------------------------
   Toast / popup notifications
   --------------------------------------------------------- */
#toast-container {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 300;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: center;
    pointer-events: none;
}
.toast {
    background: var(--card-bg);
    color: var(--text);
    border: 1px solid var(--border);
    border-left: 4px solid var(--gold);
    padding: 12px 20px;
    border-radius: 8px;
    font-size: 14px;
    box-shadow: 0 6px 20px rgba(0,0,0,0.35);
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.25s ease, transform 0.25s ease;
    max-width: 90vw;
}
.toast-show { opacity: 1; transform: translateY(0); }
.toast-success { border-left-color: var(--success-text); }
.toast-error { border-left-color: var(--primary); }
.toast-info { border-left-color: var(--gold); }

/* ---------------------------------------------------------
   Comments
   --------------------------------------------------------- */
.comments-toggle-row { margin-top: 20px; }
.comments-body { margin-top: 14px; }
.comment-item { margin-top: 12px; }
.comment-bubble {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 14px;
    transition: border-color 0.15s ease;
}
.comment-meta { font-size: 12px; margin-bottom: 4px; }
.comment-body { font-size: 14px; line-height: 1.6; white-space: pre-wrap; word-break: break-word; }

/* Blank avatar placeholder — a colored circle with the user's
   first initial, shown next to gossip messages and comments. */
.avatar-circle {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--primary), #6B4FA0);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 14px;
    flex-shrink: 0;
    box-shadow: 0 2px 6px rgba(0,0,0,0.25);
}
.message-row { display: flex; gap: 10px; align-items: flex-start; }
.typing-indicator { font-size: 12px; color: var(--muted); font-style: italic; padding: 6px 0; min-height: 18px; }
.gossip-guidelines {
    background: rgba(232,163,61,0.1);
    border: 1px solid rgba(232,163,61,0.25);
    border-radius: 8px;
    padding: 10px 14px;
    font-size: 12px;
    color: var(--muted);
    margin: 14px 0;
}
.tab-bar {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}
.tab-btn {
    background: none;
    border: none;
    color: var(--muted);
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 14px;
    padding: 12px 18px;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    white-space: nowrap;
    flex-shrink: 0;
    transition: color 0.15s ease, border-color 0.15s ease;
}
.tab-btn.active { color: var(--gold); border-bottom-color: var(--gold); }
.tab-btn:hover { color: var(--text); }

.currency-toggle-btn {
    background: var(--card-bg);
    border: 1px solid var(--border);
    color: var(--muted);
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 12.5px;
    padding: 8px 14px;
    border-radius: 20px;
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.currency-toggle-btn:hover { border-color: var(--gold); color: var(--text); }
.currency-toggle-btn.active { background: var(--gold); border-color: var(--gold); color: #1B1730; }
.tab-panel { display: none; animation: tabFadeIn 0.2s ease; }
.tab-panel.active { display: block; }
@keyframes tabFadeIn { from { opacity: 0; } to { opacity: 1; } }

/* Form rows (e.g. chapter number + title side by side) */
.form-row { display: flex; gap: 16px; flex-wrap: wrap; }
.form-row .form-group { margin-bottom: 16px; }
.form-row-3col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; align-items: end; }
@media (max-width: 640px) {
    .form-row-3col { grid-template-columns: 1fr; }
}

/* Fixed-height, scrollable content editor — stays a manageable
   size no matter how much text/how many paragraphs are entered */
.fixed-height-editor .ql-editor { height: 340px; overflow-y: auto; }
/* Same fixed-height, scrollable treatment for the Synopsis editor
   on Add/Edit Novel — without an explicit height here, min-height
   on the outer container alone doesn't reliably constrain Quill's
   own inner .ql-editor, letting a longer synopsis grow the editor
   tall enough to visually overlap the Tags section rendered right
   below it in the page layout. !important guards against Quill's
   own bundled CSS (loaded from its CDN, after this stylesheet)
   setting a conflicting height on the same element. overflow:hidden
   on the container itself is a second, redundant safeguard — even
   if the inner .ql-editor were somehow taller than its own set
   height for any reason, the container physically cannot let that
   overflow bleed into the page below it.
   */
#synopsis-editor { overflow: hidden; }
#synopsis-editor .ql-editor { height: 220px !important; max-height: 220px !important; overflow-y: auto !important; }

/* Text-to-speech paragraph highlighting — the paragraph containing
   the word currently being spoken gets a left accent bar, so it's
   easy to spot at a glance which part of a longer chapter is
   currently playing. (Word-level highlighting existed here too at
   one point; removed on request — .tts-word spans are still wrapped
   around every word for the auto-scroll-to-position logic, they're
   just never visually marked as active anymore.) */
.tts-active-paragraph {
    border-left: 3px solid var(--gold);
    padding-left: 10px;
    margin-left: -13px;
}
/* Quill's own editor area keeps its default white background, but
   this site's dark theme sets a light text color on <body> that
   was cascading straight into the editor uncorrected — light text
   on Quill's white background is exactly white-on-white,
   unreadable while typing. Explicit dark text + white background
   here, regardless of the surrounding page's theme. */
.ql-editor, .ql-editor.ql-blank::before {
    color: #1a1a1a;
    background: #fff;
}
.ql-toolbar { background: #f4f2f7; border-color: var(--border) !important; }
.ql-container { border-color: var(--border) !important; }

/* List toolbar (search + sort, admin & reader chapter lists) */
.list-toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* Quill editor — align with site theme */
#chapter-editor { background: #FAF7F1; color: #241F3B; border-radius: 0 0 6px 6px; min-height: 260px; }
.ql-toolbar.ql-snow { border-radius: 6px 6px 0 0; background: #FAF7F1; }
.ql-container.ql-snow { border-color: var(--border); }
.ql-toolbar.ql-snow { border-color: var(--border); }
