/* =======================================================================
   writing.css — Quiet Signals Lab writing section
   Separate from the main styles.css so post-specific styling is isolated.
   This file is self-contained: it does not import styles.css because
   the writing section has its own layout model.
   ======================================================================= */

/* ── Self-hosted fonts ──────────────────────────────────────────────────
   Source Serif 4: body text for the reading column.
   Chosen over Georgia (too web-circa-2005) and Palatino (platform variance
   is too high). Source Serif 4 is designed for screen reading, has good
   optical compensation at text sizes, and is available under OFL.

   JetBrains Mono: code. Good x-height, clear zero/O disambiguation,
   open source, and compact enough to fit ~80 chars in the column without
   overflow at 0.875rem.

   Both served as woff2 (Latin subset only) from /fonts/ for privacy —
   no external font requests.
   ---------------------------------------------------------------------- */

@font-face {
    font-family: 'Source Serif 4';
    src: url('../fonts/source-serif-4-latin-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Source Serif 4';
    src: url('../fonts/source-serif-4-latin-400italic.woff2') format('woff2');
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

@font-face {
    font-family: 'Source Serif 4';
    src: url('../fonts/source-serif-4-latin-700.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'JetBrains Mono';
    src: url('../fonts/jetbrains-mono-latin-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'JetBrains Mono';
    src: url('../fonts/jetbrains-mono-latin-400italic.woff2') format('woff2');
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

/* ── Design tokens ──────────────────────────────────────────────────────
   Color rationale:
   - Text: #1c1c1a — very near-black with a barely perceptible warm tint.
     Pure #000 reads as harsh on screen; this is softer without sacrificing
     contrast (WCAG AA at body sizes, AAA at display sizes).
   - Background: #f7f5f1 — matches the main site's off-white exactly.
     Warm newsprint undertone; not pure white.
   - Accent: #be6e19 — amber, matches the main site accent exactly.
     Used on links, the header rule, and active states only.
   - Secondary text: #5a5a57 — warmed-down gray for dates, captions,
     reading time. Clearly subordinate but not invisible.
   - Code background: #edeae3 — matches the main site's light-bg token,
     same warm key, no hue shift. Marks code as distinct.
   ---------------------------------------------------------------------- */
:root {
    /* Colors — light mode */
    --w-bg:           #f7f5f1;
    --w-text:         #1c1c1a;
    --w-secondary:    #5a5a57;
    --w-accent:       #be6e19;
    --w-accent-dark:  #a05c14;
    --w-border:       #dedad3;
    --w-code-bg:      #edeae3;
    --w-code-text:    #2a2927;
    --w-mark-bg:      rgba(190, 110, 25, 0.12);

    /* Typography */
    --w-body-font:    'Source Serif 4', Georgia, 'Times New Roman', serif;
    --w-head-font:    'Avenir Next', 'Avenir', -apple-system, BlinkMacSystemFont, sans-serif;
    --w-mono-font:    'JetBrains Mono', 'Courier New', monospace;

    /* Type scale — Major Third (×1.25) anchored at 1.125rem (18px)
       h4  → 1.125rem  (equal to body, used as a run-in label)
       h3  → 1.25rem   (×1.11 step, sub-section)
       h2  → 1.563rem  (×1.25)
       h1  → 2.441rem  (×1.25²; post title only — never used inline)
       Rationale: Major Third produces a readable hierarchy without the
       aggressive jumps of Perfect Fourth that strain narrow columns. */
    --w-size-base:    1.125rem;   /* 18px body */
    --w-size-sm:      0.875rem;   /* 14px captions, meta */
    --w-size-xs:      0.75rem;    /* 12px labels */
    --w-size-h4:      1.125rem;
    --w-size-h3:      1.25rem;
    --w-size-h2:      1.563rem;
    --w-size-h1:      2.441rem;

    /* Content width: 68ch ≈ 65-70 chars per line at 18px Source Serif 4.
       ch is relative to the '0' glyph width in the current font, so this
       tracks the body font correctly even if the font changes. */
    --w-content-width: 68ch;
    --w-wide-content:  90ch;   /* wide figures stop here, not full viewport */
    --w-max-width:     1200px;

    /* Spacing */
    --w-sp-xs: 0.5rem;
    --w-sp-sm: 1rem;
    --w-sp-md: 1.5rem;
    --w-sp-lg: 2.5rem;
    --w-sp-xl: 4rem;

    /* Line heights */
    --w-lh-body:  1.7;
    --w-lh-heads: 1.2;
    --w-lh-tight: 1.3;
    --w-lh-code:  1.6;
}

/* ── Reset / base ───────────────────────────────────────────────────── */
*, *::before, *::after {
    box-sizing: border-box;
}

html {
    font-size: 16px;
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--w-bg);
    color: var(--w-text);
    font-family: var(--w-body-font);
    font-size: var(--w-size-base);
    line-height: var(--w-lh-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ── Site header (writing section) ──────────────────────────────────── */
.site-header {
    position: sticky;
    top: 0;
    z-index: 200;
    background: var(--w-bg);
    border-bottom: 1px solid var(--w-border);
    backdrop-filter: blur(8px);
    /* Slightly transparent so stickied header doesn't blank out content */
    background-color: color-mix(in srgb, var(--w-bg) 95%, transparent);
}

.site-header-inner {
    max-width: var(--w-max-width);
    margin: 0 auto;
    padding: 0.75rem var(--w-sp-md);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--w-sp-md);
}

.site-brand {
    font-family: var(--w-head-font);
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--w-text);
    text-decoration: none;
}

.site-brand:hover {
    color: var(--w-accent);
}

.site-nav {
    display: flex;
    align-items: center;
    gap: var(--w-sp-md);
    list-style: none;
    margin: 0;
    padding: 0;
}

.site-nav a {
    font-family: var(--w-head-font);
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--w-secondary);
    text-decoration: none;
    transition: color 0.15s ease;
}

.site-nav a:hover,
.site-nav a[aria-current="page"] {
    color: var(--w-accent);
}

/* ── Writing index page ─────────────────────────────────────────────── */
.writing-index {
    max-width: var(--w-max-width);
    margin: 0 auto;
    padding: var(--w-sp-xl) var(--w-sp-md);
}

.writing-index-header {
    max-width: var(--w-content-width);
    margin: 0 auto var(--w-sp-xl);
    padding-bottom: var(--w-sp-lg);
    border-bottom: 2px solid var(--w-text);
}

.writing-index-header h1 {
    font-family: var(--w-head-font);
    font-size: var(--w-size-h2);
    font-weight: 700;
    line-height: var(--w-lh-heads);
    letter-spacing: -0.02em;
    color: var(--w-text);
    margin: 0 0 var(--w-sp-sm);
}

.writing-index-header p {
    font-size: 0.95rem;
    color: var(--w-secondary);
    margin: 0;
    line-height: 1.6;
}

/* Post list */
.post-list {
    max-width: var(--w-content-width);
    margin: 0 auto;
    list-style: none;
    padding: 0;
}

.post-list-item {
    padding: var(--w-sp-md) 0;
    border-bottom: 1px solid var(--w-border);
}

/* ── Hidden posts ────────────────────────────────────────────────────────
   Add this class to a <li class="post-list-item"> to remove it from the
   listing without deleting the entry. The post's own URL remains live.
   Also comment out the matching <item> in feed.xml.
   ---------------------------------------------------------------------- */
.post-list-item.post-hidden {
    display: none;
}

.post-list-item:first-child {
    border-top: 1px solid var(--w-border);
}

.post-list-link {
    display: block;
    text-decoration: none;
    color: inherit;
}

.post-list-link:hover .post-list-title {
    color: var(--w-accent);
}

.post-list-title {
    font-family: var(--w-head-font);
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--w-text);
    margin: 0 0 0.35rem;
    line-height: var(--w-lh-tight);
    transition: color 0.15s ease;
}

.post-list-desc {
    font-size: 0.9rem;
    color: var(--w-secondary);
    margin: 0 0 0.5rem;
    line-height: 1.55;
}

.post-list-meta {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: var(--w-size-sm);
    color: var(--w-accent);
    font-family: var(--w-head-font);
}

.post-list-meta time {
    /* Dates displayed as "15 June 2026". Using machine-readable datetime
       attribute on the <time> element while displaying human text. */
}

.post-list-meta .sep {
    color: var(--w-border);
}

/* ── Article layout — CSS Grid breakout column ──────────────────────── */
/*
   The layout uses a named-line CSS Grid to enable "breaking out" of the
   reading column for wide figures without JavaScript or negative margins.

   Columns:
     [full-start] 1fr [content-start] min(68ch, 100%) [content-end] 1fr [full-end]

   All direct children default to the content column.
   Adding .figure-wide moves an element to span the full track.
   On narrow viewports, the 1fr side columns collapse to 0, so
   figure-wide naturally becomes column-width on mobile.
*/
.article-layout {
    padding: var(--w-sp-xl) var(--w-sp-md);
}

.article-body {
    display: grid;
    grid-template-columns:
        [full-start] 1fr
        [content-start] min(var(--w-content-width), 100%)
        [content-end] 1fr
        [full-end];
    row-gap: 0; /* managed by margin-bottom on children */
}

.article-body > * {
    grid-column: content;
}

/* ── Post header ─────────────────────────────────────────────────────── */
.post-header {
    grid-column: content;
    padding-bottom: var(--w-sp-lg);
    margin-bottom: var(--w-sp-lg);
    border-bottom: 1px solid var(--w-border);
}

.post-title {
    font-family: var(--w-head-font);
    font-size: var(--w-size-h1);
    font-weight: 700;
    line-height: var(--w-lh-heads);
    letter-spacing: -0.025em;
    color: var(--w-text);
    margin: 0 0 var(--w-sp-sm);
}

.post-subtitle {
    font-size: 1.1rem;
    color: var(--w-secondary);
    line-height: 1.5;
    margin: 0 0 var(--w-sp-md);
    font-style: italic;
}

.post-meta {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-family: var(--w-head-font);
    font-size: var(--w-size-sm);
    color: var(--w-secondary);
}

.post-meta time { /* datetime attribute carries machine-readable format */ }

.post-meta .sep {
    color: var(--w-border);
}

.reading-time {
    /* Computed by JS snippet in the post — see bottom of _template.html */
    font-variant-numeric: tabular-nums;
}

/* ── Body typography ─────────────────────────────────────────────────── */
.article-body p {
    margin: 0 0 var(--w-sp-md);
}

.article-body p:last-child {
    margin-bottom: 0;
}

/* ── Headings (h2–h4; h1 is post title only) ────────────────────────── */
.article-body h2 {
    font-family: var(--w-head-font);
    font-size: var(--w-size-h2);
    font-weight: 700;
    line-height: var(--w-lh-heads);
    letter-spacing: -0.02em;
    color: var(--w-text);
    margin: var(--w-sp-xl) 0 var(--w-sp-sm);
    padding-top: 0;
}

.article-body h3 {
    font-family: var(--w-head-font);
    font-size: var(--w-size-h3);
    font-weight: 600;
    line-height: var(--w-lh-heads);
    letter-spacing: -0.01em;
    color: var(--w-text);
    margin: var(--w-sp-lg) 0 var(--w-sp-sm);
}

.article-body h4 {
    font-family: var(--w-head-font);
    font-size: var(--w-size-h4);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--w-secondary);
    margin: var(--w-sp-lg) 0 var(--w-sp-xs);
}

/* ── Links ───────────────────────────────────────────────────────────── */
.article-body a {
    color: var(--w-accent);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
    transition: color 0.15s ease;
}

.article-body a:hover {
    color: var(--w-accent-dark);
}

/* ── Lists ───────────────────────────────────────────────────────────── */
.article-body ul,
.article-body ol {
    padding-left: 1.5rem;
    margin: 0 0 var(--w-sp-md);
}

.article-body li {
    margin-bottom: 0.4rem;
}

.article-body li:last-child {
    margin-bottom: 0;
}

/* ── Blockquote: editorial, not techbro ─────────────────────────────── */
.article-body blockquote {
    margin: var(--w-sp-lg) 0;
    padding: var(--w-sp-sm) 0 var(--w-sp-sm) var(--w-sp-md);
    border-left: 3px solid var(--w-accent);
    font-style: italic;
    color: var(--w-secondary);
}

.article-body blockquote p {
    margin: 0;
}

.article-body blockquote p + p {
    margin-top: var(--w-sp-sm);
}

/* ── Code ────────────────────────────────────────────────────────────── */
/* Inline code: subtle tint, no padding that shifts baselines */
.article-body code {
    font-family: var(--w-mono-font);
    font-size: 0.85em; /* relative to surrounding body text */
    background: var(--w-code-bg);
    color: var(--w-code-text);
    padding: 0.1em 0.35em;
    border-radius: 3px;
    border: 1px solid color-mix(in srgb, var(--w-border) 80%, transparent);
}

/* Block code: override Prism defaults to match editorial feel */
.article-body pre {
    grid-column: content; /* stays in column by default */
    margin: var(--w-sp-md) 0 var(--w-sp-lg);
    border-radius: 4px;
    overflow-x: auto; /* horizontal scroll on narrow viewports, no layout break */
    -webkit-overflow-scrolling: touch;
    background: var(--w-code-bg) !important; /* override Prism theme */
    border: 1px solid var(--w-border);
}

.article-body pre code {
    /* Reset the inline-code overrides inside block code */
    font-size: 0.875rem;
    background: transparent;
    color: var(--w-code-text);
    padding: 0;
    border: none;
    border-radius: 0;
    line-height: var(--w-lh-code);
    display: block;
    padding: var(--w-sp-md);
}

/* Prism token colours that work on both light and dark backgrounds */
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata          { color: #8a9099; font-style: italic; }

.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol         { color: #c9783f; }

.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin        { color: #3a8c56; }

.token.operator,
.token.entity,
.token.url,
.token.variable       { color: var(--w-text); }

.token.atrule,
.token.attr-value,
.token.keyword        { color: var(--w-accent); }

.token.function       { color: #7c5db7; }

.token.regex,
.token.important      { color: #d97b4a; font-weight: bold; }

/* ── Figures and captions ────────────────────────────────────────────── */
.article-body figure {
    margin: var(--w-sp-lg) 0;
}

.article-body figure img {
    display: block;
    max-width: 100%;
    height: auto;
    border-radius: 3px;
    border: 1px solid var(--w-border);
}

.article-body figcaption {
    margin-top: 0.6rem;
    font-size: var(--w-size-sm);
    color: var(--w-secondary);
    font-style: italic;
    line-height: 1.5;
}

/*
   Wide figure breakout — uses the named grid columns defined on .article-body.
   Spans [full-start] to [full-end], capped at --w-wide-content for readability
   (full viewport-width figures on large monitors are too wide to follow).
   On viewports narrower than the content column, the 1fr columns collapse
   to zero, so .figure-wide falls back to exactly column width.
*/
.article-body .figure-wide {
    grid-column: full;
    max-width: var(--w-wide-content);
    width: 100%;
    justify-self: center;
}

/* ── KaTeX math ──────────────────────────────────────────────────────── */
/* Inline math: let it flow with body text */
.katex { font-size: 1em; }

/* Display math: centered, with breathing room */
.katex-display {
    margin: var(--w-sp-md) 0;
    overflow-x: auto;
    overflow-y: hidden;
    padding: var(--w-sp-xs) 0;
}

/* ── Footnotes ───────────────────────────────────────────────────────── */
/*
   Footnotes use a pure anchor-link pattern. Numbered with <sup><a href="#fnN">
   in-text, collected in an <ol class="footnotes"> at the end of the article.
   No JavaScript required. Each footnote links back up with a ↩ character.
*/
.article-body sup {
    font-size: 0.7em;
    line-height: 0;
    vertical-align: super;
}

.article-body sup a {
    color: var(--w-accent);
    text-decoration: none;
    font-family: var(--w-head-font);
    font-weight: 600;
}

.footnotes {
    grid-column: content;
    margin-top: var(--w-sp-xl);
    padding-top: var(--w-sp-md);
    border-top: 1px solid var(--w-border);
    font-size: var(--w-size-sm);
    color: var(--w-secondary);
    line-height: 1.6;
}

.footnotes ol {
    padding-left: 1.5rem;
    margin: var(--w-sp-xs) 0 0;
}

.footnotes li {
    margin-bottom: 0.5rem;
}

.footnotes a {
    color: var(--w-accent);
    text-decoration: none;
}

.footnotes a:hover {
    text-decoration: underline;
}

/* Back-to-content arrow */
.fn-back {
    margin-left: 0.3em;
    font-style: normal;
}

/* ── Post footer ─────────────────────────────────────────────────────── */
.post-footer {
    grid-column: content;
    margin-top: var(--w-sp-xl);
    padding-top: var(--w-sp-md);
    border-top: 1px solid var(--w-border);
    display: flex;
    flex-direction: column;
    gap: var(--w-sp-md);
}

.post-footer-author {
    font-size: var(--w-size-sm);
    color: var(--w-secondary);
    line-height: 1.6;
}

.post-footer-author strong {
    color: var(--w-text);
}

.post-footer-nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--w-sp-sm);
    font-family: var(--w-head-font);
    font-size: var(--w-size-sm);
}

.post-footer-nav a {
    color: var(--w-accent);
    text-decoration: none;
    font-weight: 500;
    transition: color 0.15s ease;
}

.post-footer-nav a:hover {
    color: var(--w-accent-dark);
    text-decoration: underline;
}

.post-footer-nav .sep {
    color: var(--w-border);
}

/* ── Site footer ─────────────────────────────────────────────────────── */
.site-footer {
    max-width: var(--w-max-width);
    margin: var(--w-sp-xl) auto 0;
    padding: var(--w-sp-md) var(--w-sp-md) var(--w-sp-lg);
    border-top: 1px solid var(--w-border);
    text-align: center;
    font-family: var(--w-head-font);
    font-size: var(--w-size-sm);
    color: var(--w-secondary);
    line-height: 1.7;
}

.site-footer p {
    margin: 0.2rem 0;
}

.site-footer a {
    color: var(--w-secondary);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.site-footer a:hover {
    color: var(--w-accent);
}

/* ── Horizontal rule ─────────────────────────────────────────────────── */
.article-body hr {
    border: none;
    border-top: 1px solid var(--w-border);
    margin: var(--w-sp-xl) 0;
}

/* ── Strong / em ─────────────────────────────────────────────────────── */
.article-body strong {
    font-weight: 700;
    color: var(--w-text);
}

.article-body em {
    font-style: italic;
}

/* ── Mark / highlight ────────────────────────────────────────────────── */
.article-body mark {
    background: var(--w-mark-bg);
    color: var(--w-text);
    padding: 0.05em 0.2em;
    border-radius: 2px;
}

/* ── Responsive ──────────────────────────────────────────────────────── */
/*
   Breakpoint rationale:
   - 768px: tablet threshold. Below this, the hero h1 drops, nav compresses.
     Post title scales down from 2.441rem to avoid overflow on portrait tablets.
   - 480px: phone. Post title scales to 1.75rem. Side padding tightens.
     Wide figures fall back to column-width (the 1fr columns are already
     zero, so no change needed in grid).
*/
@media (max-width: 768px) {
    .post-title {
        font-size: 1.953rem;
    }

    .writing-index-header h1 {
        font-size: 1.563rem;
    }

    .site-nav {
        gap: var(--w-sp-sm);
    }
}

@media (max-width: 480px) {
    .article-layout {
        padding: var(--w-sp-lg) var(--w-sp-sm);
    }

    .post-title {
        font-size: 1.75rem;
    }

    .post-meta {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.25rem;
    }

    .post-meta .sep {
        display: none;
    }

    .writing-index {
        padding: var(--w-sp-lg) var(--w-sp-sm);
    }

    .site-header-inner {
        padding: 0.6rem var(--w-sp-sm);
    }

    /* Hide secondary nav links on very small screens; keep brand visible */
    .site-nav-secondary {
        display: none;
    }
}
