/* peteroram.com
   ---------------------------------------------------------------------------
   Constraints that shape everything here:

   - The CSP in public/_headers sets `style-src 'self'` with no 'unsafe-inline',
     so there are NO inline styles or <style> blocks anywhere. Everything lives
     in this file. `npm run check` fails the build if that slips.
   - `font-src 'self'` blocks external font hosts outright, so this uses system
     stacks. Serif for display (gravitas, and it echoes the HumanTerms and Cyber
     Safety Group families), system sans for everything else (clarity, and it
     reads as software rather than as a magazine).
   - No JavaScript on the site. The nav is four short links that wrap; a
     hamburger would need JS to open and is not worth the dependency.

   The layout is fluid, not a fixed reading column. An earlier version capped
   every page at a 34rem measure, which rendered as a phone-width strip of text
   on a desktop display. Prose still gets a measure (`.prose`), but the page
   itself uses the viewport it is given.
   --------------------------------------------------------------------------- */

:root {
  color-scheme: light dark;

  --bg: #fbfaf7;
  --bg-raised: #ffffff;
  --bg-sunken: #f4f1ea;
  --ink: #14151a;
  --ink-soft: #3d3f47;
  /* 5.5:1 on --bg-sunken, which is where most muted text sits (section asides,
     .note, footer headings). The previous #6b6d77 cleared AA by 0.06. */
  --ink-muted: #5f616a;
  --line: #e2ddd1;
  --line-strong: #cec8b8;
  --accent: #1d3a8a;
  --accent-ink: #ffffff;
  --accent-wash: rgba(29, 58, 138, 0.07);
  --shadow: 0 1px 2px rgba(20, 21, 26, 0.04), 0 8px 24px -12px rgba(20, 21, 26, 0.14);
  --shadow-lift: 0 2px 4px rgba(20, 21, 26, 0.05), 0 16px 40px -16px rgba(20, 21, 26, 0.22);

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Inter, Helvetica, Arial, sans-serif;

  --container: 72rem;
  --measure: 36rem;
  --radius: 12px;
  --header-h: 4rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0e0f12;
    --bg-raised: #16181d;
    --bg-sunken: #121317;
    --ink: #eceef2;
    --ink-soft: #c2c5cd;
    --ink-muted: #8b8f9a;
    --line: #24262c;
    --line-strong: #333640;
    --accent: #8fa5ff;
    --accent-ink: #0e0f12;
    --accent-wash: rgba(143, 165, 255, 0.12);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px -12px rgba(0, 0, 0, 0.6);
    --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.5), 0 16px 40px -16px rgba(0, 0, 0, 0.8);
  }
}

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

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  /* Sticky footer. 404 is short enough that the footer otherwise stopped
     mid-screen with bare background below it. */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

body > main { flex: 1 0 auto; }

@media (min-width: 60rem) { html { font-size: 17px; } }

.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 1.5rem;
}

@media (min-width: 48rem) { .wrap { padding-inline: 2.5rem; } }

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: var(--accent-ink);
  padding: 0.7rem 1.1rem;
  border-radius: 0 0 var(--radius) 0;
  z-index: 100;
}
.skip:focus { left: 0; }

/* ---------------------------------------------------------------- header */

.siteheader {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}

/* Without color-mix support, fall back to an opaque bar rather than leaving
   text unreadable over content scrolling beneath it. */
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .siteheader { background: var(--bg); }
}

.siteheader .wrap {
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  flex-wrap: wrap;
  padding-block: 0.6rem;
}

.brand {
  font-family: var(--serif);
  font-size: 1.12rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

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

.nav {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.nav a {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  padding: 0.4rem 0.7rem;
  border-radius: 7px;
  white-space: nowrap;
}

.nav a:hover { color: var(--ink); background: var(--bg-sunken); }
.nav a.current { color: var(--accent); background: var(--accent-wash); }

/* ------------------------------------------------------------------ hero */

.hero { padding-block: clamp(3.5rem, 11vw, 7.5rem) clamp(2.5rem, 6vw, 4rem); }

.eyebrow {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1.4rem;
}

.hero h1 {
  font-family: var(--serif);
  font-size: clamp(2.6rem, 7.5vw, 5rem);
  line-height: 1.02;
  letter-spacing: -0.028em;
  font-weight: 600;
  margin-bottom: 1.6rem;
}

.hero-lead {
  font-size: clamp(1.1rem, 1.9vw, 1.32rem);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 44rem;
}

.hero-lead + .hero-lead { margin-top: 1.1rem; }
.hero-lead strong { color: var(--ink); font-weight: 600; }

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.4rem;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.94rem;
  font-weight: 600;
  text-decoration: none;
  padding: 0.72rem 1.3rem;
  border-radius: 8px;
  border: 1px solid transparent;
  background: var(--accent);
  color: var(--accent-ink);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-lift); }

.btn.ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--line-strong);
}

.btn.ghost:hover { background: var(--bg-sunken); }

/* --------------------------------------------------------------- sections */

.section { padding-block: clamp(3rem, 7vw, 5rem); }
.section.sunken { background: var(--bg-sunken); border-block: 1px solid var(--line); }

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 2rem;
  flex-wrap: wrap;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: 2.5rem;
}

.section-head h2 {
  font-family: var(--serif);
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  font-weight: 600;
  letter-spacing: -0.016em;
  line-height: 1.15;
}

.section-head .aside {
  font-size: 0.92rem;
  color: var(--ink-muted);
  max-width: 26rem;
}

/* ------------------------------------------------------------------ cards */

/* `auto-fit` with a min track, so the grid reflows continuously instead of
   snapping at one hard-coded breakpoint: three-up on a wide display, two-up on
   a laptop, one-up on a phone, all from the same rule. */
.grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  align-items: stretch;
}

.card {
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.6rem 1.6rem 1.4rem;
  box-shadow: var(--shadow);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

.card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift);
  border-color: var(--line-strong);
}

.card.wide { grid-column: 1 / -1; }

.card-kind {
  display: inline-block;
  align-self: flex-start;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-wash);
  padding: 0.28rem 0.6rem;
  border-radius: 5px;
  margin-bottom: 1rem;
}

.card h3 {
  font-family: var(--serif);
  font-size: 1.4rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  line-height: 1.2;
  margin-bottom: 0.6rem;
}

.card p { color: var(--ink-soft); font-size: 0.97rem; }

.card blockquote {
  margin-top: 1rem;
  padding-left: 1rem;
  border-left: 2px solid var(--accent);
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.02rem;
  color: var(--ink-muted);
}

/* `margin-top: auto` pins the meta row to the bottom of every card regardless
   of how much copy sits above it, so the rules line up across the row. */
.card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  margin-top: auto;
  padding-top: 1.25rem;
  font-size: 0.83rem;
  color: var(--ink-muted);
}

.card-meta .sep { color: var(--line-strong); }
.card-meta a { font-weight: 600; }

/* ------------------------------------------------------------------ prose */

.prose { max-width: var(--measure); }
.prose p { color: var(--ink-soft); }
.prose p + p { margin-top: 1.05rem; }
.prose strong { color: var(--ink); font-weight: 600; }

/* Every heading on the site is serif. Without this, a subhead inside prose
   falls back to the UA's bold sans — and to zero margin, because of the
   reset — so it collides with the paragraph under it. */
.prose h3 {
  font-family: var(--serif);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  line-height: 1.25;
  margin-bottom: 0.7rem;
}

.prose h3 + p { margin-top: 0; }

.split {
  display: grid;
  gap: 2.5rem 4rem;
  grid-template-columns: 1fr;
}

@media (min-width: 56rem) {
  .split { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
}

.note {
  padding: 1.1rem 1.3rem;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-strong);
  border-radius: 0 8px 8px 0;
  font-size: 0.92rem;
  color: var(--ink-muted);
  margin-top: 1.6rem;
}

.section.sunken .note { background: var(--bg-raised); }

/* --------------------------------------------------------------- writing */

.entries { border-top: 1px solid var(--line); }

.entry {
  display: block;
  padding: 1.35rem 0.25rem;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
}

/* Hover affordance only on entries that are actually links. The writing list is
   currently <article> — styling it as clickable would promise a click that
   nothing handles. */
a.entry:hover { background: var(--bg-sunken); }

.entry h3 {
  font-family: var(--serif);
  font-size: 1.16rem;
  font-weight: 600;
  line-height: 1.25;
  margin-bottom: 0.35rem;
}

a.entry:hover h3 { color: var(--accent); }
.entry p { color: var(--ink-soft); font-size: 0.95rem; }

/* --------------------------------------------------------------- contact */

.links {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  list-style: none;
}

.link-card {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.95rem 1.1rem;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  text-decoration: none;
  color: var(--ink);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.link-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lift);
  border-color: var(--line-strong);
}

/* Inline SVG rather than <img>: no extra request, inherits currentColor so it
   works in both themes, and no dependency on an external icon host that the
   CSP would block anyway. */
.icon {
  width: 1.35rem;
  height: 1.35rem;
  flex: none;
  fill: currentColor;
  color: var(--accent);
}

.link-card .what {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.link-card .handle {
  display: block;
  font-size: 0.95rem;
  font-weight: 500;
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------- footer */

/* No margin-top. The last section already carries its own bottom padding, and a
   margin here painted a stripe of --bg between the sunken contact band and the
   sunken footer, which read as a rendering mistake rather than as breathing
   room. */
.sitefooter {
  border-top: 1px solid var(--line);
  background: var(--bg-sunken);
  padding-block: 3rem 2rem;
}

.foot-grid {
  display: grid;
  gap: 2rem 3rem;
  grid-template-columns: 1fr;
}

@media (min-width: 44rem) {
  .foot-grid { grid-template-columns: 1.5fr 1fr 1fr; }
}

.foot-name {
  font-family: var(--serif);
  font-size: 1.15rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}

.foot-tag { font-size: 0.9rem; color: var(--ink-muted); max-width: 22rem; }

.foot-h {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 0.85rem;
}

.foot-list { list-style: none; display: flex; flex-direction: column; gap: 0.5rem; }
.foot-list a { color: var(--ink-soft); text-decoration: none; font-size: 0.92rem; }
.foot-list a:hover { color: var(--accent); }

/* The legal line gets its own row below a rule. Navigation does not belong in
   it — the previous layout put the About link in the copyright row, which is
   both a wayfinding failure and the reason the page read as unfinished. */
.foot-legal {
  margin-top: 2.5rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
  font-size: 0.82rem;
  color: var(--ink-muted);
}

/* 404 has a legal-only footer with no column grid above it. Without this the
   separator rule floats under an empty band, separating nothing. */
.foot-legal:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* ------------------------------------------------------------------ misc */

a { color: var(--accent); text-underline-offset: 0.15em; }
a:hover { text-decoration: none; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

.centered { text-align: center; max-width: 34rem; margin-inline: auto; }
.centered .hero-lead { margin-inline: auto; }
.centered .actions { justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  .card:hover, .btn:hover, .link-card:hover { transform: none; }
}
