/* ===== be.lievi.ng — Design System ===== */

:root {
    --text-primary: #1a1a1a;
    --text-secondary: #6b6b6b;
    --text-link: #1a1a1a;
    --surface: #ffffff;
    --surface-raised: #f9f9f7;
    --border: #e8e8e4;
    --highlight-verse: #fff3cc;
    --accent: #000000;
    --font-body: 'Merriweather', Georgia, serif;
    --font-ui: 'Inter', system-ui, sans-serif;
    --font-code: 'Source Code Pro', monospace;
}

/* ===== Dark mode ===== */

[data-theme="dark"] {
    --text-primary: #f0f0f0;
    --text-secondary: #999;
    --text-link: #f0f0f0;
    --surface: #111;
    --surface-raised: #1a1a1a;
    --border: #2a2a2a;
    --highlight-verse: #3a3010;
    --accent: #ffffff;
}

[data-theme="dark"] .navbar {
    border-color: var(--border) !important;
    background-color: var(--surface) !important;
}

[data-theme="dark"] .navbar-brand {
    color: var(--text-primary) !important;
}

[data-theme="dark"] .nav-link {
    color: var(--text-primary) !important;
}

[data-theme="dark"] .nav-link:hover {
    color: var(--text-secondary) !important;
}

[data-theme="dark"] .navbar-toggler {
    border-color: var(--border);
}

[data-theme="dark"] .navbar-toggler-icon {
    filter: invert(1);
}

[data-theme="dark"] .btn-dark {
    background-color: #f0f0f0;
    border-color: #f0f0f0;
    color: #111;
}

[data-theme="dark"] .btn-dark:hover {
    background-color: #ddd;
    border-color: #ddd;
    color: #111;
}

[data-theme="dark"] .btn-outline-dark {
    color: #f0f0f0;
    border-color: #555;
}

[data-theme="dark"] .btn-outline-dark:hover {
    background-color: #f0f0f0;
    color: #111;
}

[data-theme="dark"] .btn-outline-secondary {
    color: #999;
    border-color: #444;
}

[data-theme="dark"] .btn-outline-danger {
    color: #ff6b6b;
    border-color: #ff6b6b;
}

[data-theme="dark"] .form-control,
[data-theme="dark"] .form-select {
    background-color: var(--surface-raised);
    border-color: var(--border);
    color: var(--text-primary);
}

[data-theme="dark"] .form-control:focus,
[data-theme="dark"] .form-select:focus {
    background-color: var(--surface-raised);
    border-color: #555;
    color: var(--text-primary);
    box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.1);
}

[data-theme="dark"] .form-control::placeholder {
    color: #666;
}

[data-theme="dark"] .list-group-item {
    background-color: transparent;
    border-color: var(--border);
    color: var(--text-primary);
}

[data-theme="dark"] .list-group-item-action:hover {
    background-color: var(--surface-raised);
    color: var(--text-primary);
}

[data-theme="dark"] .card,
[data-theme="dark"] .bg-light {
    background-color: var(--surface-raised) !important;
    color: var(--text-primary);
}

[data-theme="dark"] .table {
    color: var(--text-primary);
}

[data-theme="dark"] .table th,
[data-theme="dark"] .table td {
    border-color: var(--border);
}

[data-theme="dark"] .badge.bg-light {
    background-color: var(--surface-raised) !important;
    color: var(--text-primary) !important;
    border-color: var(--border) !important;
}

[data-theme="dark"] .border-bottom,
[data-theme="dark"] .border-top,
[data-theme="dark"] .border-start {
    border-color: var(--border) !important;
}

[data-theme="dark"] .dropdown-menu {
    background-color: var(--surface-raised);
    border-color: var(--border);
}

[data-theme="dark"] .dropdown-menu span,
[data-theme="dark"] .dropdown-item {
    color: var(--text-primary);
}

[data-theme="dark"] .dropdown-item:hover {
    background-color: #2a2a2a;
    color: var(--text-primary);
}

[data-theme="dark"] .alert {
    background-color: var(--surface-raised);
    border-color: var(--border);
    color: var(--text-primary);
}

[data-theme="dark"] .page-link {
    background-color: var(--surface-raised);
    border-color: var(--border);
    color: var(--text-primary);
}

[data-theme="dark"] .page-item.active .page-link {
    background-color: var(--accent);
    border-color: var(--accent);
    color: #111;
}

[data-theme="dark"] .text-muted {
    color: var(--text-secondary) !important;
}

[data-theme="dark"] .text-dark {
    color: var(--text-primary) !important;
}

[data-theme="dark"] code {
    color: #e8a0bf;
    background-color: var(--surface-raised);
}

/* Theme toggle button */
.theme-toggle {
    background: none;
    border: none;
    padding: 4px;
    cursor: pointer;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
}

.theme-toggle:hover {
    color: var(--text-primary);
}

.theme-toggle .icon-sun,
.theme-toggle .icon-moon {
    width: 18px;
    height: 18px;
}

[data-theme="dark"] .theme-toggle .icon-sun { display: inline; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
:root .theme-toggle .icon-sun { display: none; }
:root .theme-toggle .icon-moon { display: inline; }

/* ===== Base ===== */

body {
    font-family: var(--font-ui);
    color: var(--text-primary);
    background-color: var(--surface);
    -webkit-font-smoothing: antialiased;
    transition: background-color 0.2s ease, color 0.2s ease;
}

/* ===== Typography ===== */

.verse-text,
.reader-body {
    font-family: var(--font-body);
    font-size: 18px;
    line-height: 1.8;
    max-width: 680px;
    margin: 0 auto;
}

/* ===== Navigation ===== */

.navbar {
    font-family: var(--font-ui);
    background-color: var(--surface);
}

.navbar-brand {
    font-family: var(--font-body);
    letter-spacing: -0.02em;
}

/* v1.6: brand-mark image to the left of the wordmark. The two <img>
   variants share the same box; only one is displayed per theme to
   avoid a layout shift on theme toggle. ``object-fit: contain``
   keeps the square-ish brand glyph inside the 28 × 28 slot even if
   the underlying PNG has padding. 2 px border frames the glyph —
   black in light theme, white in dark — matching the avatar-circle
   stroke pattern used elsewhere in the app. */
.navbar-brand-logo {
    width: 28px;
    height: 28px;
    object-fit: contain;
    display: inline-block;
    border: 2px solid #000;
    border-radius: 6px;
}
.navbar-brand-logo-dark { display: none; }
[data-theme="dark"] .navbar-brand-logo-light { display: none; }
[data-theme="dark"] .navbar-brand-logo-dark { display: inline-block; }
[data-theme="dark"] .navbar-brand-logo { border-color: #fff; }

/* Nav links with icons — icon sits in a subtle pill that highlights when active */
.navbar-nav .nav-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.nav-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    background-color: transparent;
    transition: background-color 0.15s ease;
    flex-shrink: 0;
}

.nav-icon svg {
    width: 16px;
    height: 16px;
}

.navbar-nav .nav-link:hover .nav-icon {
    background-color: var(--surface-raised);
}

.navbar-nav .nav-link.active {
    color: var(--text-primary);
    font-weight: 600;
}

.navbar-nav .nav-link.active .nav-icon {
    background-color: var(--highlight-verse);
}

[data-theme="dark"] .navbar-nav .nav-link.active {
    color: var(--text-primary) !important;
}

/* ===== Landing page ===== */

/* v1.9.10: mobile-only branding above the daily verse — logo +
   "be.lievi.ng" wordmark, both centered. Desktop already shows
   the brand in the top navbar; on phones the navbar is hidden
   (see ``.navbar-authed`` rule below the mobile breakpoint) so
   the home page would otherwise open with no brand visible at
   all. Whole block is ``display: none`` by default and flips to
   block under the mobile breakpoint. v1.9.11 adds the logo
   images. */
.home-mobile-brand-block {
    display: none;
}

@media (max-width: 767.98px) {
    .home-mobile-brand-block {
        display: block;
        margin-top: 1.5rem;
    }

    .home-mobile-brand-logo {
        width: 56px;
        height: 56px;
        margin-bottom: 0.5rem;
    }

    /* Theme-toggle the two logo variants — same approach as the
       navbar brand mark. Light favicon on light theme, reversed
       on dark. */
    .home-mobile-brand-logo-dark {
        display: none;
    }

    [data-theme="dark"] .home-mobile-brand-logo-light {
        display: none;
    }

    [data-theme="dark"] .home-mobile-brand-logo-dark {
        display: inline-block;
    }

    .home-mobile-brand {
        font-family: var(--font-ui);
        font-size: 1.4rem;
        font-weight: 700;
        letter-spacing: -0.01em;
        color: var(--text-primary, #1a1a1a);
    }
}

.landing-hero {
    padding-top: 8rem;
    padding-bottom: 4rem;
}

.verse-display {
    max-width: 600px;
}

.verse-display .verse-text {
    font-size: 1.5rem;
    line-height: 1.9;
    font-style: italic;
}

.verse-display .verse-ref {
    font-family: var(--font-ui);
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.verse-display .verse-ref a {
    color: var(--text-link);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ===== Like / heart button ===== */

.like-btn {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-secondary);
    border-radius: 20px;
    padding: 4px 12px;
    font-family: var(--font-ui);
    font-size: 0.875rem;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
    transition: border-color 0.2s ease;
}

.like-btn:hover:not(:disabled) {
    border-color: #e74c3c;
    color: #e74c3c;
}

.like-btn:hover:not(:disabled) .heart-icon {
    stroke: #e74c3c;
}

.like-btn:disabled {
    cursor: default;
    opacity: 1;
}

/* ===== Avatar circle ===== */

.avatar-circle {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background-color: var(--accent);
    color: var(--surface);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-ui);
    font-weight: 600;
    font-size: 0.85rem;
    flex-shrink: 0;
    box-shadow: 0 0 0 2px #fff;  /* v1.4: white stroke on both variants */
}

.avatar-circle.avatar-lg {
    width: 56px;
    height: 56px;
    font-size: 1.3rem;
}

/* Uploaded-image variant (v1.4). <img> replaces the initial-in-a-circle;
   object-fit: cover keeps non-square uploads looking sensible. */
img.avatar-circle.avatar-image {
    object-fit: cover;
    background-color: transparent;
}

/* Dark mode: the white ring looks harsh against near-black surfaces, so
   match the surface colour instead — still visible as a subtle bevel. */
[data-theme="dark"] .avatar-circle {
    box-shadow: 0 0 0 2px var(--surface, #1a1a1a);
}

/* ===== Online indicator dot (admin users page) ===== */

.online-dot {
    display: inline-block;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background-color: #22c55e;
    vertical-align: baseline;
    margin-right: 0.15rem;
}

/* ===== Avatar colour swatch (settings page) ===== */

.avatar-swatch {
    cursor: pointer;
    margin: 0;
}

.avatar-swatch-dot {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background-color: var(--swatch-color);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-family: var(--font-ui);
    font-weight: 600;
    font-size: 0.85rem;
    box-shadow: 0 0 0 2px transparent;
    transition: box-shadow 0.15s ease;
}

.avatar-swatch input:checked + .avatar-swatch-dot {
    box-shadow: 0 0 0 2px var(--surface, #fff), 0 0 0 4px var(--text-primary, #1a1a1a);
}

.avatar-swatch input:focus-visible + .avatar-swatch-dot {
    outline: 2px solid var(--text-primary, #1a1a1a);
    outline-offset: 2px;
}

.avatar-swatch-initial {
    pointer-events: none;
}

/* ===== Related-notes row (note editor) =====

   Layout matches the design reference (avatar + title/snippet left,
   date right-aligned under the snippet). The whole row is a link, but
   only the title adopts the primary text colour so the snippet stays
   muted. Hover lifts the title without disturbing the snippet/date. */

.related-note-row {
    color: inherit;
}

.related-note-row:hover {
    background-color: var(--surface-raised, #f9f9f7);
}

.related-note-row:hover .related-note-title {
    text-decoration: underline;
}

.related-note-title {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 1rem;
    color: var(--text-primary, #1a1a1a);
    line-height: 1.35;
}

.related-note-snippet {
    line-height: 1.5;
    /* Cap at ~2 lines so long snippets don't push the date far below. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.related-note-date {
    font-size: 0.75rem;
}

/* ===== Verse-reference peek tooltip (/notes/<uuid>) ===== */
/* v1.6: small popover that appears when a reader hovers a verse link
   inside a rendered note. JS in ``note_peek.js`` positions it above
   (or below, if no room) the anchor; these rules handle the look and
   hide the whole feature on coarse-pointer devices so touch UX
   stays exactly as before. */

/* Popover deliberately INVERTS the page theme for emphasis — light
   mode = dark chip, dark mode = light chip. Fixed colours rather than
   tokens because the whole point is to contrast the page surface.
   Sub-elements (ref, version, range) derive from the chip palette via
   ``currentColor`` / semi-transparent whites so they flip correctly
   when the dark-mode override kicks in. */
.verse-peek {
    position: absolute;
    z-index: 1060;
    display: none;
    max-width: 320px;
    min-width: 220px;
    padding: 0.65rem 0.8rem;
    background-color: #1a1a1a;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
    font-family: var(--font-body);
    font-size: 0.88rem;
    line-height: 1.45;
    pointer-events: none;
}

[data-theme="dark"] .verse-peek {
    background-color: #fff;
    color: #1a1a1a;
    border-color: rgba(0, 0, 0, 0.1);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}

.verse-peek.is-visible { display: block; }

/* Suppress the iOS / Android native long-press callout on verse-ref
   anchors inside a note — the custom popover is our UI for that
   gesture. JS-tagged in ``note_peek.js::init()``. */
#note-preview-mode a.verse-ref {
    -webkit-touch-callout: none;
}

/* Touch-mode popover (summoned by long-press) is tappable — the whole
   card navigates to the verse on tap, with a clear affordance at the
   bottom. Hover-mode stays ``pointer-events: none`` so a mouse sliding
   off the anchor isn't trapped by the tooltip. */
.verse-peek[data-peek-mode="touch"] {
    pointer-events: auto;
    cursor: pointer;
}

.verse-peek-open {
    margin-top: 0.5rem;
    padding-top: 0.4rem;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    font-family: var(--font-ui);
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.7);
    text-align: right;
}

[data-theme="dark"] .verse-peek-open {
    border-top-color: rgba(0, 0, 0, 0.1);
    color: rgba(0, 0, 0, 0.55);
}

.verse-peek-ref {
    font-family: var(--font-ui);
    font-weight: 600;
    font-size: 0.78rem;
    letter-spacing: 0.03em;
    color: currentColor;  /* inherits the inverted chip text colour */
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.3rem;
    padding-bottom: 0.3rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.15);
}

[data-theme="dark"] .verse-peek-ref {
    border-bottom-color: rgba(0, 0, 0, 0.1);
}

.verse-peek-version {
    font-weight: 500;
    font-size: 0.7rem;
    /* Muted secondary on the dark chip (~60% of white). */
    color: rgba(255, 255, 255, 0.65);
    letter-spacing: 0.02em;
}

[data-theme="dark"] .verse-peek-version {
    color: rgba(0, 0, 0, 0.55);
}

.verse-peek-text {
    /* Inherits colour from the chip; serif body text for readability. */
}

.verse-peek-range {
    margin-top: 0.35rem;
    font-family: var(--font-ui);
    font-size: 0.72rem;
    color: rgba(255, 255, 255, 0.6);
    font-style: italic;
}

[data-theme="dark"] .verse-peek-range {
    color: rgba(0, 0, 0, 0.5);
}

/* ===== Study hub cards (/study) ===== */
/* v1.5: one card per study utility — matches the site's Medium-
   inspired aesthetic (restrained, bordered, generous padding) rather
   than Bootstrap's default card chrome. Hover lifts slightly to signal
   clickability. */

.study-card {
    display: block;
    padding: 1.25rem 1.25rem 1.15rem;
    background-color: var(--surface, #fff);
    color: var(--text-primary, #1a1a1a);
    border: 1px solid var(--border, #e5e5e5);
    border-radius: 8px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease,
                transform 0.15s ease;
}

.study-card:hover,
.study-card:focus-visible {
    border-color: var(--text-primary, #1a1a1a);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
    transform: translateY(-1px);
    color: var(--text-primary, #1a1a1a);
    text-decoration: none;
}

.study-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 8px;
    background-color: var(--surface-raised, #f5f5f4);
    color: var(--text-primary, #1a1a1a);
    flex-shrink: 0;
}

.study-card-title {
    font-family: var(--font-body);
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.study-card-description {
    color: var(--text-secondary, #6b7280);
    font-size: 0.9rem;
    line-height: 1.45;
}

/* ===== Meditation list + detail (/meditation, /meditation/<uuid>) ===== */
/* v1.8: list rows are intentionally restrained — title + meta line +
   status pill on the right. The detail page borrows the home-page
   hero verse styling so the daily verse reads as the centerpiece. */

.meditation-row {
    padding: 1rem 1.1rem;
    background-color: var(--surface, #fff);
    border: 1px solid var(--border, #e5e5e5);
    border-radius: 8px;
}

.meditation-row-title {
    font-family: var(--font-body);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-primary, #1a1a1a);
    letter-spacing: -0.01em;
}

a.meditation-row-title:hover {
    text-decoration: underline !important;
}

.meditation-row-meta {
    line-height: 1.45;
}

.meditation-status {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-family: var(--font-ui);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.25rem 0.55rem;
    border-radius: 999px;
    border: 1px solid transparent;
}

.meditation-status-generating {
    background-color: rgba(217, 119, 6, 0.08);
    color: #b45309;
    border-color: rgba(217, 119, 6, 0.2);
}

.meditation-status-ready {
    background-color: rgba(21, 128, 61, 0.08);
    color: #15803d;
    border-color: rgba(21, 128, 61, 0.2);
}

.meditation-status-failed {
    background-color: rgba(192, 57, 43, 0.08);
    color: #c0392b;
    border-color: rgba(192, 57, 43, 0.2);
}

/* ===== Navbar bell icon + notifications dropdown (v1.8) =====
   Sits between the theme toggle and the avatar dropdown. Badge is
   hidden when there's nothing unread; the dropdown body is rendered
   client-side from /api/notifications. */

.notif-bell {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    padding: 0.4rem 0.55rem;
    color: var(--text-primary, #1a1a1a);
    cursor: pointer;
}

.notif-bell:hover,
.notif-bell:focus-visible {
    color: var(--text-primary, #1a1a1a);
    outline: none;
}

.notif-bell-icon {
    width: 20px;
    height: 20px;
}

.notif-badge {
    position: absolute;
    top: 4px;
    right: 4px;
    min-width: 1.05rem;
    height: 1.05rem;
    padding: 0 0.3rem;
    border-radius: 999px;
    background-color: #c0392b;
    color: #fff;
    font-family: var(--font-ui);
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1.05rem;
    text-align: center;
    pointer-events: none;
}

.notif-dropdown {
    width: 22rem;
    max-width: calc(100vw - 1.5rem);
    padding: 0.5rem 0;
    max-height: 70vh;
    overflow-y: auto;
}

.notif-dropdown-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.25rem 1rem 0.25rem;
}

.notif-mark-all-read {
    text-decoration: none;
    font-size: 0.78rem;
}

.notif-list {
    /* Rows inherit Bootstrap dropdown-item styling for hover/focus
       (already a sensible default). */
}

.notif-empty {
    text-align: center;
}

.notif-row {
    display: block;
    padding: 0.6rem 1rem;
    border-bottom: 1px solid var(--border, #e5e5e5);
    white-space: normal;
    color: var(--text-primary, #1a1a1a);
}

.notif-row:last-child {
    border-bottom: none;
}

.notif-row-unread {
    background-color: rgba(192, 57, 43, 0.04);
}

.notif-row-title {
    font-family: var(--font-ui);
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.35;
}

.notif-row-body {
    font-size: 0.78rem;
    color: var(--text-secondary, #6b7280);
    margin-top: 0.15rem;
    line-height: 1.4;
}

.notif-row-time {
    font-family: var(--font-ui);
    font-size: 0.7rem;
    color: var(--text-secondary, #6b7280);
    margin-top: 0.3rem;
    letter-spacing: 0.02em;
}

[data-theme="dark"] .notif-row-unread {
    background-color: rgba(255, 255, 255, 0.04);
}

/* "+ start a devotional" circle button under the empty-state copy.
   Hands off to the Scribe panel — see ``meditation/index.html``. */
.meditation-start-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background-color: var(--text-primary, #1a1a1a);
    color: var(--surface, #fff);
    border: none;
    cursor: pointer;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.15);
    transition: transform 0.15s ease, box-shadow 0.15s ease,
                background-color 0.15s ease;
}

.meditation-start-btn:hover,
.meditation-start-btn:focus-visible {
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.2);
    outline: none;
    color: var(--surface, #fff);
}

[data-theme="dark"] .meditation-start-btn {
    background-color: var(--surface, #fff);
    color: var(--text-primary, #1a1a1a);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
}

.meditation-status-dot {
    display: inline-block;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background-color: #d97706;
    animation: meditation-pulse 1.4s ease-in-out infinite;
}

.meditation-status-dot-large {
    width: 0.75rem;
    height: 0.75rem;
    margin-right: 0.4rem;
    vertical-align: baseline;
}

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

.meditation-pending-card {
    background-color: var(--surface, #fff);
    border: 1px solid var(--border, #e5e5e5);
    border-radius: 12px;
    padding: 2.5rem 1.5rem;
}

.meditation-title {
    font-family: var(--font-ui);
    font-size: 1.6rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    line-height: 1.2;
}

.meditation-day-counter {
    font-family: var(--font-ui);
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--text-primary, #1a1a1a);
}

.meditation-rule {
    border: 0;
    border-top: 1px solid var(--border, #e5e5e5);
    margin: 1.25rem 0;
    opacity: 1;
}

.meditation-slider-row {
    display: flex;
    align-items: center;
    gap: 0.9rem;
}

.meditation-slider {
    flex: 1;
    min-width: 0;
}

.meditation-slider-caption {
    white-space: nowrap;
}

.meditation-section-label {
    font-family: var(--font-ui);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-secondary, #6b7280);
}

.meditation-verse-block {
    text-align: center;
    padding: 0.75rem 0 0.5rem;
}

.meditation-verse-text {
    font-family: var(--font-body);
    font-size: 1.6rem;
    line-height: 1.45;
    font-weight: 400;
    color: var(--text-primary, #1a1a1a);
    letter-spacing: -0.005em;
}

.meditation-verse-ref {
    margin-top: 0.85rem;
    font-family: var(--font-ui);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-secondary, #6b7280);
}

.meditation-verse-version {
    font-weight: 500;
    margin-left: 0.4rem;
    opacity: 0.8;
}

.meditation-prayer-block {
    padding: 0.25rem 0;
}

.meditation-prayer-text {
    font-family: var(--font-body);
    font-size: 1.05rem;
    line-height: 1.7;
    color: var(--text-primary, #1a1a1a);
    margin-bottom: 0;
}

.meditation-song-embed {
    border-radius: 12px;
    width: 100%;
}

@media (max-width: 575px) {
    .meditation-verse-text { font-size: 1.35rem; }
    .meditation-title { font-size: 1.3rem; }
}

/* ===== Highlights grid (/study/highlights) ===== */
/* v1.5: every card carries the user's chosen highlight colour inline
   via ``style="background-color: #RRGGBB"`` (server-rendered from the
   whitelist). CSS only handles the layout + the typographic contrast
   over those coloured backgrounds. */

.highlights-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
}

@media (max-width: 991px) {
    .highlights-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 575px) {
    .highlights-grid { grid-template-columns: 1fr; }
}

.highlights-card {
    display: block;
    padding: 0.75rem 0.9rem;
    border-radius: 8px;
    text-decoration: none;
    color: #1a1a1a;  /* always the dark ink — the pastel palette is
                       readable with near-black text, and it's simpler
                       than contrast-testing 8 different colours. */
    border: 1px solid rgba(0, 0, 0, 0.05);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    min-height: 110px;
}

.highlights-card:hover,
.highlights-card:focus-visible {
    color: #1a1a1a;
    text-decoration: none;
    transform: translateY(-1px);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
}

.highlights-card-disabled {
    cursor: default;
    opacity: 0.7;
}

.highlights-card-ref {
    font-family: var(--font-ui);
    font-weight: 600;
    font-size: 0.8rem;
    letter-spacing: 0.02em;
    margin-bottom: 0.35rem;
    opacity: 0.85;
}

.highlights-card-text {
    font-family: var(--font-body);
    font-size: 0.92rem;
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.highlights-card-unavailable {
    font-style: italic;
    opacity: 0.65;
    font-size: 0.85rem;
}

/* Filter colour swatches on the filter bar. Mirrors the reader's
   palette swatches but smaller — they're a filter, not an action. */
.highlights-filters {
    padding: 0.6rem 0.75rem;
    background-color: var(--surface-raised, #f5f5f4);
    border: 1px solid var(--border, #e5e5e5);
    border-radius: 8px;
}

.highlight-filter-swatch {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 1px solid rgba(0, 0, 0, 0.1);
    text-decoration: none;
    color: #1a1a1a;
    font-size: 0.65rem;
    transition: transform 0.1s ease, box-shadow 0.1s ease;
    background-color: var(--surface, #fff);
}

.highlight-filter-swatch:hover,
.highlight-filter-swatch:focus-visible {
    transform: scale(1.1);
}

.highlight-filter-swatch.is-active {
    box-shadow: 0 0 0 2px var(--text-primary, #1a1a1a);
}

.highlight-filter-swatch-all {
    font-family: var(--font-ui);
    font-weight: 600;
    line-height: 1;
}

/* ===== Theme chips (/notes) ===== */

.theme-chip {
    background-color: var(--surface-raised, #f5f5f4);
    color: var(--text-primary, #1a1a1a);
    border: 1px solid var(--border, #e5e5e5);
    font-weight: 500;
    font-size: 0.8rem;
    padding: 0.4rem 0.75rem;
    border-radius: 999px;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.theme-chip:hover {
    background-color: var(--text-primary, #1a1a1a);
    color: var(--surface, #fff);
    border-color: var(--text-primary, #1a1a1a);
}

.theme-chip-active {
    background-color: var(--text-primary, #1a1a1a);
    color: var(--surface, #fff);
    border-color: var(--text-primary, #1a1a1a);
}

/* v1.5: Skeleton placeholders for the theme chips while the cold-cache
   async fetch is in flight. Shown on the first /notes render after a
   deploy or after the 24h TTL lapses for an inactive user. One shared
   shimmer animation via ``background-image: linear-gradient(...)`` +
   ``background-position`` translate — zero JS for the animation itself. */
@keyframes theme-chip-shimmer {
    from { background-position: 150% 0; }
    to   { background-position: -150% 0; }
}

.theme-chip-skeleton {
    display: inline-block;
    height: 28px;
    width: 72px;
    border-radius: 999px;
    background-color: var(--surface-raised, #f5f5f4);
    background-image: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.55) 50%,
        transparent 100%
    );
    background-size: 200% 100%;
    animation: theme-chip-shimmer 1.2s ease-in-out infinite;
}

/* Slight size variation so the skeleton row doesn't look mechanical —
   mimics the natural width variance of real theme words. */
.theme-chips-skeleton .theme-chip-skeleton:nth-child(2) { width: 56px; }
.theme-chips-skeleton .theme-chip-skeleton:nth-child(3) { width: 96px; }
.theme-chips-skeleton .theme-chip-skeleton:nth-child(4) { width: 64px; }
.theme-chips-skeleton .theme-chip-skeleton:nth-child(5) { width: 88px; }
.theme-chips-skeleton .theme-chip-skeleton:nth-child(6) { width: 60px; }
.theme-chips-skeleton .theme-chip-skeleton:nth-child(7) { width: 80px; }

/* Dark-mode variant: flip the shimmer highlight to a subtle white
   glow over a darker base so it still reads. */
[data-theme="dark"] .theme-chip-skeleton {
    background-color: var(--surface-raised, #2a2a2a);
    background-image: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.08) 50%,
        transparent 100%
    );
}

/* Accessibility: honour ``prefers-reduced-motion`` — hold a steady
   static placeholder instead of shimmering. */
@media (prefers-reduced-motion: reduce) {
    .theme-chip-skeleton {
        animation: none;
        background-image: none;
    }
}

/* ===== Scripture Search (v1.14) =====================================
   Surface for /study/search. Three sections — definition (async,
   shimmer placeholder), Strong's, verse grid (4 cols desktop / 2 cols
   mobile). All hue tokens reuse the existing palette so the dark-mode
   flip is automatic. */

/* Search input on the /study hub card. */
.study-search-form .input-group .form-control {
    border-color: var(--border-subtle, #e7e5e4);
}

/* Section heading shared across the three blocks on /study/search. */
.search-section {
    margin-bottom: 1.5rem;
}
.search-section-title {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted, #6b6b6b);
    margin-bottom: 1rem;
}

/* The horizontal rules between sections — slightly stronger than
   the default Bootstrap <hr> so the three blocks read as distinct. */
.search-rule {
    border: 0;
    border-top: 1px solid var(--border-subtle, #e7e5e4);
    margin: 2rem 0;
    opacity: 1;
}

/* Filter pill (testament / expansion). Same shape as the existing
   reader-toolbar pills so the visual language is consistent. */
.search-pill {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 500;
    background-color: var(--surface-raised, #f5f5f4);
    color: var(--text-primary, #1a1a1a);
    border: 1px solid var(--border-subtle, #e7e5e4);
}
.search-pill-expanded {
    background-color: rgba(217, 119, 6, 0.12); /* amber accent */
    border-color: rgba(217, 119, 6, 0.3);
    color: #92400e;
}
[data-theme="dark"] .search-pill {
    background-color: var(--surface-raised, #2a2a2a);
    color: var(--text-primary, #f5f5f4);
    border-color: var(--border-subtle, #3a3a3a);
}
[data-theme="dark"] .search-pill-expanded {
    background-color: rgba(217, 119, 6, 0.2);
    color: #fcd34d;
}

/* ── Definition block ───────────────────────────────────────────── */

.search-definition {
    font-family: 'Merriweather', Georgia, serif;
    font-size: 1.025rem;
    line-height: 1.6;
    color: var(--text-primary, #1a1a1a);
}
.search-definition-sense {
    margin-bottom: 1rem;
}
.search-definition-sense:last-child {
    margin-bottom: 0;
}
.search-definition-headword {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 0.95rem;
    margin-bottom: 0.25rem;
}

/* Shimmer skeleton for the definition while the AI fetch is in
   flight. Reuses the keyframes defined for theme chips above. */
.search-definition-skeleton {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.search-skeleton-line {
    height: 14px;
    border-radius: 4px;
    background-color: var(--surface-raised, #f5f5f4);
    background-image: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.55) 50%,
        transparent 100%
    );
    background-size: 200% 100%;
    animation: theme-chip-shimmer 1.2s ease-in-out infinite;
    width: 100%;
}
.search-skeleton-line-title {
    height: 18px;
    width: 35%;
    margin-bottom: 0.4rem;
}
.search-skeleton-line-short {
    width: 60%;
}
[data-theme="dark"] .search-skeleton-line {
    background-color: var(--surface-raised, #2a2a2a);
    background-image: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.08) 50%,
        transparent 100%
    );
}
@media (prefers-reduced-motion: reduce) {
    .search-skeleton-line {
        animation: none;
        background-image: none;
    }
}

/* ── Strong's card ──────────────────────────────────────────────── */

.strongs-card {
    padding: 0.85rem 1rem;
    border: 1px solid var(--border-subtle, #e7e5e4);
    border-radius: 8px;
    background-color: var(--surface, #fff);
}
[data-theme="dark"] .strongs-card {
    background-color: var(--surface, #1f1f1f);
    border-color: var(--border-subtle, #3a3a3a);
}
.strongs-card-id {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 0.85rem;
    color: var(--text-primary, #1a1a1a);
}
.strongs-card-testament {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-muted, #6b6b6b);
    letter-spacing: 0.05em;
}
.strongs-card-headword {
    font-family: 'Merriweather', Georgia, serif;
    font-size: 1.05rem;
    line-height: 1.4;
    margin-bottom: 0.4rem;
}
.strongs-card-lemma {
    font-weight: 600;
    margin-right: 0.4rem;
}
.strongs-card-trans {
    color: var(--text-muted, #6b6b6b);
    margin-right: 0.3rem;
}
.strongs-card-pron {
    font-size: 0.85rem;
    color: var(--text-muted, #6b6b6b);
}
.strongs-card-short {
    font-size: 0.92rem;
    color: var(--text-primary, #1a1a1a);
    margin-bottom: 0;
}
.strongs-card-details summary {
    cursor: pointer;
    margin-top: 0.4rem;
}
.strongs-card-matched em {
    font-style: italic;
}

/* ── Verse grid card ────────────────────────────────────────────── */

.search-verse-card {
    display: block;
    padding: 0.75rem 0.85rem;
    border: 1px solid var(--border-subtle, #e7e5e4);
    border-radius: 8px;
    background-color: var(--surface, #fff);
    color: var(--text-primary, #1a1a1a);
    transition: border-color 0.15s ease, transform 0.1s ease;
    height: 100%;
}
.search-verse-card:hover,
.search-verse-card:focus-visible {
    border-color: var(--text-primary, #1a1a1a);
    color: var(--text-primary, #1a1a1a);
    text-decoration: none;
    transform: translateY(-1px);
}
[data-theme="dark"] .search-verse-card {
    background-color: var(--surface, #1f1f1f);
    border-color: var(--border-subtle, #3a3a3a);
    color: var(--text-primary, #f5f5f4);
}
[data-theme="dark"] .search-verse-card:hover,
[data-theme="dark"] .search-verse-card:focus-visible {
    border-color: var(--text-primary, #f5f5f4);
}
.search-verse-ref {
    font-family: 'Inter', system-ui, sans-serif;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted, #6b6b6b);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 0.35rem;
}
.search-verse-text {
    font-family: 'Merriweather', Georgia, serif;
    font-size: 0.92rem;
    line-height: 1.5;
    /* Clamp to ~5 lines so cards stay roughly equal height in the grid. */
    display: -webkit-box;
    -webkit-line-clamp: 5;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.search-verse-tag {
    margin-top: 0.5rem;
    font-size: 0.72rem;
    color: var(--text-muted, #6b6b6b);
}
/* Expansion-sourced cards get a subtle amber left border so the user
   can tell at a glance which results came from concept expansion vs
   the literal lemma. */
.search-verse-card-expanded {
    border-left: 3px solid rgba(217, 119, 6, 0.6);
}

/* ===== Connection-code QR block (settings page) ===== */

.connection-qr {
    width: 140px;
    height: 140px;
    padding: 0.4rem;
    background-color: #fff;
    border: 1px solid var(--border, #e5e5e5);
    border-radius: 6px;
    flex-shrink: 0;
}

.connection-qr svg {
    display: block;
    width: 100%;
    height: 100%;
}

/* ===== Footer (v1.4: Mercy Court branding) =====

   Two logo <img>s are emitted (black + white); CSS swaps visibility on
   the [data-theme="dark"] root attribute — same mechanism as the favicon.
   Size is intentionally restrained (~28px) with light opacity so the
   mark sits quietly beneath the page content rather than dominating. */

.app-footer {
    padding: 0.25rem 0;
}

.app-footer-logo-link {
    display: inline-flex;
    align-items: center;
    opacity: 0.8;
    transition: opacity 0.2s ease;
}

.app-footer-logo-link:hover {
    opacity: 1;
}

.app-footer-logo {
    height: 48px;
    width: auto;
    display: block;
}

.app-footer-logo-dark {
    /* Light-mode default: the white logo is hidden. Dark mode flips via
       the rule below. */
    display: none;
}

[data-theme="dark"] .app-footer-logo-light {
    display: none;
}

[data-theme="dark"] .app-footer-logo-dark {
    display: block;
}

.app-footer-tagline {
    letter-spacing: 0.01em;
}

.app-footer-links a {
    text-decoration: none;
}

.app-footer-links a:hover {
    color: var(--text-primary, #1a1a1a) !important;
    text-decoration: underline;
}

/* ===== Legal pages (terms / privacy) ===== */

.legal-page {
    font-family: var(--font-body);
    line-height: 1.7;
}

.legal-page h2 {
    font-family: var(--font-ui);
    font-weight: 600;
    color: var(--text-primary, #1a1a1a);
}

.legal-page p,
.legal-page li {
    color: var(--text-primary, #1a1a1a);
}

.legal-page ul {
    padding-left: 1.25rem;
}

.legal-page ul li {
    margin-bottom: 0.35rem;
}

/* ===== Note title ===== */

.note-title {
    font-family: 'Inter', 'Arial Black', 'Arial Bold', Gadget, sans-serif;
    font-weight: 900;
    font-size: 2rem;
    line-height: 1.3;
    letter-spacing: -0.02em;
}

/* ===== Note action bar icons ===== */

.note-icon-btn {
    background: none;
    border: none;
    padding: 4px;
    cursor: pointer;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    transition: color 0.15s ease;
}

.note-icon-btn:hover {
    color: var(--text-primary);
}

/* v1.9.6: active-state for the fellowship-share toggle — note is
   currently shared with the owner's fellowship. Slightly darker +
   bolder than the rest of the icon row so it reads as "on". */
.note-icon-btn-active {
    color: var(--text-primary);
}

.note-icon-btn-active svg {
    stroke-width: 2.2;
}

/* v1.9.6: shared-notes section above the user's own list. Slightly
   indented byline + smaller-than-default avatar so the row reads
   as a "delivered to you" surface rather than your own work. */
.shared-note-byline {
    margin-top: 0.35rem;
}

.shared-note-byline .avatar-circle,
.shared-note-byline img {
    width: 20px !important;
    height: 20px !important;
    font-size: 0.6rem !important;
}

/* ===== Buttons ===== */

.btn-dark {
    background-color: var(--accent);
    border-color: var(--accent);
    font-family: var(--font-ui);
    font-weight: 500;
    font-size: 0.875rem;
    padding: 0.5rem 1.5rem;
    border-radius: 4px;
}

.btn-outline-dark {
    font-family: var(--font-ui);
    font-weight: 500;
    font-size: 0.875rem;
    border-radius: 4px;
}

/* ===== Accessibility ===== */

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

.visually-hidden-focusable:not(:focus):not(:focus-within) {
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
}

/* ===== Verse highlight ===== */

.verse-highlight {
    background-color: var(--highlight-verse);
    padding: 2px 4px;
    border-radius: 2px;
}

/* ===== Verse numbers ===== */

sup.verse-num {
    font-family: var(--font-ui);
    font-size: 65%;
    color: var(--text-secondary);
    font-weight: 400;
    margin-right: 2px;
    vertical-align: super;
}

/* ===== Alerts / flash messages ===== */

.alert {
    font-family: var(--font-ui);
    font-size: 0.875rem;
    border-radius: 4px;
}

/* ===== Footer ===== */

footer {
    font-family: var(--font-ui);
    border-color: var(--border) !important;
}

/* ===== Fellowship rank badges (v1.9.5) =====
   Tiny pill under the display name on /@handle when the profile
   owner has crossed a follower threshold. Three palettes — Teacher
   (slate), Pastor (amber), Apostle (rust) — so each rank has a
   distinct silhouette without dragging in a colour-coded UI mess
   elsewhere in the app. */

.rank-badge {
    display: inline-block;
    margin-top: 0.3rem;
    padding: 0.15rem 0.55rem;
    font-family: var(--font-ui);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-radius: 999px;
    border: 1px solid transparent;
    line-height: 1.4;
}

.rank-badge-teacher {
    background-color: rgba(71, 85, 105, 0.1);
    color: #475569;
    border-color: rgba(71, 85, 105, 0.25);
}

.rank-badge-pastor {
    background-color: rgba(217, 119, 6, 0.1);
    color: #b45309;
    border-color: rgba(217, 119, 6, 0.3);
}

.rank-badge-apostle {
    background-color: rgba(192, 57, 43, 0.1);
    color: #c0392b;
    border-color: rgba(192, 57, 43, 0.3);
}

[data-theme="dark"] .rank-badge-teacher {
    background-color: rgba(148, 163, 184, 0.15);
    color: #cbd5e1;
    border-color: rgba(148, 163, 184, 0.35);
}

[data-theme="dark"] .rank-badge-pastor {
    background-color: rgba(251, 191, 36, 0.15);
    color: #fbbf24;
    border-color: rgba(251, 191, 36, 0.35);
}

[data-theme="dark"] .rank-badge-apostle {
    background-color: rgba(248, 113, 113, 0.15);
    color: #f87171;
    border-color: rgba(248, 113, 113, 0.35);
}

/* ===== Mobile bottom tab bar + Me sheet (v1.9 Phase 2) =====
   Desktop top navbar disappears below ``MOBILE_BREAKPOINT``; the
   bottom tab bar takes over primary navigation. The Me tab opens a
   bottom-anchored offcanvas (``.me-sheet``) that holds secondary
   destinations + the notifications block + theme toggle + log out.
   Bar height is in ``--bottom-nav-height`` so any page can pad its
   bottom by that amount + safe-area-inset.

   Breakpoint: 768px (Bootstrap's md). iPhones / small phones get
   the new mobile look; iPad portrait + everything bigger keeps the
   existing top nav. */

:root {
    --bottom-nav-height: 64px;
}

.bottom-nav,
.me-sheet {
    /* Hidden by default; shown only on mobile via the media query
       below. Also hidden when the Me sheet's parent template
       branch isn't rendered (anonymous users). */
    display: none;
}

@media (max-width: 767.98px) {
    /* Hide the desktop top navbar on phones — its function is
       fully replaced by the bottom bar + Me sheet. *Only* for
       authenticated users (``.navbar-authed`` is appended in
       ``base.html`` when ``current_user.is_authenticated``).
       Anonymous mobile users keep the desktop navbar visible so
       they can still see the brand mark and reach Log in /
       Register — the bottom nav doesn't render for them. */
    body > nav.navbar.navbar-authed {
        display: none !important;
    }

    .bottom-nav {
        display: flex;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 1040;
        height: calc(var(--bottom-nav-height) + env(safe-area-inset-bottom, 0px));
        padding-bottom: env(safe-area-inset-bottom, 0px);
        background-color: var(--surface, #fff);
        border-top: 1px solid var(--border, #e5e5e5);
        box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.04);
        font-family: var(--font-ui);
    }

    [data-theme="dark"] .bottom-nav {
        background-color: var(--surface, #1a1a1a);
        border-top-color: var(--border, #2a2a2a);
        box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.4);
    }

    /* Body padding so the last bit of page content isn't covered
       by the fixed bar. Containers / cards still scroll under it
       — only the absolute baseline of the page gets the gutter. */
    body {
        padding-bottom: calc(var(--bottom-nav-height)
                             + env(safe-area-inset-bottom, 0px) + 0.25rem);
    }
}

.bottom-nav-tab {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    padding: 0.4rem 0.25rem 0.45rem;
    background: transparent;
    border: none;
    color: var(--text-secondary, #6b7280);
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    transition: color 0.12s ease;
}

.bottom-nav-tab:hover,
.bottom-nav-tab:focus-visible {
    color: var(--text-primary, #1a1a1a);
    outline: none;
}

.bottom-nav-tab.active {
    color: var(--text-primary, #1a1a1a);
}

/* v1.9.9: active tab fills the icon SVG — the inactive tabs use
   stroke-only Lucide glyphs (``fill="none"``), and flipping to
   ``fill: currentColor`` on active gives a clear at-a-glance
   "this is the page you're on" signal without needing a separate
   icon set. ``currentColor`` picks up the same theme-aware tone
   as the surrounding text colour, so it's pure black on light
   and pure white on dark for free. */
.bottom-nav-tab.active .bottom-nav-icon svg {
    fill: currentColor;
}

.bottom-nav-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
    width: 26px;
    height: 26px;
}

.bottom-nav-icon svg {
    width: 22px;
    height: 22px;
}

.bottom-nav-icon-avatar img,
.bottom-nav-icon-avatar .avatar-circle {
    width: 24px !important;
    height: 24px !important;
    font-size: 0.7rem;
}

.bottom-nav-label {
    font-size: 0.65rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    line-height: 1;
}

/* Active-tab underline accent — subtle but legible. Matches the
   icon colour above so the active tab reads as one cluster. */
.bottom-nav-tab.active::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 28px;
    height: 2px;
    background-color: var(--text-primary, #1a1a1a);
    border-radius: 0 0 2px 2px;
}

/* Me-tab unread-notifications dot. Small red presence indicator
   on the avatar; the actual count + list lives in the Me sheet's
   notifications block. */
.bottom-nav-dot {
    position: absolute;
    top: -2px;
    right: -2px;
    min-width: 0.5rem;
    width: 0.5rem;
    height: 0.5rem;
    padding: 0;
    border-radius: 50%;
    background-color: #c0392b;
    border: 2px solid var(--surface, #fff);
    color: transparent;       /* hide the count text — dot only */
    font-size: 0;
    overflow: hidden;
    line-height: 0;
}

[data-theme="dark"] .bottom-nav-dot {
    border-color: var(--surface, #1a1a1a);
}

/* ── Me sheet (offcanvas) ────────────────────────────────────── */

.me-sheet {
    /* v1.16: full-screen height (was max-height: 88vh) so the
       account menu, theme toggle, and Log out are always reachable
       without the user having to scroll inside a cramped bottom
       sheet. Bootstrap 5 drives ``.offcanvas-bottom`` height via
       the ``--bs-offcanvas-height`` variable (default 30vh), so
       overriding the variable is the cleanest way to work *with*
       the framework instead of fighting it. ``100dvh`` respects
       iOS Safari's URL-bar show/hide; ``100vh`` is the fallback.
       Border-radius dropped because a full-screen sheet flush to
       the screen edges shouldn't carry rounded corners. */
    --bs-offcanvas-height: 100vh;
    --bs-offcanvas-height: 100dvh;
    height: 100vh;
    height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    border-radius: 0;
    /* Theme-aware surface — Bootstrap 5's ``.offcanvas`` paints
       ``background-color: var(--bs-offcanvas-bg, #fff)`` and
       ``color: var(--bs-offcanvas-color)``. We re-bind those
       variables to our own surface tokens so the theme flip on
       ``[data-theme="dark"]`` (which only updates ``--surface`` /
       ``--text-primary``) propagates here too. Direct
       ``background-color`` is belt-and-suspenders for browsers
       that haven't picked up the CSS-vars rebinding yet. */
    --bs-offcanvas-bg: var(--surface, #fff);
    --bs-offcanvas-color: var(--text-primary, #1a1a1a);
    --bs-offcanvas-border-color: var(--border, #e5e5e5);
    background-color: var(--surface, #fff);
    color: var(--text-primary, #1a1a1a);
}

/* Bootstrap's close-button glyph is a black SVG that disappears
   on a dark surface — invert it so the X stays readable. */
[data-theme="dark"] .me-sheet .btn-close {
    filter: invert(1) grayscale(1) brightness(1.6);
}

@media (max-width: 767.98px) {
    /* The offcanvas itself is rendered into the DOM at all sizes
       (so the script can find it) but only displayed via Bootstrap
       on mobile — we override the bare ``display: none`` from above. */
    .me-sheet.show,
    .me-sheet.showing,
    .me-sheet.hiding {
        display: flex;
    }
}

.me-sheet-header {
    align-items: center;
    border-bottom: 1px solid var(--border, #e5e5e5);
    padding: 1rem 1.25rem 0.85rem;
}

.me-sheet-name {
    font-family: var(--font-ui);
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1.2;
    color: var(--text-primary, #1a1a1a);
}

.me-sheet-handle {
    font-size: 0.78rem;
    color: var(--text-secondary, #6b7280);
}

.me-sheet-body {
    padding: 0.5rem 0.5rem 1.25rem;
    overflow-y: auto;
}

.me-sheet-section {
    padding: 0.5rem 0.75rem;
}

.me-sheet-section-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 0.25rem 0.25rem 0.5rem;
}

.me-sheet-section-label {
    font-family: var(--font-ui);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary, #6b7280);
}

.me-sheet-notifications .notif-list {
    max-height: 30vh;
    overflow-y: auto;
}

/* v1.9.12: cap the Me-sheet notifications list to 10 rows on
   mobile so the sheet doesn't grow tall and crowd everything
   below it. The poller still fetches up to 20 (used by the
   desktop bell dropdown); rows 11+ are simply hidden in the
   sheet. Deleting a visible row via swipe re-fetches and the
   next-most-recent slides up to fill the slot. */
@media (max-width: 767.98px) {
    .me-sheet-notif-list .notif-row:nth-child(n+11) {
        display: none;
    }
}

/* v1.9.12: visual baseline for swipe-to-delete — gives the row
   a paint surface so the ``transform: translateX()`` during the
   gesture doesn't reveal the row beneath through transparency.
   Also marks rows as touch-friendly (no double-tap zoom). */
.notif-row {
    background-color: var(--surface, #fff);
    touch-action: pan-y;  /* allow vertical scroll, capture horizontal swipe */
    will-change: transform, opacity;
}

[data-theme="dark"] .notif-row {
    background-color: var(--surface, #111);
}

.me-sheet-list {
    list-style: none;
    margin: 0.5rem 0;
    padding: 0;
}

.me-sheet-link {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.85rem 1rem;
    border-bottom: 1px solid var(--border, #e5e5e5);
    color: var(--text-primary, #1a1a1a);
    text-decoration: none;
    font-family: var(--font-ui);
    font-size: 0.95rem;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0.05);
}

.me-sheet-link:last-child {
    border-bottom: none;
}

.me-sheet-link:active {
    background-color: rgba(0, 0, 0, 0.04);
}

[data-theme="dark"] .me-sheet-link:active {
    background-color: rgba(255, 255, 255, 0.04);
}

.me-sheet-link-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    color: var(--text-secondary, #6b7280);
}

.me-sheet-link-icon svg {
    width: 20px;
    height: 20px;
}

.me-sheet-theme {
    border-top: 1px solid var(--border, #e5e5e5);
    border-bottom: 1px solid var(--border, #e5e5e5);
}

.me-sheet-theme-btn {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    width: 100%;
    background: transparent;
    border: none;
    padding: 0.85rem 0.25rem;
    color: var(--text-primary, #1a1a1a);
    font-family: var(--font-ui);
    font-size: 0.95rem;
    text-align: left;
    cursor: pointer;
}

.me-sheet-theme-btn .icon-moon,
.me-sheet-theme-btn .icon-sun {
    width: 20px;
    height: 20px;
    color: var(--text-secondary, #6b7280);
}

.me-sheet-theme-label {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.me-sheet-logout {
    display: block;
    margin: 1rem 1rem 0;
    padding: 0.75rem 1rem;
    border-radius: 10px;
    text-align: center;
    color: #c0392b;
    font-family: var(--font-ui);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    background-color: rgba(192, 57, 43, 0.05);
    border: 1px solid rgba(192, 57, 43, 0.15);
}

.me-sheet-logout:active {
    background-color: rgba(192, 57, 43, 0.1);
    color: #c0392b;
}

/* ─────────────────────────────────────────────────────────────────
   v1.12.4 — Notes list ellipsis menu.

   Rows on /notes restructured from ``<a>`` to flex-row ``<div>``
   so the per-row dropdown trigger isn't nested inside an anchor.
   These rules restore the hover-link feel ``list-group-item-action``
   used to provide on the old anchor row.
   ───────────────────────────────────────────────────────────────── */
.note-list-row {
    transition: background-color 0.12s ease;
}

.note-list-row:hover,
.note-list-row:focus-within {
    background-color: var(--surface-raised);
}

.note-list-link {
    color: var(--text-primary);
    min-width: 0; /* allow flex sibling to truncate cleanly */
}

.note-list-link:hover h6,
.note-list-link:focus h6 {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

.note-list-ellipsis {
    color: var(--text-secondary);
    line-height: 1;
    border-radius: 4px;
}

.note-list-ellipsis:hover,
.note-list-ellipsis:focus,
.note-list-ellipsis[aria-expanded="true"] {
    color: var(--text-primary);
    background-color: var(--surface);
    text-decoration: none;
}

.note-list-actions .dropdown-menu {
    font-size: 0.875rem;
    min-width: 11rem;
}

.note-list-actions .dropdown-item {
    padding: 0.5rem 1rem;
}

[data-theme="dark"] .note-list-row:hover,
[data-theme="dark"] .note-list-row:focus-within {
    background-color: var(--surface-raised);
}

/* ===== Reader copyright footer (v1.14) ============================
   Renders below the chapter-nav on /bible/<v>/<b>/<c> and
   /scripture/<v>/<b>/<c>. Required for compliance on the proprietary
   versions (NLT / AMPC / GW); inline style notes for the public-domain
   ones too. Visually muted so it sits below the chapter content
   without competing for attention. */

.bible-copyright {
    margin-top: 1.25rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-subtle, #e7e5e4);
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--text-muted, #6b6b6b);
    font-family: 'Inter', system-ui, sans-serif;
}

.bible-copyright p {
    margin: 0;
}

/* Permissions link inherits the muted colour but underlines on
   hover so the click affordance is clear. */
.bible-copyright a {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: var(--border-subtle, #e7e5e4);
    text-underline-offset: 2px;
}

.bible-copyright a:hover,
.bible-copyright a:focus-visible {
    color: var(--text-primary, #1a1a1a);
    text-decoration-color: currentColor;
}

[data-theme="dark"] .bible-copyright a:hover,
[data-theme="dark"] .bible-copyright a:focus-visible {
    color: var(--text-primary, #f5f5f4);
}
