/* Shared page chrome — pairs with tokens.css (S040). Component-level styling for individual
 * pages (dashboard, article, etc.) belongs to the steps that add those templates; this file
 * only carries the base layout, interaction states and skip-link every page inherits from
 * templates/base.html. */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: var(--size-ui);
  -webkit-font-smoothing: antialiased;
  transition: background-color var(--motion), color var(--motion);
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

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

a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Visible focus ring everywhere — never `outline: none` (WCAG AA; design brief). */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}

/* Off-screen until focused, then pinned top-left — the first focusable element on every
 * page (design/design_handoff_agentblog/README.md, skip-link requirement). */
.skip-link {
  position: absolute;
  top: var(--space-2);
  left: -9999px;
  z-index: 50;
  padding: var(--space-2) var(--space-3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  font-family: var(--mono);
  font-size: var(--size-mono);
}

.skip-link:focus {
  left: var(--space-2);
}

.site-header {
  border-bottom: 1px solid var(--line);
}

.site-footer {
  border-top: 1px solid var(--line);
  margin-top: auto;
}

/* `Agentblog.dc.html:41,129` draws the platform wordmark at two distinct sizes — 22px with
 * `-0.01em` tracking in the header (above 480px; the S277 block below sets 20px at ≤480px,
 * D-226), 16px with none in the footer — not one shared 20px.
 * Now that S077e suppresses this wordmark on every owner-known per-blog surface
 * (`base.html`'s `{% if not site_nav or not site_nav.owner %}` guard), the only pages
 * these two rules still style are the marketing home and the system/auth pages, so
 * nothing depends on the old shared value (S077e review round 1, minor). */
.site-header .wordmark {
  font-family: var(--display);
  font-size: 22px;
  letter-spacing: -0.01em;
  color: var(--text);
}

.site-footer .wordmark {
  font-family: var(--display);
  font-size: 16px;
  color: var(--text);
}

/* Every ownerless footer bar wraps, as `Agentblog.dc.html:128`'s own footer row does
 * (`flex-wrap:wrap`): S112's `Terms`/`Abuse`/`DMCA` links (D-168) widened
 * `partials/marketing_footer.html` to six links plus the wordmark and copyright, and
 * `.wrap-bar`'s unwrapped row cannot shrink inline text below its content width — at a
 * 360px viewport the document scrolled sideways to 508px (S112 review round 2, major).
 * `.wrap-bar.blog-footer` already wraps; this only adds the same to the marketing,
 * system and auth footers, and leaves the header's `.wrap-bar` untouched. */
.site-footer .wrap-bar {
  flex-wrap: wrap;
}

.wordmark-dot {
  color: var(--accent);
}

/* Shared per-blog header nav (S072, D-83): `partials/blog_nav.html`'s `<nav
 * class="blog-nav">`, included by every page through `base.html`'s own `{% block nav
 * %}` default — chrome, so it lives here rather than a page-specific stylesheet, matching
 * this file's own module doc. The active section's link (`aria-current="page"`) gets the
 * mockup's accent underline (`Blog.dc.html:49`); every other link stays muted. */
.blog-nav {
  display: flex;
  align-items: center;
  /* The mockup's header is one flex row whose `<span style="flex:1">` pushes the section
   * links onto the right gutter (`Article.dc.html:46-53`, `Blog.dc.html:45-53`). Here the
   * row is `base.html`'s `.wrap-bar` and this nav is one of its items, so the spacer below
   * only has free space to distribute once the nav itself grows into the bar — without
   * `flex: 1` the links pack left against the owner wordmark (S077a review, major).
   * `min-width: 0` lets it shrink past its content on a narrow viewport, and `flex-wrap`
   * reflows the items instead of overflowing the viewport (handoff README, "Responsive":
   * no fixed pixel widths on text-bearing containers, test 360-1440px). Above 480px; the
   * S277 block below sets `nowrap` and a smaller gap at ≤480px (D-226). */
  flex: 1;
  min-width: 0;
  flex-wrap: wrap;
  gap: var(--space-5);
  font-size: var(--size-ui-dense);
}

.blog-nav-spacer {
  flex: 1;
}

.blog-nav .blog-nav-owner {
  font-family: var(--display);
  /* 20px, not `--size-h2` (22px) — matches `Article.dc.html`'s header `<a>`
   * (`font-size:20px`) verbatim; independent of the platform wordmark's own 22px/16px
   * split above (`.site-header .wordmark`/`.site-footer .wordmark`) — this owner mark
   * never appears beside that one, since S077e suppresses the platform wordmark on every
   * surface this class renders on (S077e review round 1, minor: the old comment cited a
   * shared literal that no longer exists). */
  font-size: 20px;
  color: var(--text);
}

/* Host-qualified domain line beside the owner wordmark (S077a, D-90:
 * `Article.dc.html`'s header `<span>`, mono 12px `--text-2`, e.g. "agentblog.net/alice"). */
.blog-nav-domain {
  font-family: var(--mono);
  font-size: var(--size-mono);
  color: var(--text-2);
}

.blog-nav a:not(.blog-nav-owner) {
  color: var(--text-2);
}

/* The signed-in reader's way back (D-212; `Blog.dc.html:51`, `Article.dc.html:53`): a
 * muted link after Search, its color from the rule above, set apart by a 1px `--line`
 * rule on its left with 20px of padding (above 480px; the S277 block below drops it to 12px,
 * D-226). When `.blog-nav` wraps and this link starts a new row, the rule stays (D-212,
 * operator's choice). */
.blog-nav-dashboard {
  border-left: 1px solid var(--line);
  padding-left: var(--space-5);
}

/* The current tab's underline must not lift its text (D-212): top padding equals the
 * bottom padding plus the border width, 3px = 2px + 1px (`Blog.dc.html:49`), so its text
 * shares its row's vertical center with the unpadded links beside it. A rule that changes
 * either width restates the top padding too (`public-feed.css`). */
.blog-nav a[aria-current="page"] {
  color: var(--text);
  border-bottom: 1px solid var(--accent);
  padding-top: 3px;
  padding-bottom: 2px;
}

/* The marketing chrome's call-to-action button (`partials/marketing_nav.html`'s
 * `Register`/`Log in`, `home.html`'s hero pair) — shared by `/`, `/docs`, `/status`,
 * `/privacy` and `/docs/verdicts`, so it lives here beside `.blog-nav` rather than in
 * `home.css`, which only `/` loads: every other marketing surface used to fall through to
 * `.blog-nav a:not(.blog-nav-owner)` and render the CTA as plain grey 14px text with no
 * accent fill, padding or radius (S077h review round 2, minor — `marketing_nav.html`'s own
 * comment already claimed these rules were here). `.home-cta-secondary` (hero-only) moves
 * with it: the two share the sizing and `:hover` rules below, and splitting the selector
 * lists across two files would duplicate their declarations. */
.home-cta,
.home-cta-secondary {
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-s);
  font-size: var(--size-ui);
}

.home-cta {
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 500;
}

/* The header CTA is the same button inside `partials`-shaped chrome: `base.html`'s `{%
 * block nav %}` puts it in `<nav class="blog-nav">`, where
 * `.blog-nav a:not(.blog-nav-owner) { color: var(--text-2) }` (0,2,1) outranks the shared
 * `.home-cta` (0,1,0) and leaves muted grey text on the accent fill — 1.03:1, far under
 * the brief's 4.5:1 "including on the accent". Restated at (0,2,2) so it wins on
 * specificity rather than on stylesheet order, the same fix `post.css`'s
 * `.article-header .eyebrow` already applies to `.wrap-main p`.
 *
 * `Agentblog.dc.html:45` also draws the header Register button smaller than the hero's
 * "Create a blog" (`:56`) — `8px 14px`/14px against the shared rule's `12px 20px`/15px —
 * one component drawn at two sizes on the marketing home (S077e review round 1, minor). */
nav.blog-nav a.home-cta {
  color: var(--on-accent);
  padding: 8px 14px;
  font-size: var(--size-ui-dense);
}

.home-cta-secondary {
  border: 1px solid var(--line);
  color: var(--text);
}

/* The handoff pins no underline on hover for either CTA
 * (`Agentblog.dc.html:40,56`'s `style-hover="text-decoration:none;opacity:.92"`), so this
 * overrides this file's own global `a:hover` (S074 review, minor) — (0,2,0) beats (0,1,1)
 * regardless of source order, so one rule covers both the hero and `nav.blog-nav` CTAs. */
.home-cta:hover,
.home-cta-secondary:hover {
  text-decoration: none;
  opacity: 0.92;
}

/* Shared per-blog footer (S077a, D-90): `partials/blog_footer.html`'s tagline + feed
 * links + right-aligned "hosted on agentblog" mono line, replacing `.site-footer`'s bare
 * wordmark on the article and every blog-landing surface (`Article.dc.html`'s footer div:
 * `display:flex;gap:20px;flex-wrap:wrap;align-items:center;font-size:13px`). Scoped to
 * `.blog-footer` — a class `base.html`'s `{% block footer %}` wrapper only carries when
 * `site_nav.owner` is present — rather than `.site-footer .wrap-bar`, which used to select
 * every page's footer bar including the marketing home's (S077a review round 3, minor:
 * that rule silently restyled `Agentblog.dc.html`'s own 32px/24px footer to 24px/20px, a
 * surface this card does not build). The marketing home's footer keeps `.wrap-bar`'s own
 * pre-existing padding until a later step sets its own. */
/* Compound `.wrap-bar.blog-footer`, not bare `.blog-footer`: the element carries both
 * classes, `.wrap-bar` is declared 48 lines below this rule, and at equal specificity the
 * later rule wins — so the padding and font-size below were dead, and the browser-verified
 * round-1 values silently reverted to the header bar's (S077a review round 4, minor). */
.wrap-bar.blog-footer {
  flex-wrap: wrap;
  /* 24px on every side, the mockup's own footer padding (`Article.dc.html`'s footer div:
   * `padding:24px`), not the header bar's asymmetric `--space-3`/`--space-4` block padding
   * this rule inherits from `.wrap-bar` (S077a review, minor). */
  padding-block: var(--space-6);
  font-size: var(--size-helper);
  color: var(--text-2);
}

/* Narrow-viewport header compaction (S277, D-226; `docs/design-brief.md:36`: fully
 * responsive from 360px). The mockups draw the same flex-wrap header (`Agentblog.dc.html:45`,
 * `Article.dc.html:47`) and pin nothing below 480px, so this block adds what they leave
 * open: at 390px the marketing header put `Posts Docs Log in` above the wordmark row with
 * `Register` pushed below it, and the per-blog header wrapped `Tags Search` onto a second
 * row, because `.blog-nav`'s `flex-wrap: wrap` reflows *inside* the nav once wordmark +
 * domain line + links exceed the ~342px content width. Scoped to `.site-header`, which
 * every page's header carries (`base.html`), so the dashboard, auth and system headers get
 * the same `.wrap-bar` padding/gap and `.wordmark` size while footers stay untouched;
 * nothing here applies above 480px. Every spacing, type and visibility difference from the
 * mockup headers below is recorded in D-226 (D-90 exception register). Each
 * `.site-header …` selector outranks the base rule it overrides on specificity;
 * `nav.blog-nav a.home-cta` and `.site-header .wordmark` tie theirs and win on source
 * order, so this block must stay below both. */
@media (max-width: 480px) {
  /* `--space-2`, not `--space-3`: with `--space-3` the signed-out marketing nav overflowed
   * its box by 2px at 360px (`Register` 2px into the right gutter), the case the S277 card's
   * item 3 fallback names (S277 review round 1, minor). */
  .site-header .wrap-bar {
    padding-inline: var(--space-4);
    gap: var(--space-2);
  }

  .site-header .blog-nav {
    flex-wrap: nowrap;
    gap: var(--space-2);
  }

  .site-header .blog-nav a {
    white-space: nowrap;
  }

  .site-header .wordmark {
    flex-shrink: 0;
    font-size: 20px;
  }

  /* `aria-hidden` decoration repeating the address bar (`blog_nav.html`); hiding it frees
   * the ~140px the Tags/Search links need (D-226). */
  .site-header .blog-nav-domain {
    display: none;
  }

  /* The owner wordmark is the one item allowed to shrink: a long username truncates with
   * an ellipsis instead of wrapping or pushing the section links off the row. */
  .site-header .blog-nav .blog-nav-owner {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .site-header .blog-nav-dashboard {
    padding-left: var(--space-3);
  }

  nav.blog-nav a.home-cta {
    padding: 8px 12px;
  }

  /* The dashboard header (`dash/base.html`): `View blog ↗` stays one line, and the username
   * chip, a flex item of `.wrap-bar`, is the item that shrinks, with an ellipsis. Without
   * these an 8-character username wrapped `View blog ↗` to two lines at 360px and a
   * 16-character one scrolled the document sideways (S277 review round 1, minor). (0,2,0)
   * outranks `dash.css`'s (0,1,0) rules whatever the stylesheet order. */
  .site-header .dash-view-blog {
    white-space: nowrap;
  }

  .site-header .dash-user-chip {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

.blog-footer-link {
  color: var(--text-2);
}

/* `Agentblog.dc.html:134`: the marketing footer's copyright row is right-aligned mono
 * 12px. Shared by `/`, `/docs`, `/status`, `/privacy` and `/docs/verdicts` through
 * `partials/marketing_footer.html`, so it belongs here rather than in `home.css` — on the
 * four pages that load no `home.css` the year used to render left-packed in the body face
 * (S077h review round 2, minor). */
.home-footer-copyright {
  margin-left: auto;
  font-family: var(--mono);
  font-size: var(--size-mono);
  color: var(--text-2);
}

.blog-footer-host {
  margin-left: auto;
  font-family: var(--mono);
  font-size: var(--size-mono);
}

/* Shared "Older"/"Newer" pagination nav (`blog/list.html`, `tag.html`, `search.html`):
 * base layout only — `justify-content` and any `.pagination-next` push-right trick a page
 * needs beyond this base stay in that page's own stylesheet, since they depend on whether
 * the page ever renders more than one link (S073 review, nit: this rule was copied
 * byte-for-byte into three page stylesheets before this extraction). */
.pagination {
  display: flex;
  padding-top: var(--space-5);
  font-family: var(--mono);
  font-size: var(--size-helper);
}

main {
  flex: 1;
}

/* The centred column every page shares: `--content-width` wide, with the handoff's 24px
 * gutter so text never touches the viewport edge on a narrow screen (mockups put
 * `max-width:1080px;margin:0 auto;padding:…24px` on the header bar, main and the footer of
 * every page). The rule lives here rather than in each page template so a later template
 * cannot forget it. */
.wrap {
  width: 100%;
  max-width: var(--content-width);
  margin-inline: auto;
  padding-inline: var(--space-6);
}

.wrap-bar {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding-block: var(--space-3) var(--space-4);
  font-size: var(--size-ui-dense);
}

.wrap-main {
  padding-block: var(--space-10) var(--space-20);
}

/* Headings are the display face at regular weight — never the browser's bold sans default
 * (design handoff "Type": Newsreader 400 for headings, Instrument Sans for UI). */
h1,
h2,
h3 {
  margin: 0 0 var(--space-3);
  font-family: var(--display);
  font-weight: 400;
  line-height: 1.2;
}

h1 {
  font-size: var(--size-h1);
}

h2 {
  font-size: var(--size-h2);
}

/* Body copy on a system/landing page: readable measure, muted secondary tone. */
.wrap-main p {
  margin: 0 0 var(--space-5);
  max-width: var(--measure-reading);
  color: var(--text-2);
  line-height: 1.55;
}

.wrap-main p:last-child {
  margin-bottom: 0;
}

/* The small mono eyebrow above a system-page heading (`<code>404</code>`). */
code {
  font-family: var(--mono);
  font-size: var(--size-mono);
  color: var(--text-2);
}
