/* johnrnelson.com - the 2026-09 rebuild.

   One stylesheet for four hand-written pages and the 404. It replaces
   redesign.css, which styled the markup left over from the WordPress mirror;
   that markup is gone, so nothing here hooks onto an ast-* or wp-* class.

   John's standing rules for this site (README, "The 2026-08-28 revision"):
   blue and red, every background light, no yellow outside the duck itself,
   no dark mode, no sidebar.

   ONE DUCK PER SCREEN (John, 2026-09-18: "too many ducks on the screen. One
   at the top and the big one"). The header is his name and the links, with
   no duck in it; each page shows the duck exactly once, at every width. This
   replaces the older "duck beside his name in the header" preference - he
   chose which duck went.

   No inline styles and no JavaScript anywhere on the site, which is what lets
   the vhost send a Content-Security-Policy without 'unsafe-inline'. Keep it
   that way: a style="" attribute or a <script> would simply be blocked. */

/* ------------------------------------------------------------------ tokens */

:root {
  --ink: #16181d;          /* headings */
  --body: #39414f;         /* running text */
  --muted: #566073;        /* captions, footer text */
  --accent: #1d4ed8;       /* blue: links, the button, the rule */
  --accent-deep: #15379b;  /* hover and pressed blue */
  --accent-soft: #cfdefa;  /* chip border, the ring behind the duck */
  --accent-wash: #eef3fd;  /* chip fill */
  --accent-2: #cf2e2e;     /* red: rule tail, quote marks, current page */
  --paper: #f6f8fc;        /* page */
  --card: #ffffff;         /* header and the quote band */
  --line: #dfe6f3;         /* hairlines */
  --footer-bg: #e9eef8;
  --on-accent: #ffffff;

  --display: 'Space Grotesk', ui-sans-serif, system-ui, sans-serif;
  --text: 'Source Sans 3', ui-sans-serif, system-ui, sans-serif;

  --wrap: 1080px;          /* the one width control for the home page */
  --column: 720px;         /* and the one for the inner pages */
  --gutter: clamp(1.1rem, 4vw, 2.5rem);
}

/* -------------------------------------------------------------------- base */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  color-scheme: light;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--body);
  font-family: var(--text);
  font-size: 1.1875rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

p { margin: 0 0 1.2em; }

a {
  color: var(--accent);
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.18em;
}
a:hover { color: var(--accent-deep); }

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

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

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

.wrap {
  width: 100%;
  max-width: calc(var(--wrap) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip {
  position: absolute;
  left: 0.75rem;
  top: -4rem;
  z-index: 10;
  padding: 0.55rem 0.9rem;
  border-radius: 6px;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--display);
  font-size: 0.95rem;
  font-weight: 500;
  text-decoration: none;
}
.skip:focus { top: 0.75rem; color: var(--on-accent); }

/* The blue and red rule that sits under every page's heading. */
.rule {
  display: flex;
  margin: 1.1rem 0 1.5rem;
}
.rule::before,
.rule::after {
  content: "";
  height: 5px;
}
.rule::before { width: 3.25rem; background: var(--accent); border-radius: 3px 0 0 3px; }
.rule::after  { width: 1.5rem;  background: var(--accent-2); border-radius: 0 3px 3px 0; }

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

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

.bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.35rem 1.5rem;
  padding-block: 0.7rem;
}

/* Just the name. No duck up here - see "one duck per screen" at the top. */
.brand {
  padding-block: 0.3rem;
  color: var(--ink);
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  text-decoration: none;
}
.brand:hover { color: var(--accent); }

.nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav a {
  display: block;
  padding: 0.4rem 0.7rem;
  border-radius: 6px;
  color: var(--body);
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 500;
  text-decoration: none;
}
.nav a:hover { background: var(--accent-wash); color: var(--accent-deep); }
.nav a[aria-current="page"] {
  color: var(--ink);
  box-shadow: inset 0 -3px 0 var(--accent-2);
  border-radius: 6px 6px 0 0;
}

/* -------------------------------------------------------------------- home */

main { flex: 1; display: flex; flex-direction: column; }

/* The hero sits between two FLEXIBLE spacers, 2 parts above to 3 below, so it
   rides a little above the middle on a tall screen (an iPad held upright) and
   the spacers simply shrink on a short one. They used to be fixed vh padding,
   and the page came out 1.5px taller than an 820px window: a scrollbar for
   nothing. Fixed padding around a block that is meant to fit the screen is
   the mistake; give the slack somewhere to go. */
.hero-band {
  flex: 1;
  display: grid;
  grid-template-rows: minmax(1.25rem, 2fr) auto minmax(1.25rem, 3fr);
}
.hero-band > .hero { grid-row: 2; }

/* The ring behind the duck is wider than its column. It must never widen the
   page: between about 1000 and 1170px it would otherwise reach past the
   gutter and produce a horizontal scrollbar. */
main { overflow-x: hidden; overflow-x: clip; }

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) min(32vw, 340px);
  grid-template-areas:
    "title art"
    "body  art";
  column-gap: clamp(1.5rem, 6vw, 5rem);
  align-items: center;
}

.hero-title { grid-area: title; align-self: end; }
.hero-body  { grid-area: body;  align-self: start; }
.hero-art   { grid-area: art; }

.hero h1 { font-size: clamp(2.35rem, 6.2vw, 4.6rem); }
.hero h1 span { color: var(--accent); }

.lede {
  max-width: 34em;
  margin-bottom: 1.6rem;
  font-size: 1.3rem;
  line-height: 1.55;
}

.interests-label {
  margin: 0 0 0.6rem;
  color: var(--ink);
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 500;
}

.interests {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin: 0 0 1.9rem;
  padding: 0;
  list-style: none;
}
.interests li {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.95rem 0.5rem 0.75rem;
  border: 1px solid var(--accent-soft);
  border-radius: 999px;
  background: var(--accent-wash);
  color: var(--accent-deep);
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.2;
}
.interests svg { width: 1.35rem; height: 1.35rem; flex: none; color: var(--accent); }

.button {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.8rem 1.25rem;
  border-radius: 10px;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 500;
  text-decoration: none;
  transition: background-color 0.15s ease, transform 0.15s ease;
}
.button:hover { background: var(--accent-deep); color: var(--on-accent); transform: translateY(-1px); }
.button svg { width: 1.3rem; height: 1.3rem; flex: none; }

/* The duck is a JPEG with a white background. multiply turns that white into
   whatever is behind it, so the disc shows through and no box appears. Two
   traps from the README still apply: never put `filter` on this same element
   (it silently switches the blend off), and everything behind it must stay
   light or the duck goes dark with it. */
/* The duck is the tallest thing in the hero, so its size follows the HEIGHT of
   the window as well as the width: 40svh wide is about 56svh tall. That is what
   lets the whole page fit an iPad in landscape with Safari's bars showing. */
.hero-art {
  justify-self: center;
  width: 100%;
  max-width: min(340px, 40vh);
  max-width: min(340px, 40svh);
}
.duck { position: relative; }
/* No `isolation` and no negative z-index here, on purpose. An isolated group
   starts from a transparent backdrop, so the duck's corners (outside the
   disc) multiplied against nothing and stayed white. The disc sits at
   z-index 0 and the duck at 1 in the page's own stacking context, so the
   duck blends with the disc AND the page behind it.

   The pale disc is the ONLY decoration. A small red ring used to float by the
   duck's head; John called it "an odd circle" on 2026-09-18 and it went. Do
   not add ornaments around the duck. */
.duck::before {
  content: "";
  position: absolute;
  z-index: 0;
  border-radius: 50%;
  left: 50%;
  top: 54%;
  width: 112%;           /* plus the 12px halo: must stay inside the gutter */
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: #e4ecfb;
  box-shadow: 0 0 0 12px #eef3fd;
}
.duck img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: auto;
  mix-blend-mode: multiply;
}

/* The featured quote, a white band across the bottom of the home page. */
.pull {
  background: var(--card);
  border-top: 1px solid var(--line);
}
.pull .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1.1rem;
  padding-block: 1.05rem;
}
.pull blockquote {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  margin: 0;
  flex: 1 1 18rem;
}
.pull blockquote p {
  margin: 0;
  color: var(--ink);
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.01em;
}
.mark {
  flex: none;
  height: 0.55em;
  margin-top: 0.08em;
  color: var(--accent-2);
  font-family: var(--display);
  font-size: 3.4rem;
  font-weight: 700;
  line-height: 1;
}
.more {
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 500;
  white-space: nowrap;
}

/* ------------------------------------------------------------- inner pages */

/* Same skeleton as the home page: the heading and the text share the
   header's left edge, and the duck stands on the right. Moving between pages
   should not move the margin. It is the same three-cell grid as the hero -
   title, duck, body - so on a phone the duck can move up beside the heading
   and every screen still has its one duck. */
.split {
  display: grid;
  grid-template-columns: minmax(0, var(--column)) minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "title art"
    "body  art";
  column-gap: clamp(2rem, 6vw, 5rem);
  align-items: start;
  padding-block: clamp(2.25rem, 7vh, 4.5rem);
}
.page-title { grid-area: title; min-width: 0; }
.page { grid-area: body; min-width: 0; }
.side-art {
  grid-area: art;
  justify-self: end;
  width: min(100%, 230px);
  margin: 1.5rem 1.5rem 0 0;
}
.page-title h1 { font-size: clamp(2.2rem, 5.2vw, 3.4rem); }
.page > p { font-size: 1.25rem; }
.page > p:last-child { margin-bottom: 0; }

/* Quotes: type, a red mark and a hairline. No boxes inside boxes. */
.quote {
  margin: 0;
  padding: 1.75rem 0;
  border-top: 1px solid var(--line);
}
.quote:first-of-type { border-top: 0; padding-top: 0.25rem; }
.quote blockquote {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  margin: 0 0 0.7rem;
}
.quote blockquote p {
  margin: 0;
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(1.45rem, 3.4vw, 2rem);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
.quote .mark { font-size: 4.2rem; }
.quote figcaption {
  padding-left: 2.85rem;
  color: var(--muted);
  font-size: 1.1rem;
}

/* Privacy Policy is a one line joke, so the one line gets the room. */
.nope {
  margin: 0 0 1rem;
  color: var(--accent);
  font-size: clamp(3.5rem, 13vw, 7rem);
  letter-spacing: -0.04em;
}
.page strong { color: var(--ink); }

/* 404 */
.lost { text-align: left; }
.lost .button { margin-top: 0.5rem; }

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

.site-footer {
  background: var(--footer-bg);
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 1.02rem;
}
.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 2rem;
  padding-block: 1.1rem;
}
.site-footer ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-footer ul a {
  color: var(--body);
  font-family: var(--display);
  font-size: 0.98rem;
  font-weight: 500;
  text-decoration: none;
}
.site-footer ul a:hover { color: var(--accent-deep); text-decoration: underline; }
.site-footer ul a[aria-current="page"] { color: var(--ink); }
.site-footer p { margin: 0; }

/* ------------------------------------------------------------------ narrow */

@media (max-width: 860px) {
  .hero { grid-template-columns: minmax(0, 1fr) min(30vw, 240px); }
  .split { grid-template-columns: minmax(0, 1fr) min(24vw, 190px); }
  .side-art { width: 100%; margin: 0.5rem 0 0; }
}

/* Phones: the duck moves up beside the headline so the name, the line about
   him and the duck are all on the first screen. */
@media (max-width: 620px) {
  body { font-size: 1.125rem; }
  .hero {
    grid-template-columns: minmax(0, 1fr) 104px;
    grid-template-areas:
      "title art"
      "body  body";
    column-gap: 1rem;
    align-items: center;
  }
  .hero-title { align-self: end; }
  .hero h1 { font-size: clamp(1.95rem, 9.2vw, 2.6rem); }
  .split {
    grid-template-columns: minmax(0, 1fr) 84px;
    grid-template-rows: auto auto;
    grid-template-areas:
      "title art"
      "body  body";
    column-gap: 1rem;
    padding-block: 1.75rem 2.5rem;
  }
  .page-title { align-self: end; }
  .side-art { align-self: center; margin: 0; }
  .hero-band { grid-template-rows: 1.75rem auto 2.5rem; }
  .duck::before { width: 110%; box-shadow: 0 0 0 7px #eef3fd; }
  .lede { font-size: 1.2rem; }
  .pull blockquote p { font-size: 1.2rem; }
  .quote figcaption { padding-left: 0; }
}

@media (max-width: 480px) {
  .button { width: 100%; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .button { transition: none; }
  .button:hover { transform: none; }
}

@media print {
  .site-header .nav, .site-footer ul, .skip { display: none; }
  body { background: #fff; }
}
