/* static/css/base.css — layout + typography primitives.
 *
 * Second of the seven stylesheets split out of the former single
 * ``gallae.css`` (tasks/FILE_SPLIT_TASKS.md Phase 1). It defines the shared
 * page scaffolding — the ``.container`` wrapper, base type scale, links,
 * headings — that every page and both reading UIs build on. MUST load after
 * ``tokens.css`` (it reads the color/spacing tokens) and before the
 * page/reading files that override these primitives at equal specificity.
 */

/* ---------------------------------------------------------------------
 * Layout
 * ------------------------------------------------------------------ */

/* The ``.container`` class wraps the main content. ``max-width`` keeps
 * line lengths comfortable on large screens; ``margin: 0 auto`` centers
 * it; the ``padding`` floor keeps text off the screen edge on narrow
 * viewports without requiring a media query. */
.container {
    max-width: 42rem;
    margin: 0 auto;
    padding: 1rem;
}

/* Narrow phones: the two reading surfaces run edge-to-edge horizontally — drop
 * the 1rem side gutter so their cards and bars span the full width (vertical
 * padding stays). This is opt-IN: every other page (forms, prose, settings)
 * keeps the .container gutter, because a form or paragraph flush against the
 * screen edge reads as broken. Only the home feed, the @username profile feed,
 * and the post reading view carry these classes, and they genuinely want the
 * full bleed. Scoped by #main-content id so it beats the .container padding
 * regardless of source order. */
@media (max-width: 559px) {
    #main-content.container--home,
    #main-content.container--profile,
    #main-content.container--post-detail {
        padding-left: 0;
        padding-right: 0;
    }
}

/* The account-settings surface defaults to the sans-serif reading face
 * (Open Sans) rather than the body serif; set as a container default so
 * everything inside inherits it, with room to opt specific elements back out. */
.container--settings {
    font-family: var(--font-sans);
}

/* The site nav is a full-bleed band (background + bottom rule run edge to
 * edge), and so is its content: ``.site-nav-inner`` spans the whole bar. We
 * tried capping + centring it to the page width so the links would align with
 * the homepage hero/cards, but the content column width varies page to page,
 * so the alignment never held — the nav now just hugs the viewport edges (left
 * cluster left, account cluster right). The whole bar is JetBrains Mono,
 * lowercase — the redesign's "label" voice. */
.site-nav {
    /* Sticky at the top of the viewport across every breakpoint — it matters
     * most on mobile, where you'd otherwise have to scroll back up to reach the
     * nav. The opaque --surface background hides content scrolling beneath it.
     * z-index 100 sits above ordinary page content and the reading-view card
     * rails (5/50) but below modals/toasts (980+), so overlays still cover it. */
    position: sticky;
    top: 0;
    z-index: 100;
    border-bottom: 2px solid var(--border-nav);
    /* Full-bleed band on the same background as the page body (--surface), so
     * the bar isn't a slightly different shade — the bottom rule is the only
     * thing setting it apart. No horizontal padding here: .site-nav-inner
     * carries the 1rem so the leftmost/rightmost nav text clears the viewport
     * edge by the same gutter as the page content. */
    background: var(--surface);
}

.site-nav-inner {
    /* Full-width (no max-width cap): the left cluster sits at the far left and
     * the account cluster (settings + logout, pushed by .nav-settings's
     * margin-left:auto on desktop) at the far right. The 1rem padding is the
     * only gutter from the viewport edges. */
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding: 0.7rem 1rem;
    font-family: var(--font-mono);
    font-size: 0.85rem;
    letter-spacing: 0.02em;
}

/* Header nav links read as a plain cluster, not underlined hyperlinks. */
.site-nav nav a {
    text-decoration: none;
    color: inherit;
}

/* Nav links flare to the cool link/title accent on hover, matching links
 * elsewhere. (Log out is the exception — see .logout-form button:hover, which
 * keeps the warm --brand-red.) */
.site-nav nav a:hover {
    color: var(--brand-cool);
}

/* Rolling word-count goal readout. Hidden by default; only wide screens
 * (>=1200px) have room for a centered third element in the bar. It inherits
 * the bar's font/size/colour/letter-spacing from .site-nav-inner, so it reads
 * identically to the nav links. Absolutely centered (rather than a third flex
 * item) so it's pinned to the middle of the viewport regardless of how wide
 * the left/right clusters are, and so it leaves the existing flex layout of
 * <nav> untouched. */
.nav-wordcount {
    display: none;
}
@media (min-width: 1200px) {
    .site-nav-inner {
        position: relative;
    }
    .nav-wordcount {
        display: block;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        white-space: nowrap;
        /* Purely informational — never intercept clicks meant for the bar. */
        pointer-events: none;
    }
    /* Goal met: emphasise just the running total. */
    .nav-wordcount-count {
        font-weight: 700;
        color: var(--brand-cool);
    }
}

/* The unread "status dot" to the upper-right of "inbox". Hidden by default;
   .is-on shows a small dot in the current link colour (so it tracks the link's
   hover state too); .is-super enlarges it and pins it to brand-red. The dot is
   nudged up and right of the word to read as a superscript marker. */
.nav-dot {
    display: none;
}

.nav-dot.is-on {
    display: inline-block;
    width: 0.4em;
    height: 0.4em;
    margin-left: 0.15em;
    border-radius: 50%;
    background: currentColor;
    position: relative;
    top: -0.4em;
}

.nav-dot.is-super {
    width: 0.6em;
    height: 0.6em;
    background: var(--brand-red);
}

.site-nav nav {
    display: flex;
    gap: 0.85rem;
    align-items: baseline;
}

/* ---------------------------------------------------------------------
 * Typography
 * ------------------------------------------------------------------ */

h1, h2, h3, h4, h5, h6 {
    line-height: 1.2;
    margin: 0.7em 0 0.5em;
}

/* The story-tree title (the root post's <h1>) overrides the global heading
 * margin: flush at the top, with a wider gap below before the post body.
 * Scoped to .post-header so markdown headings inside post/riff bodies keep
 * the global rhythm. */
.post-header h1 {
    margin: 0 0 1.5rem;
}

p, ul, ol, blockquote, pre {
    margin: 0 0 1em;
}

/* Rendered-content lists in a card body (the root post's ``.post-body`` and a
 * riff's ``.contribution-content``): the browser default padding-inline-start
 * (~40px) over-indents bullets and numbers. Pull them in to a gentle indent.
 * Scoped to the prose wrappers so the structural ARIA-tree / nav / rail lists
 * (which zero their own padding) are untouched. */
.post-body ul,
.post-body ol,
.contribution-content ul,
.contribution-content ol {
    padding-inline-start: 15px;
}

blockquote {
    border-left: 3px solid var(--border-subtle);
    margin-left: 0;
    padding-left: 1em;
    color: var(--text-muted);
}

/* Code-block sizing: keep ``<pre>`` from blowing past the container on
 * narrow viewports. ``overflow-x: auto`` is the right escape hatch:
 * long lines scroll inside the block instead of stretching the page. */
pre {
    overflow-x: auto;
    background: var(--surface-code);
    padding: 0.75em;
    border-radius: 4px;
}

code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.95em;
}

/* Rendered-markdown tables (the ``tables`` extension — M.5). Global element
 * selectors like the rest of the prose rules. ``display: block; overflow-x:
 * auto`` is the CSS-only responsive-table pattern: it keeps the cells laying
 * out as a table (the browser wraps the rows in an anonymous table box) while
 * letting a wide table scroll inside its own box rather than pushing the page
 * body into a horizontal scroll on mobile. Borders + the subtly raised header
 * use theme tokens, so light and dark are handled automatically. Column
 * alignment isn't rendered — the extension's per-cell text-align ``style`` is
 * stripped at sanitize time (see render.py), a deliberate trade to avoid a CSS
 * sanitizer on the XSS-sensitive render surface. */
table {
    display: block;
    overflow-x: auto;
    max-width: 100%;
    border-collapse: collapse;
    margin: 0 0 1em;
}

th, td {
    border: 1px solid var(--border-subtle);
    padding: 0.4em 0.7em;
    text-align: left;
    vertical-align: top;
}

thead th {
    background: var(--surface-raised);
    font-weight: 600;
}

a {
    color: var(--link);
}

/* Links light up to the title accent (--brand-cool) on hover, not their resting
 * --link colour — theme-aware: the title's periwinkle in light, its coral in
 * dark. Components with their own :hover (nav, .btn, the reading rail) keep
 * theirs via specificity. */
a:hover {
    color: var(--brand-cool);
}

a:focus-visible {
    /* Phase 5 will use the focus ring heavily for the keyboard-nav
     * tree (Task 5.4). Defining it here means the same indicator
     * applies everywhere by default. */
    outline: 2px solid var(--link);
    outline-offset: 2px;
}

