/*
Theme Name: Goldypaper
Theme URI: https://www.goldypaper.com
Author: Goldypaper
Author URI: https://www.goldypaper.com
Description: Marketing blog theme for goldypaper.com/blog. Continues the home
  page's gold-anchored design system: same wordmark, same paper background,
  same golden-ratio type scale, same 72rem canvas.
Version: 1.7.1
Requires PHP: 7.4
Text Domain: goldypaper
*/

/* ==========================================================================
   Design tokens — colour, radius, type scale, spacing.
   Declared once here; every template references these custom properties and
   nothing else. Values copied verbatim from brand-brief.md.
   ========================================================================== */

:root {
  color-scheme: light;
  --background:          oklch(0.98 0.008 85);   /* warm paper */
  --foreground:          oklch(0.24 0.012 75);   /* near-black ink */
  --card:                oklch(0.98 0.008 85);
  --primary:             oklch(0.54 0.11 80);    /* gold */
  --primary-foreground:  oklch(0.98 0.008 85);
  --secondary:           oklch(0.93 0.02 85);
  --muted:               oklch(0.93 0.02 85);
  --muted-foreground:    oklch(0.48 0.02 75);
  --accent:              oklch(0.92 0.025 82);
  --border:              oklch(0.88 0.02 85);
  --ring:                oklch(0.54 0.11 80);    /* focus ring = primary */
  --radius:              0.625rem;

  /* Gold tuned for the hero's inverted slab (background: var(--foreground)),
     not the page background --primary is tuned against. The slab flips
     between modes — dark in light mode, light in dark mode — so --primary
     itself fails 4.5:1 on it in both directions; this is a deliberately
     separate, per-scheme value. */
  --hero-eyebrow:        oklch(0.68 0.11 80);

  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);

  --font-serif: "Iowan Old Style", "Palatino Linotype", Georgia, "Times New Roman", serif;
  --font-sans:  ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
                "Helvetica Neue", Arial, sans-serif;
  --font-mono:  ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  /* Golden-ratio type scale — climbs in sqrt(phi) and lands on exact phi
     multiples at the display end. Use only these steps, nothing else. */
  --phi: 1.618;
  --ratio: 1.272;                        /* sqrt(phi) */

  --step--2: 0.618rem;                   /* 1/phi    — captions, fine print */
  --step--1: 0.786rem;                   /* 1/sqrt(phi) — meta, eyebrow labels */
  --step-0:  1rem;                       /* base, h4 */
  --step-1:  1.272rem;                   /* sqrt(phi)   — lead paragraph, h3 */
  --step-2:  1.618rem;                   /* phi         — h2 */
  --step-3:  2.058rem;                   /* sqrt(phi)^3 — display step */
  --step-4:  2.618rem;                   /* phi^2       — h1 */
  --step-5:  4.236rem;                   /* phi^3       — index hero title only */

  /* Spacing scale — every margin/padding/gap in this theme is one of these
     seven values, derived from phi. */
  --space-2xs: 0.382rem;                 /* phi^-2 */
  --space-xs:  0.618rem;                 /* phi^-1 */
  --space-sm:  1rem;                     /* phi^0 */
  --space-md:  1.618rem;                 /* phi^1 */
  --space-lg:  2.618rem;                 /* phi^2 */
  --space-xl:  4.236rem;                 /* phi^3 */
  --space-2xl: 6.854rem;                 /* phi^4 */
}

/* The dark class is set by the head bootstrap in header.php from the same
   weddang-host-theme flag the Rails host uses, OS preference as fallback —
   so both sites always wear the same scheme. */
.dark {
  color-scheme: dark;
  --background:          oklch(0.17 0.012 80);
  --foreground:          oklch(0.94 0.01 85);
  --card:                oklch(0.21 0.014 80);
  --primary:             oklch(0.68 0.11 82);
  --primary-foreground:  oklch(0.17 0.012 80);
  --secondary:           oklch(0.24 0.016 80);
  --muted:               oklch(0.24 0.016 80);
  --muted-foreground:    oklch(0.70 0.02 80);
  --accent:              oklch(0.26 0.018 80);
  --border:              oklch(0.32 0.018 80);
  --ring:                oklch(0.68 0.11 82);
  --hero-eyebrow:        oklch(0.42 0.11 82);
}

/* ==========================================================================
   Reset & base
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  /* Every --step-* is a rem, and rem resolves against the root element —
     this has to live on html, not body, or the whole phi scale is inert. */
  font-size: clamp(1.0625rem, 1rem + 0.25vw, 1.125rem);
}

body,
h1, h2, h3, h4, p, figure, blockquote, dl, dd, ol, ul {
  margin: 0;
}

ol, ul {
  padding: 0;
  list-style: none;
}

img, svg, video {
  display: block;
  max-width: 100%;
  height: auto;
}

table {
  border-collapse: collapse;
  width: 100%;
}

html,
body {
  /* The landing's header does the same on the marketing site: at 320px the
     Get started pill sits past the viewport edge, clipped instead of
     turning the page into a horizontal scroller. */
  overflow-x: clip;
}

body {
  font-family: var(--font-sans);
  /* font-size inherited from html's fluid root */
  line-height: var(--phi);
  color: var(--foreground);
  background: var(--background);
}

h1, h2, h3, h4 {
  font-family: var(--font-serif);
  font-weight: 600;
  font-style: normal;
  color: var(--foreground);
}

/* Heading levels jump a full phi at the top (h1 → h2) and sqrt(phi)
   below — consecutive sqrt(phi) steps made h1/h2/h3 read as one size. */
h1 { font-size: var(--step-4); line-height: 1.1; letter-spacing: -0.01em; }
h2 { font-size: var(--step-2); line-height: 1.272; letter-spacing: -0.01em; }
h3 { font-size: var(--step-1); line-height: 1.272; }
h4 { font-size: var(--step-0); }

a {
  color: inherit;
  text-decoration-color: var(--border);
}

a:not(.btn) {
  transition: color 200ms ease;
}

a:not(.btn):hover {
  color: var(--primary);
}

:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

::selection {
  background: var(--accent);
  color: var(--foreground);
}

/* ==========================================================================
   Utilities
   ========================================================================== */

.screen-reader-text {
  border: 0;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute !important;
  width: 1px;
  word-wrap: normal !important;
}

.skip-link {
  z-index: 100000;
}

.skip-link:focus {
  background-color: var(--background);
  color: var(--foreground);
  display: block;
  clip: auto !important;
  clip-path: none;
  height: auto;
  width: auto;
  position: fixed !important;
  top: var(--space-xs);
  left: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  text-decoration: none;
  border-radius: var(--radius-sm);
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* A short page — a 404, an empty search — should still push the footer to the
   bottom of the window rather than letting it ride up mid-screen. */
.site-main {
  min-height: 60vh;
}

.wrap {
  /* The home page's max-w-6xl is 72rem at its default 16px root = 1152px,
     and its px-4/px-6 paddings are fixed px. This theme's fluid root would
     inflate rem values on desktop, so the canvas is pinned in px to stay
     pixel-identical with the home. */
  max-width: 1152px;
  margin-inline: auto;
  padding-inline: 16px;
}

@media (min-width: 640px) {
  .wrap {
    padding-inline: 24px;
  }
}

.section {
  padding-block: var(--space-xl);
}

@media (min-width: 640px) {
  .section {
    padding-block: var(--space-2xl);
  }
}

.eyebrow {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--primary);
  margin-block-end: var(--space-xs);
}

.prose {
  max-width: 66ch;
}

.prose > * + * {
  margin-block-start: var(--space-md);
}

.prose h2 { margin-block-start: var(--space-lg); }
.prose h3 { margin-block-start: var(--space-md); }
.prose ul,
.prose ol {
  padding-inline-start: var(--space-md);
  list-style: revert;
}

.prose blockquote {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: var(--ratio);
  font-style: normal;
  color: var(--foreground);
  border-inline-start: 3px solid var(--primary);
  padding-inline-start: var(--space-md);
}

.prose code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--muted);
  border-radius: var(--radius-sm);
  padding: 0.15em 0.4em;
}

.prose pre {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  background: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md);
  overflow-x: auto;
}

.prose pre code {
  background: none;
  padding: 0;
}

.prose figcaption {
  font-size: var(--step--1);
  color: var(--muted-foreground);
  margin-block-start: var(--space-2xs);
}

/* Body links wear the gold at rest — with the inherited colour and a pale
   underline they vanished into the paragraph, and readers missed real
   links. */
.prose a {
  color: var(--primary);
  text-decoration-color: var(--primary);
  text-underline-offset: 0.2em;
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-height: 2.75rem;
  padding-inline: var(--space-md);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  transition: color 200ms ease, background-color 200ms ease, transform 200ms ease;
}

.btn-primary {
  background: var(--primary);
  color: var(--primary-foreground);
}

.btn-primary:hover {
  color: var(--primary-foreground);
  transform: translateY(-1px);
}

.btn-ghost {
  background: transparent;
  color: var(--foreground);
  border-color: transparent;
}

.btn-ghost:hover {
  color: var(--primary);
}

/* Compact button — pixel-for-pixel the Rails Button "sm" (h-8 px-3
   rounded-md text-sm font-medium), which the landing header uses. The
   primary call adds the rounded-full px-4 override Get started carries.
   Fixed px on purpose: rem would inflate 12.5% under the blog's fluid root
   font-size and drift off the marketing header. */
.btn-sm {
  min-height: 32px;
  gap: 6px;
  padding-inline: 12px;
  font-size: 14px;
  font-weight: 500;
  border-radius: 6px;
}

.btn-sm.btn-primary {
  border-radius: 999px;
  padding-inline: 16px;
}

.btn-sm.btn-primary:hover {
  transform: none;
}

@supports (color: color-mix(in oklch, red, blue)) {
  .btn-sm.btn-primary:hover {
    background: color-mix(in oklch, var(--primary) 90%, transparent);
  }
}

.btn-sm.btn-ghost:hover {
  background: var(--accent);
  color: var(--foreground);
}

/* ==========================================================================
   Site header — mirrors the marketing home's landing header (show.tsx).
   Every size is the Tailwind value in fixed px (py-2.5 = 10, text-sm =
   14/20, py-3 = 12, gap-7 = 28, text-xl = 20/28, …) so the fluid root
   font-size here cannot inflate them off the Rails header.
   ========================================================================== */

.promo-strip {
  border-bottom: 1px solid var(--border);
  background: var(--muted);
  color: var(--primary);
}

@supports (color: oklch(from red l c h)) {
  .promo-strip {
    border-bottom-color: oklch(from var(--primary) l c h / 0.25);
    background: oklch(from var(--primary) l c h / 0.1);
  }
}

.promo-strip p {
  max-width: 1152px;
  margin-inline: auto;
  padding-block: 10px;
  padding-inline: 16px;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  text-align: center;
}

@media (min-width: 640px) {
  .promo-strip p {
    padding-inline: 24px;
  }
}

.site-nav {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--background);
  border-bottom: 1px solid var(--border);
}

@supports (backdrop-filter: blur(1px)) {
  .site-nav {
    backdrop-filter: blur(12px);
  }
}

@supports (color: color-mix(in oklch, red, blue)) {
  .site-nav {
    background: color-mix(in oklch, var(--background) 90%, transparent);
  }
}

@supports (color: oklch(from red l c h)) {
  .site-nav {
    border-bottom-color: oklch(from var(--border) l c h / 0.8);
  }
}

.site-nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-block: 12px;
}

/* Inline on purpose, like the Rails anchor: the inline-flex inner span
   baseline-aligned inside the 20/28 line box is what makes the link 33px
   tall and centers the wordmark exactly as on the marketing header. */
.site-branding {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 20px;
  line-height: 28px;
  letter-spacing: -0.025em;
  color: var(--foreground);
  text-decoration: none;
  flex-shrink: 0;
}

.site-branding-inner {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.site-branding:hover {
  color: var(--foreground);
}

.brand-mark {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}

.primary-navigation {
  display: none;
}

@media (min-width: 1024px) {
  .primary-navigation {
    display: block;
  }
}

.primary-navigation ul {
  display: flex;
  align-items: center;
  gap: 28px;
}

.primary-navigation a {
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  color: var(--foreground);
  text-decoration: none;
  transition: color 150ms ease;
}

.primary-navigation a:hover {
  color: var(--primary);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

@media (min-width: 640px) {
  .header-actions {
    gap: 8px;
  }
}

/* ==========================================================================
   Blog hero — the home page's dark band echoed once, on the index header.
   The echo borrows the home hero's art direction, not its selling structure:
   a directional gold wash instead of a centred glow, and the two-ring mark
   as a pure ornament bleeding off the band.
   ========================================================================== */

.blog-hero {
  position: relative;
  overflow: hidden;
  background: var(--foreground);
  color: var(--background);
  padding-block: var(--space-lg);
}

/* The marketing hero's 118deg sweep (host_ui.css .landing-hero): gold bleeds
   in from both ends of the slab rather than glowing from dead centre — the
   centred radial is the one treatment every dark template hero shares. */
@supports (background: color-mix(in oklab, red, blue)) {
  .blog-hero {
    background-image: linear-gradient(
      118deg,
      color-mix(in oklab, var(--foreground) 94%, var(--primary)),
      var(--foreground) 56%,
      color-mix(in oklab, var(--foreground) 84%, var(--primary))
    );
  }
}

@media (min-width: 640px) {
  .blog-hero {
    padding-block: var(--space-xl);
  }
}

.blog-hero h1 {
  color: var(--background);
  max-width: 20ch;
}

/* --primary itself fails 4.5:1 against this inverted slab in both colour
   schemes (see --hero-eyebrow above) — the base .eyebrow rule doesn't apply
   here. */
.blog-hero .eyebrow {
  color: var(--hero-eyebrow);
}

@media (min-width: 640px) {
  .blog-hero h1 {
    font-size: var(--step-5);
  }
}

.blog-hero p {
  font-size: var(--step-1);
  color: var(--background);
  opacity: 0.85;
  max-width: 55ch;
  margin-block-start: var(--space-sm);
}

/* The two-ring mark as ornament, anchored to the content column's right edge
   (not the viewport's) so it keeps its relationship to the copy on wide
   screens. It sits behind the copy: .wrap is positioned above it. */
.blog-hero-mark {
  position: absolute;
  right: -5rem;
  bottom: -7rem;
  width: 17rem;
  height: auto;
  opacity: 0.14;
  pointer-events: none;
}

@media (min-width: 1152px) {
  .blog-hero-mark {
    width: 26rem;
    right: calc((100% - 1152px) / 2 - 5rem);
    bottom: -9rem;
  }
}

/* In dark mode the slab flips to near-white, so the mark needs a touch more
   presence to read as gold rather than vanish into the paper. */
.dark .blog-hero-mark {
  opacity: 0.2;
}

.blog-hero .wrap {
  position: relative;
}

.archive-hero {
  padding-block: var(--space-lg) var(--space-md);
  border-bottom: 1px solid var(--border);
}

.archive-hero p {
  color: var(--muted-foreground);
  max-width: 55ch;
  margin-block-start: var(--space-2xs);
}

/* ==========================================================================
   Breadcrumbs
   ========================================================================== */

.breadcrumbs {
  font-size: var(--step--1);
  color: var(--muted-foreground);
  margin-block-end: var(--space-sm);
}

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}

.breadcrumbs li:not(:last-child)::after {
  content: "/";
  margin-inline-start: var(--space-2xs);
  color: var(--border);
}

.breadcrumbs a {
  color: var(--muted-foreground);
  text-decoration: underline;
  text-decoration-color: var(--border);
}

.breadcrumbs a:hover {
  color: var(--primary);
}

/* ==========================================================================
   Post grid & card — the archive/index listing.
   Hallmark · component: post-grid + post-card · genre: editorial ·
   system: brand-brief.md (locked) ·
   states: rest · hover · focus-within (links use the global :focus-visible) ·
   pre-emit critique: P5 H5 E4 S4 R5 V4
   ========================================================================== */

/* The listing section sits tighter than a marketing section — the hero
   above already spent the generous padding budget. */
.section--listing {
  padding-block: var(--space-md) var(--space-lg);
}

@media (min-width: 640px) {
  .section--listing {
    padding-block: var(--space-lg) var(--space-xl);
  }
}

.post-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-md);
}

@media (min-width: 640px) {
  .post-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .post-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.post-card {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color 200ms ease;
}

/* The hover is editorial, not SaaS: no lift, no drop shadow — the hairline
   frame simply warms to gold. focus-within mirrors it for the keyboard. */
.post-card:hover,
.post-card:focus-within {
  border-color: var(--primary);
}

.post-card-media {
  display: block;
  aspect-ratio: 1.618 / 1;
  background: var(--muted);
}

.post-card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The no-thumbnail fallback: the same flat --muted field .post-card-media
   already carries (the img simply covers it when one exists), with the
   header's brand mark reused as a low-opacity decorative motif, not a logo. */
.post-card-media-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

.post-card-media-mark {
  width: 35%;
  height: auto;
  opacity: 0.3;
}

.post-card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: var(--space-md);
  gap: var(--space-2xs);
}

/* Read order is category eyebrow, then title, then date — the same order
   the single post's entry header uses, so a card reads as a miniature of
   the page it opens. The date is bottom-anchored instead: grid rows
   stretch cards to equal height, so dates line up across a row even when
   titles clamp to different line counts. */
.post-card-date {
  margin-block-start: auto;
  padding-block-start: var(--space-xs);
  font-size: var(--step--1);
  color: var(--muted-foreground);
}

.post-card-title {
  font-size: var(--step-1);
  line-height: var(--ratio);
  overflow-wrap: break-word;
  /* Clamp to 3 lines — one long headline should not stretch a card taller
     than its row-mates and break the grid's proportions. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

.post-card-title a {
  text-decoration: none;
}

.post-card-title a:hover {
  color: var(--primary);
}

.post-card-category {
  font-size: var(--step--1);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--primary);
  text-decoration: none;
}

/* Inside the card only, the category eyebrow stays subordinate — muted at
   rest, gold on hover, so it doesn't compete with the title as the card's
   focal point. single.php's entry-header eyebrow uses the same class above
   a much larger h1, where that competition doesn't exist, so it keeps the
   base (always-gold) styling. */
.post-card .post-card-category {
  color: var(--muted-foreground);
}

.post-card .post-card-category:hover {
  color: var(--primary);
}

/* ==========================================================================
   Single post — golden split layout.
   ========================================================================== */

.single-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-xl);
  align-items: start;
}

@media (min-width: 1024px) {
  .single-layout {
    grid-template-columns: minmax(0, 1.618fr) minmax(0, 1fr);
  }

  .single-aside {
    position: sticky;
    top: calc(4.236rem + var(--space-md));
  }
}

.entry-header {
  margin-block-end: var(--space-md);
}

.entry-header .post-card-category {
  display: inline-block;
  margin-block-end: var(--space-2xs);
}

.entry-title {
  overflow-wrap: break-word;
}

.entry-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  font-size: var(--step--1);
  color: var(--muted-foreground);
  margin-block-start: var(--space-xs);
}

.entry-thumbnail {
  margin-block-end: var(--space-md);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.entry-thumbnail img {
  width: 100%;
  height: auto;
}

.entry-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin-block-start: var(--space-lg);
}

.entry-tags a {
  font-size: var(--step--1);
  color: var(--muted-foreground);
  background: var(--muted);
  border-radius: var(--radius-sm);
  padding: var(--space-2xs) var(--space-xs);
  text-decoration: none;
}

.entry-tags a:hover {
  color: var(--primary);
}

.aside-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-md);
}

.aside-card + .aside-card {
  margin-block-start: var(--space-md);
}

.aside-card h2 {
  font-size: var(--step-1);
  margin-block-end: var(--space-sm);
}

/* One component, two callers: the single-post aside and the 404. Both are the
   same thing — a bare list of post links — so they share the treatment rather
   than each inventing one. */
.aside-related-list li + li,
.not-found-links li + li {
  margin-block-start: var(--space-sm);
  padding-block-start: var(--space-sm);
  border-block-start: 1px solid var(--border);
}

.aside-related-list a,
.not-found-links a {
  font-family: var(--font-serif);
  font-weight: 600;
  text-decoration: none;
}

.aside-related-list a:hover,
.not-found-links a:hover {
  color: var(--primary);
}

.aside-related-list time,
.not-found-links time {
  display: block;
  font-size: var(--step--1);
  color: var(--muted-foreground);
  margin-block-start: var(--space-2xs);
}

.aside-cta {
  background: var(--foreground);
  color: var(--background);
  border-color: transparent;
}

.aside-cta h2 {
  color: var(--background);
}

.aside-cta p {
  font-size: var(--step--1);
  opacity: 0.85;
  margin-block-end: var(--space-md);
}

/* ==========================================================================
   Post navigation
   ========================================================================== */

.post-navigation {
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-md);
  border-block-start: 1px solid var(--border);
}

/* the_post_navigation() wraps prev/next in .nav-links; its own <h2> is a
   screen-reader-text (position: absolute), so it never becomes a grid item —
   the grid has to target .nav-links directly, not .post-navigation itself. */
.post-navigation .nav-links {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
}

.post-navigation .nav-next {
  text-align: end;
}

.post-navigation a {
  display: block;
  text-decoration: none;
  min-height: 2.75rem;
}

.post-navigation .nav-subtitle {
  display: block;
  font-size: var(--step--1);
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.post-navigation .nav-title {
  font-family: var(--font-serif);
  font-weight: 600;
}

.post-navigation a:hover .nav-title {
  color: var(--primary);
}

/* ==========================================================================
   Pagination
   ========================================================================== */

.pagination {
  margin-block-start: var(--space-xl);
}

/* Same reason as .post-navigation .nav-links: the pagination nav's own <h2>
   is a screen-reader-text (position: absolute) and never becomes a flex
   item, so the row layout has to target .nav-links directly. */
.pagination .nav-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  justify-content: center;
}

.pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding-inline: var(--space-xs);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--foreground);
  font-size: var(--step--1);
}

.pagination .page-numbers.current {
  background: var(--primary);
  color: var(--primary-foreground);
}

.pagination a.page-numbers:hover {
  background: var(--accent);
}

/* ==========================================================================
   Comments
   ========================================================================== */

.comments-area {
  max-width: 66ch;
  margin-block-start: var(--space-xl);
}

.comments-title,
.comment-reply-title {
  font-size: var(--step-2);
}

.comment-list {
  margin-block-start: var(--space-md);
}

.comment-list .children {
  padding-inline-start: var(--space-lg);
}

.comment-body {
  padding-block: var(--space-md);
  border-block-start: 1px solid var(--border);
}

.comment-author {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.comment-author .avatar {
  border-radius: 50%;
  width: 2.75rem;
  height: 2.75rem;
}

.comment-author .fn {
  font-family: var(--font-serif);
  font-weight: 600;
  font-style: normal;
}

.comment-metadata {
  font-size: var(--step--1);
  color: var(--muted-foreground);
}

.comment-metadata a {
  text-decoration: none;
}

.comment-content {
  margin-block-start: var(--space-xs);
}

.comment-content > * + * {
  margin-block-start: var(--space-sm);
}

.reply {
  margin-block-start: var(--space-xs);
}

.comment-reply-link {
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--primary);
  text-decoration: none;
}

.comment-respond {
  margin-block-start: var(--space-lg);
}

.comment-form p {
  margin-block-start: var(--space-sm);
}

.comment-form label {
  display: block;
  font-size: var(--step--1);
  font-weight: 600;
  margin-block-end: var(--space-2xs);
}

.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
  width: 100%;
  min-height: 2.75rem;
  font: inherit;
  font-size: var(--step-0);
  color: var(--foreground);
  background: var(--background);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-xs) var(--space-sm);
}

.comment-form textarea {
  min-height: 8rem;
}

.comment-form .required {
  color: var(--primary);
}

/* ==========================================================================
   Search form
   ========================================================================== */

/* Field and button are one control, so they meet with no gap and square off
   where they touch. Left to itself the form spans the whole canvas, which is a
   search box the width of the page. */
.search-form {
  display: flex;
  gap: 0;
  max-width: 32rem;
}

.search-form label {
  flex: 1;
  min-width: 0;
}

.search-form input[type="search"] {
  width: 100%;
  min-height: 2.75rem;
  /* Anything under 16px makes iOS Safari zoom the page on focus. */
  font: inherit;
  color: var(--foreground);
  background: var(--background);
  border: 1px solid var(--border);
  border-start-start-radius: var(--radius-md);
  border-end-start-radius: var(--radius-md);
  border-start-end-radius: 0;
  border-end-end-radius: 0;
  padding-inline: var(--space-sm);
  appearance: none;
}

/* The pill shape belongs to standalone buttons; joined to a field it has to
   answer the field's corners. No border either — nowhere else does a filled
   gold button carry a contrasting rim. */
.search-form .search-submit {
  flex-shrink: 0;
  font-size: var(--step-0);
  border: 0;
  border-start-start-radius: 0;
  border-end-start-radius: 0;
  border-start-end-radius: var(--radius-md);
  border-end-end-radius: var(--radius-md);
}

/* ==========================================================================
   404 and empty states
   ========================================================================== */

/* Everything below the page-header band shares one measure, so the search box,
   the heading and the list all end on the same right edge. */
.not-found-body {
  max-width: 32rem;
}

.not-found-body > * + * {
  margin-block-start: var(--space-lg);
}

.not-found-heading {
  font-size: var(--step-1);
}

.not-found-links {
  margin-block-start: var(--space-sm);
}

.post-grid-empty {
  max-width: 32rem;
}

.post-grid-empty > * + * {
  margin-block-start: var(--space-md);
}

.post-grid-empty p {
  color: var(--muted-foreground);
}

/* ==========================================================================
   Site footer — mirrors the marketing site's footer one-to-one
   (MarketingFooter.tsx in the Rails app). The values here are the footer's
   Tailwind sizes verbatim in fixed px — not the phi scale the rest of the
   theme uses, and not rem, which this theme's fluid root would inflate —
   so both sites render the identical chrome.
   ========================================================================== */

.site-footer {
  border-block-start: 1px solid var(--border);
  background: var(--background);
}

/* Full-bleed skyline; the gradient mask fades both ends like the marketing
   site, and currentColor keeps it on the scheme's gold. */
.footer-illustration {
  color: var(--primary);
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
  mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
}

.footer-illustration svg {
  width: 100%;
}

/* Fuji's snowcap punches out to the page background inside the SVG. */
.footer-illustration .fill-background {
  fill: var(--background);
}

.footer-columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px 40px;              /* gap-y-8 gap-x-10 */
  padding-block: 40px;         /* py-10 */
}

@media (min-width: 640px) {
  .footer-columns {
    grid-template-columns: repeat(3, 1fr);   /* sm:grid-cols-3 */
  }
}

@media (min-width: 1024px) {
  .footer-columns {
    grid-template-columns: repeat(5, 1fr);   /* lg:grid-cols-5 */
  }
}

.footer-column h3 {
  font-family: var(--font-sans);
  font-size: 12px;              /* text-xs */
  line-height: 16px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;       /* tracking-wider */
  color: var(--foreground);
}

.footer-column ul {
  margin-block-start: 12px;     /* mt-3 */
  font-size: 14px;              /* text-sm */
  line-height: 20px;
}

.footer-column li + li {
  margin-block-start: 8px;      /* space-y-2 */
}

.footer-column a {
  color: var(--muted-foreground);
  text-decoration: none;
  text-underline-offset: 4px;   /* underline-offset-4 */
}

.footer-column a:hover {
  color: var(--foreground);
  text-decoration: underline;
  text-decoration-color: var(--primary);
}

@supports (color: oklch(from red l c h)) {
  .footer-column a:hover {
    text-decoration-color: oklch(from var(--primary) l c h / 0.5);  /* decoration-primary/50 */
  }
}

.footer-bottom {
  display: flex;
  flex-direction: column;
  gap: 16px;                    /* gap-4 */
  border-block-start: 1px solid var(--border);
  padding-block: 24px;          /* py-6 */
}

@media (min-width: 640px) {
  .footer-bottom {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
}

.footer-brand {
  display: flex;
  flex-direction: column;
  gap: 8px;                     /* gap-2 */
}

@media (min-width: 640px) {
  .footer-brand {
    flex-direction: row;
    align-items: center;
    gap: 16px;                  /* sm:gap-4 */
  }
}

.footer-wordmark {
  display: inline-flex;
  align-items: center;
  gap: 6px;                     /* gap-1.5 */
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 14px;              /* text-sm */
  line-height: 20px;
  color: var(--foreground);
  text-decoration: none;
}

/* Element-qualified so this tie-breaks the base a:hover rule, which would
   otherwise pull the wordmark to gold. */
a.footer-wordmark:hover {
  color: var(--foreground);
}

.footer-wordmark .brand-mark {
  width: 16px;                  /* [&_svg]:size-4 */
  height: 16px;
}

.footer-copyright {
  font-size: 12px;              /* text-xs */
  line-height: 16px;
  color: var(--muted-foreground);
}

.social-links {
  display: flex;
  align-items: center;
  gap: 4px;                     /* gap-1 */
}

.social-links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;                  /* size-11 */
  height: 44px;
  border-radius: 50%;
  color: var(--muted-foreground);
  text-decoration: none;
}

.social-links a:hover {
  color: var(--foreground);     /* hover:text-foreground */
}

.social-links svg {
  width: 20px;                  /* size-5 */
  height: 20px;
}

/* ==========================================================================
   Motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
