:root {
    --content-max-width: 880px;
    --content-gap: 2rem;
    --block-radius: 0.5rem;
    --block-padding: 1.5rem;
    --cms-card-glass-bg: rgba(20, 20, 22, 0.52);
    --cms-card-glass-blur: 7px;
    --cms-card-glass-saturate: 140%;
    --cms-title-text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
    --cms-teaser-title-color: #fff;
    --cms-teaser-scrim: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent);
    --font-family-heading: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-family-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* Site-wide typography, driven by the tokens above - a consuming app switches either
   family by redeclaring the same custom property in its own variables.css, without
   touching this file (see docs/css-theming.md). */
body {
    font-family: var(--font-family-body, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-family-heading, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
}

/* Block text color follows theme, not the editor's choice (no per-block color picker exists) - the
   glass background and title shadow must stay opaque/contrasty enough for that theme's text color
   regardless of how bright the page's own background image is, so both variants swap here rather
   than relying on a single fixed tint that only worked when the image happened to match the theme. */
@media (prefers-color-scheme: light) {
    :root {
        --cms-card-glass-bg: rgba(250, 250, 248, 0.52);
        --cms-title-text-shadow: 0 1px 3px rgba(255, 255, 255, 0.6);
    }
}

/* BitNavPanel's own .bit-npn sizes itself to var(--bit-env-height-avl), a value
   Bit's JS recomputes from the current scroll position - it assumes BitLayout
   itself is the app's scroll container, not the document, so it drifts once
   the document (not BitLayout) scrolls, as ours does. Pin it to a static
   calc() instead, and correct its own top:0 (which would tuck it under our
   custom header) to sit below the header. !important guards against Bit's
   own stylesheet having equal specificity. */
.bit-npn {
    top: var(--header-height, 56px) !important;
    height: calc(100vh - var(--header-height, 56px)) !important;
}

/* BitLayout's own .bit-lyt-man ("Main" region, wrapping our header + article.main)
   sizes itself to a flat 100vh, unaware that our custom header already consumes
   var(--header-height) above it - since it starts right after the header in normal
   flow, that leaves it 100vh + header-height tall overall, spilling a header-height
   sized empty bar below the actual page content (visible past the footer and next
   to the nav panel on any page, most obviously on short ones). Pin it to the same
   header-aware calc() as .bit-npn above so it ends exactly at the viewport bottom. */
.bit-lyt-man {
    height: calc(100vh - var(--header-height, 56px)) !important;
    min-height: calc(100vh - var(--header-height, 56px)) !important;
}

.skeleton-shimmer {
    background: linear-gradient(90deg, var(--bit-clr-bg-ter) 25%, var(--bit-clr-bg-pri-light) 50%, var(--bit-clr-bg-ter) 75%);
    background-size: 200% 100%;
    animation: skeleton-shimmer 1.5s ease-in-out infinite, skeleton-pulse 2s ease-in-out infinite;
    border-radius: 4px;
}

@keyframes skeleton-shimmer {
    0% {
        background-position: 200% 0;
    }

    100% {
        background-position: -200% 0;
    }
}

@keyframes skeleton-pulse {
    0%, 100% {
        opacity: 1;
    }

    50% {
        opacity: 0.6;
    }
}