/* ==========================================================================
   rodaustin.com
   Layout, type and chrome match the live site (see capture/VISUAL-DIFF.md).
   Color does not: the teal accent ramp and neutral palette are the build's own
   and are deliberately unchanged. The five mount animations and every rebuilt
   hover state are also unchanged.
   ========================================================================== */

/* - fonts - self-hosted from Google Fonts, downloaded at build time and served
     locally. No Google Fonts link. Latin and latin-ext subsets only; the browser
     fetches a subset only when a page actually renders characters from it.
     Fraunces = display, Public Sans = body, IBM Plex Mono = chrome. - */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/fraunces-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/fonts/fraunces-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/plexmono-400-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/plexmono-400-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/plexmono-500-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/plexmono-500-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/fonts/publicsans-latin.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("/fonts/publicsans-latin-ext.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* - tokens - */

:root {
  /* Palette adopted from the live site (capture/COMPUTED-DIFF.md). Every value
     below is a hex measured off the rendered live page at 1440px. */

  /* Grounds */
  /* Live declares --paper: #EFEDE6 and never applies it, so the live page ground
     renders #ffffff. This build uses the declared value: the same Bricks version
     has two other confirmed declaration-compile failures (font-family,
     flex-direction), so a failed declaration is likelier than a deliberate white.
     #EFEDE6 is also the value --card (#fbfaf6) and --rule (#dedbd2) were designed
     against, and the card only separates from the ground once it is in place. */
  --color-page: #efede6;          /* body / html, the ground the frame sits on */
  --color-surface: #fbfaf6;       /* the frame card, and form field fills */
  --color-portrait-fill: #e8e6de; /* inside the portrait frame */

  /* Ink */
  --color-text: #363636;          /* default text, headings, list items */
  --color-ink: #1b1c19;           /* wordmark, lead paragraphs, field text */
  --color-ink-soft: #56584f;      /* labels, dates, excerpts, footer, ledes */

  /* Hairlines: every rule on the page is 1px of this */
  --color-rule: #dedbd2;

  /* Accent. Live's green replaces the build's teal; where the two disagreed,
     live wins. Steps 600 and 700 are live's own --green and --green-deep; the
     rest are generated in OKLCH at live's hue (170) on a monotonic lightness
     ladder, for the tints the build uses that live has no equivalent for. */
  --color-accent: #14624d;
  --color-accent-deep: #0e5343;
  --color-accent-100: #e5f2ed;
  --color-accent-200: #d0e1da;
  --color-accent-300: #afcabf;
  --color-accent-400: #80a899;
  --color-accent-500: #498470;
  --color-accent-600: #14624d;
  --color-accent-700: #0e5343;
  --color-accent-800: #183f33;
  --color-accent-900: #1b3029;

  /* On the accent block */
  --color-on-accent: #ffffff;
  --color-on-accent-soft: rgb(255 255 255 / 0.72);
  --color-on-accent-border: #ffffff;

  /* Hover invert target, kept from the build's rebuilt hover states but moved
     onto live's darkest ink so no value sits outside live's palette. */
  --color-invert-surface: #1b1c19;

  --font-display: 'Fraunces', Georgia, serif;
  --font-body: 'Public Sans', system-ui, -apple-system, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 28px;
  --space-8: 32px;

  --radius: 0px;
  --rule: 1px;

  --shell-max: 1060px;
  --frame-inset: clamp(14px, 1.379vw + 8.83px, 24px);
  --frame-margin: clamp(18px, 2.207vw + 9.72px, 34px);
  --gutter: clamp(26px, 2.759vw + 15.66px, 46px);

  --fs-display-xl: clamp(38px, 1.655vw + 31.79px, 50px);
  --fs-display-l: clamp(25px, 0.69vw + 22.41px, 30px);
  --fs-display-m: clamp(23px, 0.552vw + 20.93px, 27px);
  --fs-display-s: 20px;
  --fs-lede: 16px;
  --fs-base: 15px;
  --fs-small: 14px;
  --fs-xs: 13px;
  --fs-mono: 11px;
  --fs-mono-s: 10px;

  --ls-mono: 0.11em;
  --ls-display: -0.01em;

  --ease-grow: cubic-bezier(.2, .7, .2, 1);
}

/* - base - */

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

html { -webkit-text-size-adjust: 100%; background: var(--color-page); }

body {
  margin: 0;
  background: var(--color-page);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.7;
  font-weight: 400;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
a:hover { color: var(--color-accent); }
img { display: block; max-width: 100%; height: auto; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: var(--ls-display);
  margin: 0;
}

:focus { outline: none; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* Every piece of chrome on the site: nav, eyebrows, labels, dates, field
   labels, buttons, footer. Mono, uppercase, letterspaced. */
.mono {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* Honeypot wrapper.
   Deliberately NOT display:none, visibility:hidden, or the hidden attribute:
   those are the three things a form-filling bot checks before deciding to skip
   a field, and a field bots skip catches nothing. Pushing it out of the
   viewport leaves it "visible" to anything reading the DOM or the CSSOM, while
   no sighted user can reach it.
   Screen readers are handled in the markup instead - aria-hidden="true" on this
   wrapper removes it from the accessibility tree, and tabindex="-1" on the
   input keeps it out of the tab order so nothing focusable hides inside an
   aria-hidden subtree. */
.hp-wrap {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.skip-link {
  position: absolute; left: var(--space-2); top: -100px;
  z-index: 10;
  background: var(--color-accent); color: var(--color-on-accent);
  padding: var(--space-2) var(--space-4);
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono); text-transform: uppercase;
}
.skip-link:focus { top: var(--space-2); color: var(--color-on-accent); }

/* - the frame: a bordered card floating on the page ground - */

.shell {
  max-width: var(--shell-max);
  width: calc(100% - (var(--frame-inset) * 2));
  margin: var(--frame-margin) auto;
  background: var(--color-surface);
  border: var(--rule) solid var(--color-rule);
  color: var(--color-text);
}

/* - header - */

.nav {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-6);
  padding: 26px var(--gutter);
  border-bottom: var(--rule) solid var(--color-rule);
}
.nav-brand {
  font-family: var(--font-display);
  font-size: 20px;
  letter-spacing: var(--ls-display);
  color: var(--color-ink);
}
.nav-links { display: flex; align-items: center; gap: 28px; }
.nav-links a {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--color-accent);
  border-bottom: var(--rule) solid transparent;
  padding-bottom: 2px;
  transition: color .2s, border-bottom-color .2s;
}
.nav-links a:hover,
.nav-links a[aria-current="page"] {
  border-bottom-color: var(--color-accent);
  color: var(--color-accent);
}

/* - hero - */

.hero {
  display: flex;
  align-items: flex-start;
  gap: 54px;
  padding: 52px var(--gutter) 58px;
}
.hero-body { flex: 1 1 auto; min-width: 0; }

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: 22px;
}
.hero h1 {
  font-size: var(--fs-display-xl);
  line-height: 1.1;
  letter-spacing: -0.012em;
  margin-bottom: 30px;
  max-width: 15ch;
  text-wrap: pretty;
}
.lede {
  font-size: var(--fs-lede);
  line-height: 1.7;
  max-width: 48ch;
  color: var(--color-ink-soft);
  text-wrap: pretty;
}

/* Portrait: 176px column, 1px frame, no padding. The source PNG is a cutout
   already trimmed to the subject on all four edges, so the box is sized to the
   image's own 400:464 ratio less ~20px - the portrait is pinned to the bottom
   inside edge and its head crosses the top rule. */
/* The hero is a flex row with align-items: flex-start, which is what pinned the
   portrait to the top of the text column. Centring this one item rather than
   changing the container's align-items leaves .hero-body top-aligned, which is
   what the eyebrow and h1 rely on. */
.hero-aside { flex: 0 0 176px; width: 176px; align-self: center; }
.portrait-frame {
  position: relative;
  aspect-ratio: 400 / 418;
  border: var(--rule) solid var(--color-rule);
  background: var(--color-portrait-fill);
  transition: transform .45s var(--ease-grow);
}
.portrait {
  position: absolute;
  left: 0;
  bottom: 0;
  display: block;
  width: 100%;
  height: auto;
  filter: grayscale(1) contrast(1.08);
}

/* Hover is on the column, not the frame: the head overflows the box, so a
   frame-scoped hover would miss it. */
.hero-aside:hover .portrait-frame { transform: translateY(-5px) rotate(-0.75deg); }

.accent-rule {
  height: var(--rule);
  background: var(--color-accent);
  transform-origin: left;
}

/* - row: label column + body - */

.band {
  display: flex;
  align-items: flex-start;
  gap: 54px;
  padding: 42px var(--gutter);
  border-bottom: var(--rule) solid var(--color-rule);
}
.label {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--color-ink-soft);
}
.band-label {
  flex: 0 0 176px;
  width: 176px;
  padding-top: 5px;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--color-ink-soft);
}
.band-content { flex: 1 1 auto; max-width: 60ch; min-width: 0; }
.band-content > * + * { margin-top: 20px; }
.band-content p { line-height: 1.7; color: var(--color-ink); }
.band-content p.muted { color: var(--color-text); }
.band-content h2 {
  font-size: var(--fs-display-m);
  line-height: 1.2;
  text-wrap: pretty;
}

/* Category list: hairline rules, no markers. */
.band-list {
  border-top: var(--rule) solid var(--color-rule);
}
.band-list li {
  padding: 11px 0;
  border-bottom: var(--rule) solid var(--color-rule);
  line-height: 1.7;
}
/* The base rule renders an unstyled link identically to body text, which left
   the 404 and thank-you recovery links with no affordance at all. Same
   treatment as links in a post body - accent plus underline, so it does not
   rely on colour alone. */
.band-list a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* - writing - */

.writing {
  padding: 42px var(--gutter) 48px;
  border-bottom: var(--rule) solid var(--color-rule);
}
.writing-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-6);
  margin-bottom: 26px;
}
.writing-head h2 { font-size: var(--fs-display-m); line-height: 1.2; }
.writing-more { font-size: var(--fs-xs); color: var(--color-accent); white-space: nowrap; }

.post-list { border-top: var(--rule) solid var(--color-rule); }

.post-row {
  display: flex;
  align-items: baseline;
  gap: 26px;
  padding: 20px 0;
  border-bottom: var(--rule) solid var(--color-rule);
  transition: background .25s, padding .25s;
}
@media (hover: hover) {
  .post-row:hover { background: var(--color-accent-100); padding-left: var(--space-4); }
}
.post-row:focus-visible { background: var(--color-accent-100); padding-left: var(--space-4); }

.post-meta-line { display: contents; }
.post-index {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.09em;
  color: var(--color-accent);
}
.post-date {
  flex: 0 0 96px;
  width: 96px;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-ink-soft);
}
.post-main { flex: 1 1 auto; min-width: 0; }
.post-title {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-display-s);
  line-height: 1.25;
  margin-bottom: 4px;
  color: var(--color-accent);
}
.post-excerpt { display: block; font-size: var(--fs-small); line-height: 1.7; color: var(--color-ink-soft); }

/* - use case / contact - */

.usecase {
  padding: 42px var(--gutter) 48px;
  border-bottom: var(--rule) solid var(--color-rule);
}
.usecase h2 {
  font-size: var(--fs-display-m);
  line-height: 1.2;
  max-width: 22ch;
  margin: 14px 0 20px;
  text-wrap: pretty;
}
.usecase p { max-width: 58ch; line-height: 1.7; color: var(--color-ink-soft); }
.usecase p + p { margin-top: 20px; }

/* - forms - */

.form-stack { max-width: 560px; margin-top: 26px; }
.form-field { margin-bottom: 18px; }
.form-field label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-mono-s);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--color-ink-soft);
  margin-bottom: 7px;
}
.form-field .field-input,
.form-field textarea {
  width: 100%;
  background: var(--color-surface);
  border: var(--rule) solid var(--color-rule);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.7;
  padding: 11px 13px;
  border-radius: var(--radius);
}
.form-field textarea { min-height: 108px; resize: vertical; }
.form-field .field-input:focus-visible,
.form-field textarea:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

.btn-primary {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  background: var(--color-accent);
  color: var(--color-on-accent);
  border: var(--rule) solid var(--color-accent);
  padding: 12px 22px;
  cursor: pointer;
  border-radius: var(--radius);
  transition: background .2s, color .2s, border-color .2s;
}
.btn-primary:hover {
  background: var(--color-invert-surface);
  border-color: var(--color-invert-surface);
  color: var(--color-on-accent);
}

/* - newsletter - */

.newsletter {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 46px;
  padding: 46px var(--gutter);
  background: var(--color-accent);
  color: var(--color-on-accent);
}
.newsletter-label {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--color-on-accent-soft);
}
.newsletter h2 {
  font-size: var(--fs-display-l);
  line-height: 1.16;
  max-width: 15ch;
  margin-top: 14px;
  text-wrap: pretty;
}
.newsletter-form { display: flex; flex: 0 0 380px; width: 380px; min-width: 0; }
.newsletter-form .field-input {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--color-on-accent);
  border: var(--rule) solid var(--color-on-accent);
  border-right: none;
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--fs-small);
  padding: 12px 14px;
  border-radius: var(--radius);
}
.newsletter-form .field-input:focus-visible {
  outline: 2px solid var(--color-on-accent-border);
  outline-offset: 1px;
}
.btn-subscribe {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  background: var(--color-on-accent);
  color: var(--color-accent);
  border: var(--rule) solid var(--color-on-accent);
  padding: 12px 22px;
  cursor: pointer;
  white-space: nowrap;
  border-radius: var(--radius);
  transition: background .2s, color .2s, border-color .2s;
}
.btn-subscribe:hover {
  background: var(--color-invert-surface);
  border-color: var(--color-invert-surface);
  color: var(--color-on-accent);
}

/* - post article - */

.post-hero { padding: 52px var(--gutter) 58px; }
.post-hero h1 {
  font-size: var(--fs-display-xl);
  line-height: 1.1;
  letter-spacing: -0.012em;
  max-width: 20ch;
  text-wrap: pretty;
  margin-bottom: 22px;
}
.post-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-ink-soft);
}
.post-body { padding: 42px var(--gutter) 48px; max-width: calc(60ch + (var(--gutter) * 2)); }
.post-body p, .post-body ul, .post-body ol { line-height: 1.7; margin: 0 0 20px; }
.post-body ul, .post-body ol { padding-left: var(--space-5); list-style: disc; }
.post-body li { margin-bottom: var(--space-2); }
.post-body h2 { font-size: var(--fs-display-m); line-height: 1.2; margin: var(--space-8) 0 var(--space-4); }
.post-body h3 { font-size: var(--fs-display-s); line-height: 1.25; margin: var(--space-7) 0 var(--space-3); }
.post-body a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; }
.post-body code { font-family: var(--font-mono); font-size: 0.9em; background: var(--color-accent-100); padding: 2px 5px; }
.post-body pre {
  font-family: var(--font-mono);
  background: var(--color-accent-900); color: var(--color-accent-100);
  padding: var(--space-4); overflow-x: auto; margin: 0 0 20px;
}
.post-body pre code { background: none; padding: 0; }
.post-body blockquote {
  margin: 0 0 20px; padding-left: var(--space-5);
  border-left: var(--rule) solid var(--color-accent);
  font-family: var(--font-display); font-size: var(--fs-lede);
}

.post-back { padding: 0 var(--gutter) 42px; }
.post-back a {
  font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono); text-transform: uppercase;
  color: var(--color-accent);
}

/* - footer - */

.footer {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-6);
  padding: 24px var(--gutter);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--color-ink-soft);
}
.footer-links { display: flex; align-items: center; gap: 26px; }

/* ==========================================================================
   Mount animations - unchanged. Same keyframes, durations, delays and easing
   as the design bundle. They fire once on load. Live has none of these; they
   are deliberately kept.
   ========================================================================== */

@keyframes rise  { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes fade  { from { opacity: 0; }                              to { opacity: 1; } }
@keyframes growx { from { transform: scaleX(0); }                    to { transform: scaleX(1); } }

.anim-eyebrow  { animation: fade  .6s  both; }
.anim-title    { animation: rise  .8s  .05s both; }
.anim-lede     { animation: rise  .8s  .18s both; }
.anim-aside    { animation: fade  .9s  .3s  both; }
.anim-rule     { animation: growx 1.1s .35s both var(--ease-grow); }

/* The portrait column drifts a little as the hero scrolls away. Scroll-driven
   timelines are Chromium-only today; elsewhere the mount fade stands alone and
   nothing else changes. */
@keyframes drift { to { transform: translateY(-18px); } }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .anim-aside {
      animation: fade .9s .3s both, drift linear both;
      animation-timeline: auto, view();
      animation-range: normal, exit 0% exit 100%;
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  .hero-aside:hover .portrait-frame { transform: none; }
}

/* ==========================================================================
   Responsive. Live collapses everything at one 820px breakpoint; the build
   keeps its own two-breakpoint layer (768px, 600px).
   ========================================================================== */

@media (max-width: 767.98px) {
  .hero { display: block; }
  /* The hero is no longer a flex row here, so align-self does nothing and
     vertical centring has no meaning - the portrait simply follows the text.
     Horizontal centring is the axis that matters once it is stacked. */
  .hero-aside { width: auto; max-width: 176px; margin: 32px auto 0; }

  .band { display: block; }
  .band-label { width: auto; padding-top: 0; margin-bottom: 16px; }
  .band-content { max-width: none; }

  .newsletter { display: block; }
  .newsletter h2 { max-width: 22ch; }
  .newsletter-form { width: auto; margin-top: 24px; }

  /* The 96px date column and the index stop earning their width. */
  .post-row { display: block; }
  .post-meta-line { display: flex; align-items: baseline; gap: var(--space-3); margin-bottom: 6px; }
  .post-date { width: auto; flex: 0 0 auto; }
}

@media (max-width: 599.98px) {
  .nav { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
  .nav-links { flex-wrap: wrap; gap: var(--space-3) var(--space-5); }

  .writing-head { flex-direction: column; align-items: flex-start; gap: var(--space-3); }

  .footer { flex-direction: column; gap: var(--space-3); }
  .footer-links { flex-wrap: wrap; gap: var(--space-3) var(--space-5); }

  /* The joined input and button cannot share a border edge when stacked. */
  .newsletter-form { flex-direction: column; gap: var(--space-3); }
  .newsletter-form .field-input { border-right: var(--rule) solid var(--color-on-accent); }
  .btn-subscribe { text-align: center; }
}

@media (max-width: 359.98px) {
  .post-meta-line { flex-wrap: wrap; gap: var(--space-1) var(--space-3); }
}
