/* ═══════════════════════════════════════════════════════
   DATABAY JOURNAL — blog_theme.css
   Shared dark "technical editorial" tokens + primitives for
   the blog routes ONLY (/blog, /blog/{slug}). Loaded by
   Blog.cshtml and BlogTemplate.cshtml BEFORE the page CSS.
   Never imported by non-blog pages.

   Design language: type-led editorial journal on the site's
   navy family — hairlines instead of cards, JetBrains Mono
   for ALL metadata (the "log line" signature), one serif
   display face for headlines, cyan as the single accent.
   ═══════════════════════════════════════════════════════ */

/* ─── Display serif: Source Serif 4 SemiBold (latin subset, self-hosted) ───
   Why Source Serif 4 over Spectral / Newsreader:
   - It is the serif companion of the Source Sans / Source Code superfamily,
     i.e. a face literally designed to sit next to monospace code — the exact
     pairing this journal runs (serif headline + JetBrains Mono metadata).
   - Low stroke contrast and sturdy slab-ish serifs hold their weight on a
     dark navy canvas; high-contrast faces (Spectral, Newsreader) sparkle and
     thin out when reversed light-on-dark at display sizes.
   - One weight (600) at 21.5 KB woff2 keeps the whole face inside the asset
     budget; headlines never need a second weight.
   Single source of truth for the file: the preload <link> in the two blog
   views must stay byte-identical to this src (same rule as Mulish 800). */
@font-face {
    font-family: 'Source Serif 4';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/fonts/source-serif-4-v5-latin-600.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Metric-matched local fallback so the swap from Georgia to Source Serif 4
   produces no layout shift on the headline (the LCP surface). Numbers are
   computed from the real font tables: SS4-600 avg latin advance 491.2/1000em
   vs Georgia 913.1/2048em -> size-adjust 110.17%; overrides = SS4 metrics
   (asc 1036, desc 335, gap 0) divided by the size-adjust. */
@font-face {
    font-family: 'Source Serif 4 Fallback';
    src: local('Georgia');
    size-adjust: 110.17%;
    ascent-override: 94.04%;
    descent-override: 30.41%;
    line-gap-override: 0%;
}

/* ─── Journal tokens (blog-scoped; brand constants reuse --db-*) ─── */
:root {
    /* Canvas — derived from the site navy family (--db-navy #091B36,
       header dark #0a0f1e, footer floor #050c1a). */
    --blog-bg: #0B1426;
    --blog-bg-deep: #0a0f1e;       /* hero band, matches the dark header */
    --blog-surface: #0E1830;       /* code blocks, raised panels */
    --blog-hairline: rgba(148, 179, 225, 0.14);
    --blog-hairline-strong: rgba(148, 179, 225, 0.28);

    /* Ink — all pairs >= 4.5:1 on --blog-bg (verified):
       text 16.2:1, body 11.7:1, muted 7.1:1, faint 5.7:1, accent 8.6:1. */
    --blog-text: #ECF1FA;
    --blog-body: #C3CFE3;
    --blog-muted: #8FA2C0;
    --blog-faint: #7E91B0;

    /* ONE accent: the brand cyan (--db-cyan). Used sparingly — links,
       active TOC tick, the ledger tick, focus rings. Never as a fill. */
    --blog-accent: #15C1E6;
    --blog-accent-soft: rgba(21, 193, 230, 0.12);
    --blog-accent-hairline: rgba(21, 193, 230, 0.35);

    /* Type */
    --blog-serif: 'Source Serif 4', 'Source Serif 4 Fallback', Georgia, 'Times New Roman', serif;
    --blog-sans: var(--db-font, 'Mulish', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);
    --blog-mono: var(--db-font-mono, 'JetBrains Mono', 'Fira Code', Consolas, monospace);

    /* Measure + breakout (B7: 72ch prose, media may break out to column) */
    --blog-measure: 72ch;
    --blog-column: 920px;

    /* Single source of truth for every "clear the fixed header" offset
       (sticky TOC top, sticky table headers, scroll-margin on anchors).
       Tracks the real header bar: shared/header.css sets --db-head-h to
       72px / 64px (<=992) / 56px (<=576) in lockstep with the bar height. */
    --blog-header-offset: var(--db-head-h, 72px);
}

/* ─── Canvas ─── */
body.db-journal {
    background: var(--blog-bg);
    color: var(--blog-body);
}
body.db-journal .db-page {
    color: var(--blog-body);
}
body.db-journal ::selection {
    background: rgba(21, 193, 230, 0.28);
    color: #ffffff;
}
body.db-journal :focus-visible {
    outline: 2px solid var(--blog-accent);
    outline-offset: 2px;
    border-radius: 2px;
}

/* ─── Shared primitives ─── */

/* Mono eyebrow: small category/label line above headlines. */
.bj-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    font-family: var(--blog-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--blog-muted);
}
.bj-eyebrow::before {
    content: '';
    width: 1.25rem;
    height: 1px;
    background: var(--blog-accent);
    flex-shrink: 0;
}

/* Mono ledger line — the signature "log line" for ALL metadata:
   PUBLISHED 2026-05-07 · UPDATED 2026-06-10 · 17 MIN READ · 4,210 WORDS */
.bj-ledger {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.375rem 0;
    font-family: var(--blog-mono);
    font-size: 0.75rem;
    font-weight: 400;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--blog-muted);
    font-variant-numeric: tabular-nums;
}
.bj-ledger time { color: inherit; }
.bj-seg { white-space: nowrap; }
/* Separator middots live in a ::before of the FOLLOWING segment; inline-block
   makes them atomic so a linked segment's underline never runs under the dot
   (text-decoration does not propagate into atomic inline boxes). */
.bj-seg + .bj-seg::before {
    content: '\00B7';
    display: inline-block;
    margin: 0 0.75em;
    color: var(--blog-faint);
}
a.bj-seg {
    color: var(--blog-muted);
    text-decoration: underline;
    text-decoration-color: var(--blog-hairline-strong);
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
    transition: color 0.15s ease, text-decoration-color 0.15s ease;
}
a.bj-seg:hover {
    color: var(--blog-accent);
    text-decoration-color: var(--blog-accent-hairline);
}

/* Hairline rule */
.bj-rule {
    border: 0;
    height: 1px;
    background: var(--blog-hairline);
    margin: 0;
}

/* Hero-only hairline grid texture (industrial blueprint tone — the ONLY
   permitted depth element, never used in the article body). */
.bj-hero-grid {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background-image:
        linear-gradient(var(--blog-hairline) 1px, transparent 1px),
        linear-gradient(90deg, var(--blog-hairline) 1px, transparent 1px);
    background-size: 64px 64px;
    opacity: 0.22;
    -webkit-mask-image: radial-gradient(ellipse 90% 80% at 50% 0%, #000 35%, transparent 78%);
    mask-image: radial-gradient(ellipse 90% 80% at 50% 0%, #000 35%, transparent 78%);
}

/* ─── Motion: ONE restrained signature ───
   Hero support elements (eyebrow, ledger, rule) rise in on load. Pure CSS,
   runs without JS, and is NEVER applied to the H1 or to body prose — the
   LCP headline and the article text paint instantly (D15/A5 stay true). */
@keyframes bj-rise {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}
.bj-rise   { animation: bj-rise 0.5s var(--db-ease, cubic-bezier(0.16, 1, 0.3, 1)) 0.05s both; }
.bj-rise-2 { animation: bj-rise 0.5s var(--db-ease, cubic-bezier(0.16, 1, 0.3, 1)) 0.15s both; }
.bj-rise-3 { animation: bj-rise 0.5s var(--db-ease, cubic-bezier(0.16, 1, 0.3, 1)) 0.25s both; }

@media (prefers-reduced-motion: reduce) {
    .bj-rise, .bj-rise-2, .bj-rise-3 { animation: none; }
    body.db-journal * { scroll-behavior: auto; }
}

/* ─── Sitewide pre-footer, journal routes ───
   _Footer ships two conversion/recirculation bands before the footer proper:
   the "Latest from the Blog" card grid (_BlogListPartial) and the gradient
   "Start Using Rotating Proxies Today" CTA (_StartNow). On journal pages both
   re-inject exactly the cookie-cutter pattern the redesign removed - on an
   article, card 1 is frequently the article being read, and the journal
   already carries its own "Continue Reading" ledger rows plus its single
   editorial CTA band (B6). The shared partials and their CSS stay untouched
   sitewide; these blog-scoped rules (this file loads on /blog routes only)
   simply keep them off the journal canvas. */
body.db-journal .db-blog-partial { display: none; }
body.db-journal .db-cta-gradient { display: none; }

/* ─── Mobile (<=480): the hero ledger stacks as a column ───
   Separator middots live in ::before of the FOLLOWING segment, so a wrapped
   ledger line would START with a dangling dot. Mirror what .blg-row__meta
   already does on the index: stack the segments, drop the separators. The
   floating Discord/Telegram stack also collides with the reading surface on
   390px screens - the journal collapses it to the single chat launcher. */
@media (max-width: 480px) {
    .db-article-hero__ledger,
    .blg-hero__facts {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.4375rem;
    }
    .db-article-hero__ledger .bj-seg + .bj-seg::before,
    .blg-hero__facts .bj-seg + .bj-seg::before {
        content: none;
        margin: 0;
    }
    body.db-journal .db-social-float { display: none; }
}

/* Print: the journal flattens to ink on paper. */
@media print {
    body.db-journal { background: #ffffff; color: #111111; }
    .bj-hero-grid { display: none; }
    .bj-eyebrow, .bj-ledger { color: #555555; }
    .bj-rule { background: #bbbbbb; }
}
