/* ==== Tokens: palette, type, and spacing ====================================== */

/* Studio design tokens. Raw design decisions live here; component CSS only consumes semantic variables. */
:root {
  color-scheme: light;
  overflow-x: clip;
  --graza-cream: oklch(93.783% 0.02621 71.19);
  --graza-tint: oklch(87.448% 0.0457 69.33);
  --graza-ink: oklch(29.194% 0.04694 145.28);
  --graza-lime: oklch(90.065% 0.20002 115.87);
  --graza-coral: oklch(70.923% 0.18564 34.78);
  /* Brand coral at pastel card weight: ink AAA (7.34), muted AA (4.64). */
  --graza-coral-tint: oklch(82% 0.12 34.78);
  /* Rose highlight for the journal bibliography: ink AAA (8.34), muted AA (5.27). */
  --graza-pink: oklch(85% 0.09 5);
  --graza-yellow: oklch(86.884% 0.13035 88.44);
  --graza-sky: oklch(84.433% 0.05933 211.05);
  --graza-hero-deep-ink: oklch(19.934% 0.02228 158.02);
  --graza-media-paper: oklch(98% 0.008 71.19);
  --graza-accent-ink: var(--graza-ink);
  --graza-line: color-mix(in oklch, var(--graza-ink) 66%, transparent);
  --graza-rule: color-mix(in oklch, var(--graza-ink) 28%, transparent);
  --graza-rule-on-dark: color-mix(in oklch, var(--graza-cream) 28%, transparent);
  --graza-cream-glow-soft: color-mix(in oklch, var(--graza-cream) 16%, transparent);
  --graza-cream-glow-faint: color-mix(in oklch, var(--graza-cream) 5%, transparent);
  --graza-cream-glow-halo: color-mix(in oklch, var(--graza-cream) 32%, transparent);
  --graza-hero-scrim-strong: color-mix(in oklch, var(--graza-hero-deep-ink) 78%, transparent);
  --graza-hero-scrim-mid: color-mix(in oklch, var(--graza-hero-deep-ink) 60%, transparent);
  --graza-hero-scrim-edge: color-mix(in oklch, var(--graza-hero-deep-ink) 68%, transparent);
  --graza-hero-scrim-floor: color-mix(in oklch, var(--graza-hero-deep-ink) 72%, transparent);
  --graza-panel-translucent: color-mix(in oklch, var(--graza-cream) 94%, transparent);
  --graza-control-on-dark: color-mix(in oklch, var(--graza-hero-deep-ink) 72%, transparent);
  --graza-control-rule-on-dark: color-mix(in oklch, var(--graza-cream) 72%, transparent);
  --graza-field-surface: color-mix(in oklch, var(--graza-cream) 72%, transparent);
  --graza-type-section: clamp(2.75rem, calc(2rem + 3.5vw), 5.5rem);
  --graza-type-hero: clamp(3.25rem, calc(2rem + 5vw), 6.5rem);
  --graza-mark-compact-block-size: 2.25rem;
  --graza-mark-block-size: 2.75rem;
  --graza-space-section-tight: clamp(4.25rem, 6vw, 6rem);
  --graza-space-section-standard: clamp(5rem, 8vw, 8rem);
  --graza-space-section-expansive: clamp(6rem, 10vw, 10rem);
  --graza-duration-fast: 150ms;
  --graza-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  /* Base component rules read these short aliases. */
  --coral: oklch(47.376% 0.15188 35.17);
  --coral-dark: oklch(40.257% 0.12916 36.41);
  --cream: var(--graza-cream);
  --ink: var(--graza-ink);
  /* 41% keeps muted text at AA on every light fill, including coral-tint. */
  --muted: oklch(41% 0.03365 134.03);
  --navy: var(--graza-ink);
  --border: var(--graza-ink);
  --shadow-soft: none;
  --sage: #7c8b78;
  --butter: #f6d27a;
  --sky: #b8d8dc;
  /* Book serif for reading and display; a typewriter mono for labels only.
     Offset shadows go flat, so every rule that reads them prints flat. */
  /* An open arrowhead; link arrows draw their shaft separately so it can
     stretch on hover. */
  --arrow-head: url("/assets/images/arrow-head.svg");
  --graza-font-display: 'Newsreader', Georgia, serif;
  --graza-font-body: 'Newsreader', Georgia, serif;
  --graza-font-mono: 'IBM Plex Mono', ui-monospace, monospace;
  --graza-type-label: 0.8125rem;
  --graza-type-ui: 0.8125rem;
  --print-radius: 3px;
  --shadow: none;
  --shadow-coral: none;
}

/* ==== Base: reset, layout, and shared components ============================== */

html {
  scroll-behavior: smooth;
  scroll-padding-top: 100px;
}

/* Firefox ignores the page's scroll padding when Shift+Tab moves focus
   upward, so focused links landed under the sticky header. A scroll margin
   on the focusable elements themselves covers that case; other browsers
   already honour the padding, so this is Firefox-only. */
@supports (-moz-appearance: none) {
  :is(a, button, input, textarea, select, summary, [tabindex]) {
    scroll-margin-top: 100px;
  }

  @media (max-width: 1100px) {
    :is(a, button, input, textarea, select, summary, [tabindex]) {
      scroll-margin-top: 150px;
    }
  }
}

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

body {
  line-height: 1.6;
  position: relative;
  /* Hallmark · pre-emit critique: P5 H5 E5 S5 R5 V5 · enrichment: Counterstep Loom · honest: pass (46) · chrome: pass (47) · tokens: pass (48) · responsive: pass (49) · icons: pass (30) · mobile: pass (34, 49, 50–57). */
  color: var(--graza-ink);
  background: var(--graza-cream);
  background-image: none;
  font-family: var(--graza-font-body);
  overflow-x: clip;
  /* Newsreader sets its own display spacing at large optical sizes, so the
     Georgia-era negative tracking would crush it. */
  font-size: 1.125rem;
  font-optical-sizing: auto;
}

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

a {
  color: inherit;
  text-decoration: none;
}

a:hover {
  color: var(--coral);
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  border-radius: 4px;
}

/* Buttons keep their own square print corners on focus. */
.button:focus-visible {
  border-radius: var(--print-radius);
}

.skip-link {
  position: absolute;
  top: -100px;
  left: 24px;
  background: var(--coral);
  color: white;
  padding: 0.5rem 1rem;
  border-radius: 999px;
  z-index: 1000;
}

.skip-link:focus {
  top: 24px;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  color: var(--graza-cream);
  background: var(--graza-ink);
  border-bottom: 1px solid var(--graza-rule-on-dark);
}

.nav {
  justify-content: space-between;
  gap: 1.5rem;
}

.nav-deck {
  display: none;
}

/* On home the nameplate is the logo, so main.js marks the header while the
   nameplate is on screen. The nav then keeps only the cowboy, and the
   wordmark slides in once the nameplate passes under the sticky bar. The
   clip is horizontal only, so the wordmark's descenders still show. */
.nav-brand span {
  max-width: 12em;
  overflow-x: clip;
}

.site-header[data-brand-hidden] .nav-brand {
  gap: 0;
}

.site-header[data-brand-hidden] .nav-brand span {
  max-width: 0;
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .nav-brand {
    transition: gap 0.35s ease;
  }

  .nav-brand span {
    transition: max-width 0.35s ease, opacity 0.25s ease;
  }
}

.nav-brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-weight: 700;
  text-transform: none;
  flex-shrink: 0;
  min-height: 44px;
  font-family: var(--graza-font-display);
  font-size: 1.35rem;
}

.nav-brand img {
  width: auto;
  height: 50px;
}

.nav-links {
  display: flex;
  list-style: none;
  gap: 0.25rem;
  color: var(--graza-cream);
  font-family: var(--graza-font-mono);
  line-height: 1.3;
  text-transform: uppercase;
  /* Labels set in mono read as a typewritten slug, not a startup chip. */
  font-size: var(--graza-type-ui);
  /* Plex Mono ships 400 and 500 only; 600 rendered as a smeared fake bold. */
  font-weight: 500;
  letter-spacing: 0.04em;
}

.nav-links a {
  transition: background-color 0.2s ease, color 0.2s ease;
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  border-radius: 0;
  border-bottom: 1px solid transparent;
  padding: 0.4rem 0.55rem;
  white-space: nowrap;
}

.hero {
  position: relative;
  overflow: hidden;
}

/* The hero canvas (the Strange Attractor Drift). Hidden by default; the
   home hero and page heroes show it. */
.attractor-background {
  position: absolute;
  inset: 0;
  z-index: 1;
}

.attractor-background canvas {
  width: 100%;
  height: 100%;
  transition: opacity 240ms ease;
}

.attractor-background--ready canvas {
  opacity: 1;
}

.hero-grid {
  display: grid;
}

.hero-copy {
  display: flex;
  flex-direction: column;
}

.hero-sub {
  margin-top: -0.5rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.85rem 1.6rem;
}

.hero-card {
  position: relative;
}

.hero-card__title {
  width: fit-content;
}

.hero-card ul {
  list-style: none;
  color: var(--muted);
}

.hero-card li {
  position: relative;
}

.hero-card li::before {
  left: 0;
  font-weight: 700;
}

.hero-card li strong {
  font-weight: 700;
}

.section {
  padding: 4.5rem 0;
  position: relative;
}

/* Low specificity, so section-specific padding still wins. */
.section:where(section:last-of-type) {
  padding-bottom: 6rem;
}

.section--tint {
  background: linear-gradient(120deg, rgba(246, 210, 122, 0.18) 0%, rgba(255, 255, 255, 0.9) 55%);
}

.section-heading {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  align-items: flex-start;
  max-width: 100%;
  margin-bottom: clamp(2.5rem, 5vw, 5rem);
  text-align: left;
}

.section-heading h2 {
  position: relative;
  max-width: 12ch;
  padding: 0;
  line-height: 0.92;
}

.section-heading h2::after {
  content: "";
  width: 80px;
  height: 3px;
  background: var(--coral);
  margin: 0.75rem auto 0;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  display: none;
}

.card-grid {
  display: grid;
  gap: 1.75rem;
}

.card-grid--three {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.card a {
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.14em;
}

.logo-strip {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  align-items: center;
  justify-items: center;
}

@media (min-width: 768px) {
  .logo-strip {
    grid-template-columns: repeat(3, 1fr);
  }
}

.logo-strip a {
  display: block;
  width: 100%;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.logo-strip img {
  width: 100%;
  object-fit: contain;
}

.logo-strip a:hover {
  transform: translate(-2px, -2px);
}

.team-grid {
  display: grid;
  position: relative;
  z-index: 1;
}

.team-card {
  position: relative;
  z-index: 1;
}

.team-card img {
  image-rendering: auto;
  background: #f7f1ea;
  display: block;
}

.team-portrait {
  position: relative;
  display: grid;
}

.team-card .team-portrait-paint {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  pointer-events: none;
}

.team-portrait:is(:hover, :focus-visible) .team-portrait-paint {
  opacity: 1;
}

.team-card .content p {
  margin-bottom: 1rem;
}

.team-card .team-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}

#team {
  background: linear-gradient(135deg, #f04e35 0%, #f7a86b 100%);
  position: relative;
}

#team::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.25) 1px, transparent 1px);
  background-size: 10px 10px;
  opacity: 0.25;
  pointer-events: none;
  z-index: 0;
}

#team .section-heading {
  position: relative;
  z-index: 1;
}

#team .section-heading h2::after {
  background: white;
}

.team-card .location {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
}

.team-card .social-links {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

.team-card .social-links a {
  font-weight: 600;
  text-decoration: underline;
  font-size: 0.95rem;
}

.team-card .social-links a:hover {
  text-decoration-line: underline;
}

/* Bio links sit inside running text, so mark them like other text links. */
.team-card .content > p a {
  text-decoration: underline;
}

.testimonial {
  position: relative;
}

.testimonial::before {
  content: "\201C";
  position: absolute;
  top: 0.4rem;
  left: 1rem;
  font-size: 3rem;
  color: rgba(239, 75, 55, 0.2);
}

.blog-card {
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

#talks .blog-meta {
  text-transform: uppercase;
}

.blog-card .content {
  padding: 1.5rem;
  display: grid;
  gap: 0.75rem;
}

.blog-card p {
  color: var(--muted);
}

.blog-meta {
  text-transform: uppercase;
}

.featured-post {
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.featured-post__content {
  padding: 1.75rem;
  display: grid;
  align-content: start;
  gap: 0.9rem;
}

.card-grid--editorial {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.contact {
  position: relative;
  overflow: hidden;
}

.contact::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.25) 1px, transparent 1px);
  background-size: 10px 10px;
  opacity: 0.25;
  pointer-events: none;
}

.contact form {
  display: grid;
  gap: 1rem;
}

.contact form p {
  margin: 0;
}

.contact form label {
  width: 100%;
}

.contact input,
.contact textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  font-family: inherit;
}

.contact button {
  justify-self: start;
}

.contact a {
  font-weight: 600;
  text-decoration: underline;
}

.site-footer {
  margin-top: 0;
  position: relative;
  padding: clamp(4rem, 7vw, 6.5rem) 0 2rem;
  color: var(--graza-cream);
  background: var(--graza-ink);
  border-top: 0;
  overflow-x: clip;
}

.site-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(239, 75, 55, 0.03) 1px, transparent 1px);
  background-size: 20px 20px;
  opacity: 0.4;
  pointer-events: none;
  display: none;
}

.footer-content {
  display: grid;
  margin-bottom: 2.5rem;
  grid-template-columns: minmax(0, 2fr) minmax(10rem, 0.45fr) minmax(14rem, 0.6fr);
  gap: clamp(2rem, 4vw, 4rem);
}

.footer-section ul {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.footer-about p {
  line-height: 1.7;
  margin-bottom: 1rem;
}

.footer-logo {
  margin-bottom: 1.5rem;
  /* Size the box itself. An inline-block sized by a percentage-width image has
     no width until the lazy image loads, so the footer jumps taller. */
  position: relative;
  display: block;
  /* The footer logotype was 620px wide; it matches the masthead nameplate. */
  width: min(100%, 22rem);
}

.footer-bottom {
  padding-top: 2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
}

.footer-bottom a {
  text-decoration: none;
  transition: color 0.2s ease;
}

@media (max-width: 768px) {
  .footer-bottom {
    flex-direction: column;
    align-items: flex-start;
  }
}

.page-hero p {
  max-width: 720px;
}

.article-meta,
.blog-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  align-items: center;
}

.article-meta {
  margin-bottom: 1rem;
}

.meta-chip,
.blog-topic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  font-family: var(--graza-font-mono);
  line-height: 1.3;
}

.work-grid {
  display: grid;
  gap: 0;
  grid-template-columns: minmax(0, 1fr);
  /* The hero's bottom rule already opens the list, so the grid drops its own. */
  border-top: 0;
  border-left: 0;
}

.work-card > a {
  display: block;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.work-card > a:hover {
  transform: translate(-2px, -2px);
}

.work-card ul {
  padding-left: 1.2rem;
  color: inherit;
}

.work-card a {
  text-decoration: underline;
  font-weight: 600;
}

.work-card a:hover {
  text-decoration-line: underline;
}

.publications ul {
  list-style: none;
  padding-left: 0;
}

.publications li {
  list-style: none;
  margin: 0;
}

.publications li a {
  display: block;
  text-decoration-line: none;
  padding: 1.25rem clamp(0.875rem, 2vw, 1.25rem);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--graza-rule);
  border-radius: 0;
  box-shadow: none;
  font-weight: 400;
  line-height: 1.55;
  transition: background-color var(--graza-duration-fast) var(--graza-ease-out);
}

.publications strong {
  font-weight: 700;
  /* Bold ink, not a color, marks the author's name. */
  color: inherit;
}

.publications li a:hover {
  text-decoration-line: none;
}

.influential-papers > ol {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: influential-paper;
  gap: 0;
  /* The chart's frame closes the intro; a rule here would double it. */
  border-top: 0;
}

.influential-paper {
  display: grid;
  counter-increment: influential-paper;
  grid-template-columns: 3.25rem minmax(0, 1fr);
  column-gap: clamp(1rem, 2.5vw, 2rem);
  padding: clamp(1.5rem, 3vw, 2.25rem) 0;
  background: transparent;
  border: 0;
  border-bottom: 2px solid var(--graza-ink);
  border-radius: 0;
  box-shadow: none;
}

.influential-paper::before {
  grid-row: 1 / span 3;
  content: counter(influential-paper);
  color: var(--coral);
  font-family: var(--graza-font-display);
  font-size: clamp(2.5rem, calc(2rem + 1.5vw), 3.5rem);
  font-style: italic;
  font-weight: 400;
  line-height: 0.85;
}

.influential-paper > * {
  grid-column: 2;
}

.influential-paper__meta {
  margin: 0 0 0.35rem;
  text-transform: uppercase;
  margin-bottom: 0.6rem;
  color: var(--coral);
  font-family: var(--graza-font-mono);
}

.influential-paper h3 {
  margin: 0 0 1rem;
  margin-bottom: 1.25rem;
  line-height: 1.12;
}

.influential-paper h3 a {
  display: block;
  text-underline-offset: 0.2em;
  /* Like the catalog rows, the title has no underline at rest; the
     arrow marks it as a link. */
  color: inherit;
  text-decoration: none;
}

.influential-paper dl {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem 2rem;
  margin: 0;
}

.influential-paper dt {
  margin-bottom: 0.35rem;
  text-transform: uppercase;
  color: var(--graza-ink);
  font-family: var(--graza-font-mono);
}

.influential-paper dd {
  margin: 0;
  line-height: 1.55;
}

/* The SPECTER entry pairs two papers, so each title takes its own line. */
.influential-paper h3 a + a {
  margin-top: 0.5rem;
}

/* Citations per year: HTML columns rather than a scaled SVG, so the labels
   keep their size on phones. Each column's --share sets its height. */
.citation-chart {
  margin: 0 0 2.5rem;
  /* Chart labels are typed in mono like the slugs; the columns print in coral. */
  margin-bottom: clamp(2.5rem, 5vw, 3.5rem);
  /* The chart was the one figure in its own coral style. It now sits on a
     tinted plate with ink bars like the matplotlib figures, and only the
     latest year takes the coral accent. */
  padding: clamp(1rem, 2vw, 1.5rem) clamp(1rem, 2vw, 1.5rem) 0;
  background: var(--graza-coral-tint);
  border: 2px solid var(--graza-ink);
  border-radius: var(--print-radius);
}

.citation-chart__title {
  margin-bottom: 1rem;
  color: var(--graza-ink);
  font-family: var(--graza-font-mono);
  text-transform: uppercase;
}

.citation-chart__plot {
  position: relative;
  height: 10rem;
  margin: 0 0.75rem 2.25rem 3rem;
}

.citation-chart__tick {
  position: absolute;
  right: 0;
  bottom: calc(var(--level) * 100%);
  left: 0;
  border-top: 1px solid rgba(20, 20, 20, 0.12);
  border-top-color: color-mix(in oklch, var(--graza-ink) 22%, transparent);
}

.citation-chart__tick span,
.citation-chart__year,
.citation-chart__value,
.citation-chart__note {
  font-variant-numeric: tabular-nums;
  line-height: 1;
  font-family: var(--graza-font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}

.citation-chart__tick span {
  position: absolute;
  right: calc(100% + 0.5rem);
  transform: translateY(-50%);
}

.citation-chart__columns {
  position: absolute;
  inset: 0;
  display: flex;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.citation-chart__column {
  position: relative;
  display: flex;
  flex: 1 1 0;
  justify-content: center;
  align-items: flex-end;
  min-width: 0;
}

.citation-chart__bar {
  position: relative;
  width: min(24px, 60%);
  height: calc(var(--share) * 100%);
  background: var(--graza-ink);
  border-radius: 0;
}

/* The hovered year lightens so readers see which column the tooltip names. */
.citation-chart__column:hover .citation-chart__bar {
  opacity: 0.72;
}

.citation-chart__value {
  position: absolute;
  bottom: calc(100% + 0.3rem);
  left: 50%;
  white-space: nowrap;
  transform: translateX(-50%);
  color: var(--graza-ink);
  font-weight: 500;
}

.citation-chart__year {
  position: absolute;
  top: calc(100% + 0.45rem);
  left: 50%;
  transform: translateX(-50%);
}

/* Sixteen year labels collide on phones, so keep every fifth. */
@media (max-width: 640px) {
  .citation-chart__column:not(.citation-chart__column--major) .citation-chart__year {
    display: none;
  }
}

/* Keep content for screen readers without showing it. Tables ignore the 1px
   box, so wrap a table in an element with this class. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Two columns of prose get too narrow beside the rank on tablets and phones. */
@media (max-width: 760px) {
  .influential-paper dl {
    grid-template-columns: minmax(0, 1fr);
  }
}

.blog-post h1 {
  margin-bottom: 0.6rem;
  font-family: var(--graza-font-display);
  font-weight: 400;
  line-height: 0.94;
  /* Post titles sit on the 64px section-heading step. The narrow column
     split long words like "Underspecification" at bigger sizes; this one
     hyphenates only when it must. */
  font-size: clamp(2.5rem, calc(1.6rem + 2.8vw), 4rem);
  hyphens: auto;
}

.blog-post .subtitle {
  color: var(--muted);
  margin-bottom: 1.5rem;
}

.blog-post .hero-image {
  margin-bottom: 2rem;
  max-width: 100%;
  height: auto;
  object-fit: contain;
}

.blog-post .content {
  display: grid;
  gap: 1.2rem;
  min-width: 0;
  color: var(--graza-ink);
  overflow-wrap: anywhere;
  font-size: clamp(1.0625rem, calc(0.98rem + 0.4vw), 1.1875rem);
  line-height: 1.65;
}

.blog-post .content img {
  max-width: 100%;
  height: auto;
  object-fit: contain;
  /* Post figures print centered on a paper matte, like the card plates. */
  display: block;
  margin-inline: auto;
  padding: clamp(0.75rem, 2vw, 1.25rem);
}

.blog-post .content pre {
  border: 2px solid var(--border);
  padding: 1.5rem;
  overflow-x: auto;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 0.9rem;
  line-height: 1.5;
  border-color: var(--graza-ink);
  /* Code blocks were the only rounded objects left; inline code joins the mono
     voice. */
  border-width: 1px;
  border-radius: var(--print-radius);
}

.blog-post .content code {
  border-radius: 4px;
  font-family: var(--graza-font-mono);
  font-size: 0.9em;
}

.blog-post .content pre code {
  padding: 0;
  background: transparent;
}

.blog-post .content h2 {
  margin-top: 1.5rem;
  width: fit-content;
  max-width: 100%;
  padding-bottom: 0.3rem;
  border-bottom: 0.3rem solid var(--graza-coral);
  font-size: clamp(1.75rem, calc(1.55rem + 0.8vw), 2.25rem);
  line-height: 1.15;
}

.blog-post .content a {
  text-decoration: underline;
  transition: color 0.2s ease;
}

.blog-post .content a:hover {
  text-decoration-line: underline;
}

.card,
.team-card,
.testimonial,
.blog-card,
.work-card,
.hero-card,
.nav-cta,
.button.primary,
.button.secondary {
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.blog-card:hover {
  transform: translate(-2px, -2px);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* Registered so the rail's fade widths interpolate in the scroll-driven
   animation below; the initial values reproduce the static fallback fade. */
@property --rail-fade-start {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

/* The end fade's initial value is 0: when the rail doesn't overflow, its
   scroll timeline is inactive, the animation never applies, and a rail that
   fits shows no fade at all. The 0% keyframe supplies the 30px fade the
   moment there is something to scroll to. */
@property --rail-fade-end {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}

/* Below the full-width layout the nav wraps onto a second masthead row: a
   scrollable rail that keeps every link reachable without a menu button or JS
   state. The wide CTA sits beside the brand and the compact skin toggle beside
   the rail, so the rail gets the widest possible row. The rail's end padding
   exceeds the fade width so the last link clears the fade once fully
   scrolled. */
@media (max-width: 1100px) {
  html {
    scroll-padding-top: 150px;
  }

  /* main.js hides the link row while the reader scrolls down. The bottom margin
     keeps the header's place in the page, so content never jumps, and the
     clipped links stay available to screen readers. */
  .site-header[data-collapsed] {
    height: var(--nav-collapsed-height);
    margin-bottom: var(--nav-link-row-height);
    overflow: hidden;
  }

  /* The kept bottom padding is taller than the row gap, so the link row's top
     edge would peek out. Hide it there; focusing it still expands the header. */
  .site-header[data-collapsed] .nav > nav {
    opacity: 0;
    pointer-events: none;
  }

  /* The CTA sits beside the brand and the link rail takes the full second
     row. */
  .nav {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas:
      "brand cta cta"
      "links links links";
    align-items: center;
    gap: 0.4rem 1rem;
  }

  .nav-brand {
    grid-area: brand;
  }

  .nav > nav {
    grid-area: links;
    min-width: 0;
  }

  .nav-links {
    overflow-x: auto;
    scrollbar-width: none;
    padding-inline-end: 34px;
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 30px), transparent);
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 30px), transparent);
  }

  .nav-links::-webkit-scrollbar {
    display: none;
  }

  .nav-links li {
    flex-shrink: 0;
  }

  /* Where scroll-driven animations are supported, the fades track the rail's
     scroll position: the start edge fades only once scrolled, and the end fade
     lifts at full scroll so the last link never reads as cut off. When the
     rail doesn't overflow the timeline is inactive and the initial values
     reproduce the static fallback above. */
  @supports (animation-timeline: scroll(self inline)) {
    /* The scroll-driven end fade lifts at full scroll, so the last link needs
       only a tiny end inset here. Four pixels keeps Studio's four links from
       being pushed into artificial overflow at 360px. */
    .nav-links {
      padding-inline-end: 4px;
      -webkit-mask-image: linear-gradient(90deg, transparent 0,
        #000 var(--rail-fade-start),
        #000 calc(100% - var(--rail-fade-end)), transparent);
      mask-image: linear-gradient(90deg, transparent 0,
        #000 var(--rail-fade-start),
        #000 calc(100% - var(--rail-fade-end)), transparent);
      animation: rail-edge-fades linear;
      animation-timeline: scroll(self inline);
    }

    @keyframes rail-edge-fades {
      0% {
        --rail-fade-start: 0px;
        --rail-fade-end: 30px;
      }

      15% {
        --rail-fade-start: 24px;
      }

      85% {
        --rail-fade-end: 30px;
      }

      100% {
        --rail-fade-start: 24px;
        --rail-fade-end: 0px;
      }
    }
  }

  .nav-cta {
    grid-area: cta;
    justify-self: end;
  }
}

/* From 360px upward the tightened rail fits all four links. Remove both the
   fallback mask and the scroll animation so a fade cannot persist after a
   narrow viewport is widened or rotated. */
@media (min-width: 360px) and (max-width: 1100px) {
  .nav-links {
    padding-inline-end: 0;
    -webkit-mask-image: none;
    mask-image: none;
    animation: none;
  }
}

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

@media (min-width: 1000px) {
  .card-grid--testimonials {
    flex-wrap: wrap;
    justify-content: center;
  }

  .card-grid--testimonials .testimonial {
    flex: 0 1 calc((100% - 3.5rem) / 3);
  }
}

/* Message pages (404, thank-you) */
.message-section {
  min-height: 60vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.message-container {
  text-align: center;
  max-width: 640px;
}

.message-heading {
  font-size: clamp(2.5rem, 5vw, 4rem);
  margin-bottom: 1.5rem;
  line-height: 0.95;
}

.message-text {
  color: var(--muted);
  margin-bottom: 2rem;
  font-size: 1.125rem;
  line-height: 1.55;
}

.message-actions {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
}

/* Mobile-only: Arrow indicators for clickable elements */
@media (max-width: 768px) {
  /* The CTA in the header; link buttons draw their own arrow. */
  .nav-cta::after {
    content: " \2192";
    display: inline;
    margin-left: 0.35rem;
    color: inherit;
    font-weight: 700;
  }

  /* Remove arrow from contact form submit button */
  .contact button.button::after {
    content: none;
  }

  /* Text links within content (excluding special cases and work-card links) */
  main a:not(.button):not(.blog-card):not(.work-card):not(.nav-brand):not(.logo-strip a):not(.s-blog-footer-btn a):not(.s-blog-footer-back-link):not(.work-card a):not(.card a):not(.team-card .social-links a):not([href^="mailto:"]):not(.blog-post a):not(.influential-paper a):not(.publications a):not(.work-contents a)::after {
    content: " \2192";
    display: inline;
    margin-left: 0.25rem;
    color: var(--coral);
    font-size: 0.9em;
    font-weight: 700;
  }

  /* Card-style links - only blog cards get arrows */
  .blog-card::after {
    content: "View \2192";
    display: block;
    margin-top: 1rem;
    padding: 0 1.5rem 1.5rem;
    color: var(--coral);
    font-weight: 700;
    font-size: 0.95rem;
  }

  /* Remove underline hover on publications */
  .publications li a:hover {
    text-decoration: none;
  }

  /* Mobile Shadow Removal - Non-Interactive Elements */

  /* Informational Cards */
  .card,
  .team-card,
  .testimonial {
    box-shadow: none !important;
  }

  /* Hero Section Elements */
  .hero-card,
  .hero-grid > div:first-child {
    box-shadow: none !important;
  }

  /* Blog Post Images */
  .blog-post .hero-image,
  .blog-post .content img {
    box-shadow: none !important;
  }

  /* Contact Section */
  .contact {
    box-shadow: none !important;
  }
}

/* ==== Studio: components and page sections ==================================== */

/* Hallmark · genre: editorial · tone: research-led Studio · anchor: forest green · macrostructure: Split Studio · nav: N6 Single-tier Masthead, brand-left loom deck · footer: Ft1 Mast-headed · contrast: pass (40–41) · slop: pass (42–45) */

:is(h1, h2, h3, .work-heading) {
  min-width: 0;
  overflow-wrap: anywhere;
}

:focus-visible {
  outline: 3px solid var(--graza-ink);
  outline-offset: 4px;
}

.site-header :focus-visible,
.home-page .hero :focus-visible,
.site-footer :focus-visible {
  outline-color: var(--graza-cream);
}

h1,
h2,
.page-hero h1 {
  font-family: var(--graza-font-display);
  font-weight: 400;
}

main h3 {
  font-family: var(--graza-font-display);
  font-weight: 400;
}

.container {
  margin: 0 auto;
  width: min(1320px, calc(100vw - 40px));
}

.nav {
  min-height: 76px;
  padding: 0.7rem 0;
}

.nav-brand span {
  display: inline-block;
  font-family: var(--graza-font-display);
  font-weight: 400;
  line-height: 0.9;
  white-space: nowrap;
}

.nav-links a:hover {
  color: var(--graza-lime);
  background: transparent;
  border-bottom-color: currentColor;
}

.nav-links a[aria-current] {
  color: var(--graza-ink);
  background: var(--graza-lime);
  border-bottom-color: transparent;
  /* main.js marks the current page after the first paint; without this the
     tab would fade in on every page load. */
  transition: none;
}

.nav-cta {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  padding: 0.45rem 1.15rem;
  color: var(--graza-ink);
  background: var(--graza-lime);
  border: 1px solid var(--graza-ink);
  font-family: var(--graza-font-mono);
  font-size: var(--graza-type-ui);
  line-height: 1.3;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Pin box-shadow and transform so the base button lift never applies. */
.nav-cta:is(:hover, :focus-visible) {
  color: var(--graza-ink);
  background: var(--graza-cream);
  transform: none;
}

@media (min-width: 48rem) {
  .nav-deck {
    position: relative;
    display: block;
    min-inline-size: 0;
    inline-size: 100%;
    block-size: var(--graza-mark-block-size);
    grid-area: deck;
    align-self: center;
    justify-self: stretch;
    overflow: clip;
    contain: strict;
    pointer-events: none;
    user-select: none;
  }

  .studio-mark__fallback,
  .studio-mark canvas {
    position: absolute;
    inset: 0;
    display: block;
    inline-size: 100%;
    block-size: 100%;
    transition: opacity var(--graza-duration-fast) var(--graza-ease-out);
  }

  .studio-mark__fallback {
    opacity: 1;
  }

  /* 3px matches the projected thickness of the live loom's beams (BEAM 0.075
     world units across the 44px deck), so the fallback→canvas swap holds. */
  .studio-mark__beam {
    fill: none;
    stroke-linecap: square;
    stroke-linejoin: miter;
    stroke-width: 3;
    vector-effect: non-scaling-stroke;
  }

  .studio-mark__beam--cream {
    stroke: var(--graza-cream);
    opacity: 0.82;
  }

  .studio-mark__beam--cream-back {
    stroke: var(--graza-cream);
    opacity: 0.3;
  }

  .studio-mark__beam--lime {
    stroke: var(--graza-lime);
  }

  .studio-mark__beam--lime-back {
    stroke: var(--graza-lime);
    opacity: 0.35;
  }

  .studio-mark__beam--folds {
    stroke: var(--graza-coral);
  }

  .studio-mark.is-live .studio-mark__fallback {
    opacity: 0;
  }

  .studio-mark.is-live canvas {
    opacity: 1;
  }
}

@media (min-width: 48rem) and (max-width: 1100px) {
  .site-header > .nav {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "brand deck cta"
      "links links links";
  }

  .site-header .nav-deck {
    block-size: var(--graza-mark-compact-block-size);
  }
}

@media (min-width: 1101px) {
  /* Single-tier masthead: brand and links read left as one editorial line, the
     loom deck takes every leftover pixel, and the lime pill anchors the end. */
  .site-header .nav {
    display: grid;
    grid-template-columns: auto auto minmax(8rem, 1fr) auto;
    grid-template-areas: "brand links deck cta";
    align-items: center;
    column-gap: clamp(1.25rem, 2.5vw, 2.25rem);
  }

  .nav-brand {
    grid-area: brand;
    justify-self: start;
  }

  .site-header .nav > nav {
    grid-area: links;
  }

  .site-header .nav-links {
    gap: 0.5rem;
    color: var(--graza-cream);
  }

  .nav-cta {
    grid-area: cta;
    justify-self: end;
  }
}

.home-page .site-header {
  position: sticky;
  top: 0;
  color: var(--graza-cream);
  background: var(--graza-ink);
  border-bottom: 1px solid var(--graza-rule-on-dark);
}

.home-page .nav-links a:hover {
  color: var(--graza-lime);
}


.home-page .hero {
  /* ---- Hero: a masthead on paper ----------------------------------------- */
  min-height: 0;
  padding: clamp(1.5rem, 2.5vw, 2.25rem) 0 clamp(3rem, 6vw, 5.5rem);
  color: var(--graza-ink);
  background: var(--graza-cream);
  border-bottom: 0;
}

.home-page .hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(90deg, var(--graza-hero-scrim-strong) 0%, var(--graza-hero-scrim-mid) 58%, var(--graza-hero-scrim-edge) 100%),
    linear-gradient(0deg, var(--graza-hero-scrim-floor) 0%, transparent 48%);
  display: none;
}

.home-page .attractor-background {
  display: block;
}

.home-page .attractor-background.attractor-background--fallback {
  -webkit-mask: url("/assets/images/studio-contours.svg") center / cover no-repeat;
  mask: url("/assets/images/studio-contours.svg") center / cover no-repeat;
  /* The static contours were cream for the dark hero; print them in faint ink. */
  opacity: 0.14;
  background-color: var(--graza-ink);
}

/* align-content: end packs the row at the hero's foot so its height comes
   from the copy column, letting the card stretch to match the copy instead
   of the full viewport. */
.home-page .hero-grid {
  gap: clamp(2rem, 6vw, 6rem);
  position: relative;
  z-index: 2;
  min-height: 0;
  align-items: start;
  align-content: start;
}

.home-page .hero-grid > div:first-child {
  max-width: 900px;
  padding: 0;
  color: inherit;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  backdrop-filter: none;
}

.home-page .hero h1 {
  /* 14ch + balance gives four even lines; 12ch broke the quoted phrase
     across lines and orphaned the final word. */
  margin-bottom: 1.5rem;
  text-wrap: balance;
  max-width: 15ch;
  color: var(--graza-ink);
  /* A step under the base hero size so the buttons clear the first screen
     below the masthead. */
  font-size: clamp(3.25rem, calc(2rem + 4vw), 5.75rem);
  font-weight: 400;
  line-height: 0.98;
}

.home-page .hero p {
  max-width: 58ch;
  margin-bottom: 1rem;
  line-height: 1.55;
  color: var(--muted);
}

.home-page .hero-actions {
  margin-top: 1.5rem;
}

:is(.button, .nav-cta):active {
  box-shadow: none;
}

:is(button, .button)[disabled],
:is(button, .button)[aria-disabled="true"] {
  cursor: not-allowed;
  filter: saturate(0.35);
  opacity: 0.55;
}

.button.secondary {
  color: var(--graza-ink);
  background: transparent;
}

/* The card stretches to the hero column's full height and distributes its
   rows evenly so the panel holds its own against the display headline. */
.home-page .hero-card {
  display: flex;
  flex-direction: column;
  color: var(--graza-ink);
  backdrop-filter: none;
  transform: none;
  /* "What you get" becomes a numbered contents column with a hairline. */
  align-self: start;
  margin: 0;
  padding: 0 0 0 clamp(1.25rem, 2.5vw, 2.25rem);
  background: transparent;
  border: 0;
  border-left: 4px solid var(--graza-ink);
  border-radius: 0;
  box-shadow: none;
  counter-reset: deliverable;
}

/* A lime pill tag, echoing the card's lime offset shadow and the CTA pills,
   so the panel announces itself at a glance. */
.home-page .hero-card__title {
  align-self: flex-start;
  font-family: var(--graza-font-mono);
  line-height: 1.3;
  text-transform: uppercase;
  margin: 0 0 0.5rem;
  padding: 0;
  color: var(--coral);
  background: none;
  border: 0;
  border-radius: 0;
  font-size: var(--graza-type-label);
  font-weight: 500;
  letter-spacing: 0.1em;
}

.home-page .hero-card ul {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 0;
}

.home-page .hero-card li {
  display: flex;
  flex: 1;
  color: var(--graza-ink);
  border-bottom: 1px solid var(--graza-rule);
  align-items: baseline;
  gap: 0.85rem;
  padding: 0.85rem 0;
  font-family: var(--graza-font-body);
  font-size: 1.125rem;
  line-height: 1.5;
  counter-increment: deliverable;
}

.home-page .hero-card li:last-child {
  border-bottom: 0;
}

.home-page .hero-card li::before {
  position: static;
  flex: none;
  min-width: 1.1em;
  color: var(--coral);
  content: counter(deliverable);
  font-family: var(--graza-font-display);
  font-size: 1.5em;
  font-style: italic;
  line-height: 0.8;
}

.home-page .hero-card li strong {
  color: var(--graza-ink);
  font-size: inherit;
}

.home-page [data-home-section="clients"] {
  padding: 1.4rem 0 1.65rem;
  background-color: var(--graza-lime);
  background-image: none;
  /* Ink edges make the strip a printed band. */
  border: 0;
  border-top: 4px solid var(--graza-ink);
  border-bottom: 4px solid var(--graza-ink);
}

.home-page [data-home-section="clients"] .section-heading {
  align-items: flex-start;
  margin-bottom: 1rem;
  text-align: left;
}

.home-page [data-home-section="clients"] .section-heading h2 {
  max-width: none;
  padding: 0;
  line-height: 1.3;
  text-transform: uppercase;
}

.home-page [data-home-section="clients"] .section-heading h2::after {
  display: none;
}

.home-page [data-home-section="clients"] .logo-strip {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 4vw, 4rem);
  row-gap: 1.25rem;
  justify-content: center;
  overflow-x: visible;
  scrollbar-width: none;
}

.home-page [data-home-section="clients"] .logo-strip a {
  flex: 0 0 150px;
  border-radius: 0;
}

.home-page [data-home-section="clients"] .logo-strip img {
  height: 58px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  filter: grayscale(1) contrast(1.4) brightness(0.35) sepia(0.25) hue-rotate(50deg);
  mix-blend-mode: multiply;
  opacity: 1;
}

/* Keep reversed marks visible after the ordinary logo ink treatment. */
.home-page [data-home-section="clients"] .logo-strip img.logo--dark {
  padding: 0.65rem;
  background: var(--graza-ink);
  filter: none;
  mix-blend-mode: normal;
}

@media (min-width: 1100px) {
  .home-page [data-home-section="clients"] .logo-strip {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

.home-page .nav-links {
  color: var(--graza-cream);
}

body .section {
  background-color: var(--graza-cream);
  background-image: none;
}

body .section--tint {
  background-color: var(--graza-tint);
  border: 0;
}

.section-heading--single-line h2 {
  max-width: none;
  white-space: nowrap;
}

.section-heading p {
  max-width: 62ch;
  color: currentColor;
  font-size: clamp(1.05rem, 1.4vw, 1.25rem);
}

.card,
.team-card,
.testimonial,
.blog-card,
.work-card,
.featured-post {
  box-shadow: none;
}

.home-page [data-home-section="services"] {
  padding: var(--graza-space-section-expansive) 0;
  background-image: none;
  border-bottom: 0;
  /* The paper hero gave up the dark green and lime pairing, so this section
     keeps it, right under the lime client strip. */
  color: var(--graza-cream);
  background-color: var(--graza-ink);
}

.home-page [data-home-section="services"] .container {
  grid-template-columns: minmax(14rem, 0.7fr) minmax(0, 1.3fr);
  gap: clamp(3rem, 8vw, 9rem);
  align-items: start;
  /* A full-width numbered list. The side-column heading overflowed into the
     list and left an empty column under it. */
  display: block;
}

.home-page [data-home-section="services"] .section-heading {
  top: 9rem;
  position: static;
  margin: 0;
  padding-bottom: clamp(1.5rem, 3vw, 2.5rem);
  border-bottom: 2px solid var(--graza-rule-on-dark);
}

.home-page [data-home-section="services"] .section-heading h2 {
  max-width: none;
  color: var(--graza-lime);
  /* The base skin sizes this heading on its own; hold it to the section size. */
  font-size: clamp(2.5rem, calc(1.6rem + 2.8vw), 4rem);
}

.home-page [data-home-section="services"] .card-grid {
  display: block;
  gap: 0;
}

.home-page [data-home-section="services"] .card {
  --service-accent: var(--graza-yellow);
  --service-marker-gutter: 1rem;
  display: grid;
  min-height: 0;
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: baseline;
  position: relative;
  padding: clamp(1.5rem, 2.5vw, 2.35rem) 0 clamp(1.5rem, 2.5vw, 2.35rem) var(--service-marker-gutter);
  background: transparent;
  border: 0;
  border-bottom: 2px solid var(--graza-rule-on-dark);
  border-radius: 0;
}

.home-page [data-home-section="services"] .card:nth-child(2) {
  --service-accent: var(--graza-sky);
}

.home-page [data-home-section="services"] .card:nth-child(3) {
  --service-accent: var(--graza-coral);
}

.home-page [data-home-section="services"] .card:nth-child(4) {
  --service-accent: var(--graza-yellow);
}

.home-page [data-home-section="services"] .card:nth-child(5) {
  --service-accent: var(--graza-sky);
}

.home-page [data-home-section="services"] .card:nth-child(6) {
  --service-accent: var(--graza-coral);
}

.home-page [data-home-section="services"] .card h3 {
  position: relative;
  margin: 0;
}

.home-page [data-home-section="services"] .card h3::before {
  content: '';
  position: absolute;
  top: 50%;
  left: calc(0px - var(--service-marker-gutter));
  width: 0.5rem;
  height: 0.5rem;
  background: var(--service-accent);
  border: 1px solid var(--graza-ink);
  border-radius: 50%;
  transform: translateY(-50%);
  display: none;
}

.home-page [data-home-section="services"] .card p {
  margin: 0;
  max-width: 56ch;
  font-size: 1.125rem;
  line-height: 1.55;
}

.home-page [data-home-section="services"] .card a {
  text-decoration-thickness: 1px;
  color: var(--graza-cream);
  text-decoration-color: var(--graza-lime);
}

.home-page [data-home-section="process"] {
  padding: var(--graza-space-section-standard) 0;
  background-image: none;
  border: 0;
  /* After the hero and the lime client strip, each beat runs paper, tan, dark
     green: What we do is the first ink band, then How we work, team, quotes,
     then blog, talks, contact. Cards no longer carry fills, so tan reads as a
     ground again instead of muddying them. Coral accents paper and tan; lime
     accents ink. */
  background-color: var(--graza-cream);
}

.home-page #team[data-home-section="team"] {
  padding: var(--graza-space-section-expansive) 0;
  color: var(--graza-ink);
  background-image: none;
  border-top: 0;
  background-color: var(--graza-tint);
}

.home-page #team[data-home-section="team"]::before {
  display: none;
}

.home-page #team[data-home-section="team"] .section-heading h2 {
  color: var(--graza-ink);
}

.home-page #team[data-home-section="team"] .section-heading h2::after {
  display: none;
}

.home-page [data-home-section="team"] .team-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.home-page [data-home-section="team"] .team-card {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  border-radius: 0;
  overflow: hidden;
}

.home-page [data-home-section="team"] .team-card img {
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  object-position: center top;
  border: 3px solid var(--graza-ink);
  filter: saturate(0.88) contrast(1.03);
}

.home-page [data-home-section="team"] .team-card .team-portrait-paint {
  filter: none;
}

.home-page [data-home-section="team"] .team-card .content {
  display: flex;
  flex-direction: column;
  padding: clamp(1.25rem, 2vw, 1.75rem) 0 0;
  border-top: 0;
}

.home-page [data-home-section="team"] .team-card .content strong {
  display: block;
  margin-bottom: 1rem;
  color: var(--graza-ink);
  font-family: var(--graza-font-display);
  font-weight: 400;
}

.home-page [data-home-section="team"] .team-card .location,
.home-page [data-home-section="team"] .team-card .social-links a {
  color: var(--graza-ink);
}

.home-page [data-home-section="testimonials"] {
  padding: var(--graza-space-section-tight) 0;
  background-image: none;
  border: 0;
  color: var(--graza-cream);
  background-color: var(--graza-ink);
}

.home-page [data-home-section="testimonials"] .card-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  border: 0;
}

.home-page [data-home-section="testimonials"] .testimonial {
  min-width: 0;
  max-width: none;
  padding: clamp(1.75rem, 4vw, 4rem);
  border: 0;
  border-radius: 0;
}

/* Quotes divide on inner 2px rules only, like newspaper columns; an outer
   frame read as an outline. The lead quote spans both columns, then two
   rows of two. Outer edges drop their padding so the text lines up with
   the heading. */
.home-page [data-home-section="testimonials"] .testimonial:nth-child(-n + 3) {
  border-bottom: 2px solid var(--graza-rule-on-dark);
}

.home-page [data-home-section="testimonials"] .testimonial:first-child {
  padding-inline: 0;
}

.home-page [data-home-section="testimonials"] .testimonial:nth-child(even) {
  padding-left: 0;
  border-right: 2px solid var(--graza-rule-on-dark);
}

.home-page [data-home-section="testimonials"] .testimonial:nth-child(odd):not(:first-child) {
  padding-right: 0;
}

.home-page [data-home-section="testimonials"] .testimonial:first-child {
  grid-column: 1 / -1;
}

.home-page [data-home-section="testimonials"] .testimonial::before {
  display: none;
}

.home-page [data-home-section="testimonials"] .testimonial p {
  font-family: var(--graza-font-display);
  color: var(--graza-cream);
}

.home-page [data-home-section="testimonials"] .testimonial .author {
  margin-top: 2rem;
  line-height: 1.45;
  text-transform: uppercase;
  color: var(--graza-lime);
}

.home-page [data-home-section="blog"] {
  padding: var(--graza-space-section-standard) 0;
  background-color: var(--graza-cream);
  background-image: none;
}

.home-page [data-home-section="blog"] .card-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 1.25rem;
}

.home-page [data-home-section="blog"] .blog-card {
  display: flex;
  flex-direction: column;
  grid-column: span 6;
  background: var(--graza-cream);
  border: 2px solid var(--graza-ink);
  overflow: hidden;
}

.home-page [data-home-section="blog"] .blog-card img {
  display: block;
}

.home-page [data-home-section="blog"] .blog-card:is(:hover, :focus-visible) {
  color: inherit;
}

.home-page [data-home-section="blog"] .blog-card:is(:hover, :focus-visible) h3 {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}

/* Pack the text at the top. A card stretched to its row's height would
   otherwise spread the extra space between its title and summary. */
.home-page [data-home-section="blog"] .blog-card .content {
  flex: 1;
  align-content: start;
  min-height: 180px;
  padding: clamp(1.4rem, 3vw, 2.6rem);
}

.home-page [data-home-section="blog"] .blog-card p {
  color: var(--graza-ink);
}

/* The mobile "View →" strip sits below the colored content block, which
   reads as a rendering seam; carry each card's content color through the
   strip and match the content's side padding. */
.home-page [data-home-section="blog"] .blog-card::after {
  margin-top: 0;
  padding: 0 clamp(1.4rem, 3vw, 2.6rem) clamp(1.4rem, 3vw, 2.6rem);
}

.home-page [data-home-section="talks"] {
  padding: var(--graza-space-section-tight) 0;
  background-image: none;
  border-color: var(--graza-line);
  background-color: var(--graza-tint);
}

.home-page [data-home-section="talks"] .card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  border-bottom: 2px solid var(--graza-ink);
}

/* The #talks ID keeps these rules above the ID-scoped base talk rules. */
.home-page #talks[data-home-section="talks"] .blog-card {
  min-height: 0;
  background: transparent;
  border: 0;
  border-top: 2px solid var(--graza-ink);
  border-radius: 0;
}

.home-page #talks[data-home-section="talks"] .blog-card:is(:hover, :focus-visible) {
  color: inherit;
  box-shadow: none;
  transform: none;
}

.home-page #talks[data-home-section="talks"] .blog-card:is(:hover, :focus-visible) h3 {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}

.home-page #talks[data-home-section="talks"] .blog-card .content {
  display: grid;
  grid-template-columns: minmax(160px, 0.8fr) minmax(260px, 1.15fr) minmax(280px, 1.25fr);
  gap: 2rem;
  align-items: start;
  padding: 1.6rem 0;
  color: var(--graza-ink);
  background: transparent;
}

/* The #talks ID keeps these rules above the ID-scoped base talk rules. */
.home-page #talks[data-home-section="talks"] .blog-meta,
.home-page #talks[data-home-section="talks"] .blog-card h3,
.home-page #talks[data-home-section="talks"] .blog-card p {
  margin: 0;
  color: var(--graza-ink);
}

.home-page [data-home-section="talks"] .blog-meta {
  line-height: 1.4;
}

.home-page [data-home-section="talks"] .blog-card h3 {
  font-family: var(--graza-font-display);
  font-weight: 400;
}

/* Talks rows have no side padding, so the mobile "View →" arrow aligns
   with the row text. */
.home-page #talks[data-home-section="talks"] .blog-card::after {
  margin-top: 0;
  padding-left: 0;
  padding-right: 0;
}

.home-page [data-home-section="contact"] {
  /* The footer follows on the same dark green, so the bottom stays short;
     the two paddings together had left about 245px of empty ground. */
  padding: var(--graza-space-section-expansive) 0 clamp(3rem, 5vw, 4rem);
  background-image: none;
  /* Contact runs straight into the footer as one dark close. */
  background-color: var(--graza-ink);
  border-bottom: 0;
}

.home-page [data-home-section="contact"] .contact {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(420px, 1.18fr);
  grid-template-rows: auto auto 1fr;
  column-gap: clamp(3rem, 8vw, 9rem);
  row-gap: 1.5rem;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.home-page [data-home-section="contact"] .contact::before {
  display: none;
}

.home-page [data-home-section="contact"] .contact > h2 {
  font-family: var(--graza-font-display);
  font-weight: 400;
  /* Newsreader runs wider than tracked Georgia; give the question room so it
     breaks between words instead of stranding the question mark. */
  max-width: 11ch;
  font-size: clamp(2.5rem, calc(1.6rem + 2.8vw), 4rem);
  line-height: 0.98;
  overflow-wrap: normal;
  text-wrap: balance;
  color: var(--graza-lime);
}

.home-page [data-home-section="contact"] .contact > p {
  max-width: 48ch;
}

.home-page [data-home-section="contact"] .contact > p:last-child {
  align-self: start;
}

.home-page [data-home-section="contact"] .contact form {
  grid-column: 2;
  grid-row: 1 / span 3;
  margin: 0;
  /* No frame: a faint outline on dark green read like the footer boxes
     that were removed. The fields carry their own 2px edges. */
  padding: 0;
  border: 0;
}

.home-page [data-home-section="contact"] .contact form label {
  display: grid;
  gap: 0.45rem;
  margin: 0;
  line-height: 1.3;
  text-transform: uppercase;
}

.home-page [data-home-section="contact"] .contact input,
.home-page [data-home-section="contact"] .contact textarea {
  max-width: 100%;
  color: var(--graza-ink);
  border: 2px solid var(--graza-ink);
  outline: 2px solid transparent;
  outline-offset: 1px;
  font-size: 1rem;
  line-height: 1.5;
  border-radius: var(--print-radius);
  /* The translucent field surface turns murky on dark green; print it solid. */
  background: var(--graza-cream);
}

.home-page [data-home-section="contact"] .contact :is(input, textarea):focus-visible {
  border-width: 1px;
  outline: 2px solid var(--graza-ink);
  outline-offset: 1px;
}

.home-page [data-home-section="contact"] .contact :is(input, textarea):user-invalid {
  border-width: 1px;
  outline: 2px solid var(--coral-dark);
  outline-offset: 1px;
}

.home-page [data-home-section="contact"] .contact :is(input, textarea):disabled {
  cursor: not-allowed;
  filter: saturate(0.35);
  opacity: 0.55;
}

.home-page [data-home-section="contact"] .contact textarea {
  resize: vertical;
}

.home-page [data-home-section="contact"] .contact :is(input, textarea)::placeholder {
  color: var(--muted);
  opacity: 1;
}

.home-page [data-home-section="contact"] .contact button {
  width: 100%;
  /* The form sits on dark green, so the action is the one solid lime block. */
  color: var(--graza-ink);
  background: var(--graza-lime);
  border-color: var(--graza-lime);
}

.page-hero,
.page-hero--editorial {
  /* Inner pages open like a newspaper section flag: the nav carries the only
     logo, and the page title takes the nameplate's place, centred over the
     attractor dots, with the dateline ruled under it. */
  position: relative;
  overflow: hidden;
  padding: clamp(2.5rem, 5vw, 4rem) 0 clamp(1.5rem, 3vw, 2.25rem);
  text-align: center;
  color: var(--graza-ink);
  background: var(--graza-cream);
  border-bottom: 0;
}

.page-hero h1 {
  margin: 0 auto 1rem;
  max-width: 12ch;
  line-height: 0.9;
  /* Page titles match the home hero; the archive pages ran 103px. */
  font-size: clamp(3.25rem, calc(2rem + 4vw), 5.75rem);
}

.page-hero + .section {
  padding-top: clamp(3.5rem, 4vw, 4.5rem);
}

.work-card {
  display: grid;
  padding: clamp(2rem, 4.5vw, 4.5rem);
  border: 0;
  border-bottom: 2px solid var(--graza-ink);
  border-radius: 0;
  /* The body spans every row, so the left column stacks the eyebrow, the
     logo, the client, and the years at their natural heights while the last
     row takes the rest. */
  /* One plate height for every mark, square or wide, so the column reads
     as one set of plates. */
  --work-mark-height: 6rem;
  --work-gap: clamp(2rem, 5vw, 5.5rem);
  position: relative;
  grid-template-columns: minmax(170px, 0.21fr) minmax(0, 0.79fr);
  grid-template-rows: auto auto auto 1fr;
  gap: 1rem var(--work-gap);
  align-content: start;
}

.work-card h2 {
  display: block;
  margin-bottom: 1.25rem;
  padding: 0;
  border: 0;
  font-family: var(--graza-font-display);
  font-weight: 400;
  /* A card heading at the site's 42px lead size, not a page title. */
  font-size: clamp(1.875rem, calc(1.4rem + 1.2vw), 2.625rem);
  line-height: 1.04;
}

.work-card > a,
.work-card > img {
  align-self: start;
  /* The mark, linked or bare, takes the second row and spans the column so
     its plate lines up with the rules above and below it. */
  grid-column: 1;
  grid-row: 2;
  width: 100%;
  justify-self: stretch;
}

/* One box shape for every logo; object-fit centers each mark inside it. */
.work-card img,
.work-card > a img {
  box-shadow: none;
  opacity: 1;
}

.work-card a,
.team-card .content > p a,
.publications a,
.blog-post .content a {
  color: inherit;
  text-decoration-thickness: 1px;
}

.work-card > div > p + p,
.work-card > div > p + ul {
  margin-top: 1rem;
}

.work-card li + li {
  margin-top: 0.35rem;
}

.publications {
  --publication-accent: var(--graza-pink);
}

.publications h2 {
  display: block;
  max-width: 100%;
  margin: 0 0 1rem;
  color: var(--graza-ink);
  border: 0;
  font-family: var(--graza-font-display);
  font-weight: 400;
  line-height: 1.05;
}

/* Groups carry the space between them, so headings need none above. */
.publication-group + .publication-group {
  margin-top: clamp(2.75rem, 5vw, 4rem);
}

/* Each group sets the accent its row hovers reuse. */
.publication-group:nth-of-type(2) {
  --publication-accent: var(--graza-sky);
}

.publication-group:nth-of-type(3) {
  --publication-accent: var(--graza-yellow);
}

.publications li a:is(:hover, :focus-visible) {
  color: inherit;
  background: var(--publication-accent);
  box-shadow: none;
  outline-offset: -3px;
  transform: none;
}

/* Entries have no underline, so the arrow marks each one as a link at
   every width. */
.publications li a::after {
  color: var(--coral);
}

/* The ranked list reads as a contents column: italic coral ranks, typed
   slugs, and hairlines instead of shadowed cards. Coral tint opens the
   heading rotation that the catalog continues in pink, sky, and yellow. */
.influential-papers {
  margin-bottom: clamp(3.5rem, 6vw, 5rem);
}

.influential-papers > h2 {
  display: block;
  max-width: 100%;
  margin: 0 0 1.75rem;
  color: var(--graza-ink);
  border: 0;
  font-family: var(--graza-font-display);
  font-weight: 400;
  line-height: 1.05;
}

.influential-paper h3 a:is(:hover, :focus-visible) {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--coral);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.16em;
}

.influential-paper h3 a::after {
  color: var(--coral);
}

@media (max-width: 760px) {
  .influential-paper {
    grid-template-columns: 2.25rem minmax(0, 1fr);
    column-gap: 0.85rem;
    padding: 1.5rem 0;
  }

  .influential-paper::before {
    font-size: 2.25rem;
  }
}

.featured-post,
.card-grid--editorial .blog-card {
  color: var(--graza-ink);
  background: var(--graza-cream);
  border: 2px solid var(--graza-ink);
}

.featured-post__media {
  padding: 0;
  overflow: hidden;
}

.featured-post__media img {
  display: block;
}

.card-grid--editorial .blog-card img {
  display: block;
}

.featured-post__content h2 {
  font-family: var(--graza-font-display);
  font-weight: 400;
  line-height: 1.05;
  /* The featured post title is a lead title, like a work card's. */
  font-size: clamp(1.875rem, calc(1.4rem + 1.2vw), 2.625rem);
}

.featured-post__content > .button {
  width: auto;
  justify-self: start;
}

.card-grid--editorial .blog-card h3 {
  line-height: 1.2;
}

.blog-card-meta .blog-meta {
  color: var(--graza-ink);
  font-family: var(--graza-font-mono);
  line-height: 1.3;
}

.blog-post > .article-meta {
  padding: 0.75rem;
  border-top: 1px solid var(--graza-ink);
  border-bottom: 1px solid var(--graza-ink);
  background: transparent;
  border-top-width: 4px;
  border-top-style: double;
  /* Separators sit in the gap before each slug. The row clips its left edge,
     so a slug that wraps to a new line drops its leading dot. */
  column-gap: 1.3em;
  padding-inline: 0;
  overflow: hidden;
}

.blog-post .content pre,
.blog-post .content code {
  color: var(--graza-ink);
  background: var(--graza-tint);
}

.blog-post .content > * {
  min-width: 0;
}

.blog-post .content :is(ul, ol) {
  padding-inline-start: 1.5rem;
}

.blog-post .content li + li {
  margin-top: 0.45rem;
}

.blog-post .content > p:has(> span:only-child:empty) {
  display: none;
}

body .message-section {
  color: var(--graza-ink);
  background-image: none;
  /* The 404 and thank-you panels were full coral-tint blocks; tints are for
     plates, so the message sits on paper. */
  background-color: var(--graza-cream);
}

.blog-post .hero-image,
.blog-post .content img {
  /* A warm paper matte supports chart edges and lazy-loading frames. */
  background: var(--graza-media-paper);
  border: 1px solid var(--graza-ink);
  box-shadow: none;
}

.footer-about {
  grid-column: auto;
}

.footer-section:nth-child(2) {
  grid-column: auto;
}

.footer-section:nth-child(3) {
  grid-column: auto;
}

/* Soft cream spotlight behind the brand mark: the red logotype sinks into
   the dark footer green, so lift the ground behind it and fade outward. */

.footer-logo::before {
  content: '';
  position: absolute;
  inset: -40% -14%;
  pointer-events: none;
  background: radial-gradient(ellipse 52% 52% at 50% 50%, var(--graza-cream-glow-soft), transparent 74%);
}

.footer-logo img {
  position: relative;
  width: 100%;
  height: auto;
  max-height: none;
  opacity: 1;
}

.footer-section h2,
.footer-section a,
.footer-about p,
.footer-bottom,
.footer-bottom a {
  color: var(--graza-cream);
}

.footer-section h2,
.footer-section a,
.footer-bottom {
  font-family: var(--graza-font-mono);
}

.footer-section a {
  text-decoration: none;
  transition: color 0.2s ease;
  font-size: 0.9375rem;
  line-height: 1.5;
  white-space: nowrap;
}

.footer-section a:is(:hover, :focus-visible) {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* WCAG 2.5.8 pointer-target floor for the footer and team link rows at every
   width; the compact blocks below widen them to 44px where touch dominates. */
.footer-section a,
.footer-bottom a,
.home-page [data-home-section="team"] .social-links a {
  display: inline-flex;
  min-width: 24px;
  min-height: 24px;
  align-items: center;
}

.footer-bottom {
  border-top: 1px solid var(--graza-rule-on-dark);
  font-size: var(--graza-type-ui);
  line-height: 1.5;
}

/* The mobile link arrows are coral by default, which vanishes on the dark
   footer. */
@media (min-width: 901px) {
  .home-page .hero-grid {
    grid-template-columns: minmax(0, 1fr) clamp(320px, 33vw, 500px);
    gap: clamp(2rem, 4vw, 4rem);
  }

}

@media (min-width: 901px) and (max-height: 800px) {
  :root body.home-page .hero h1 {
    max-width: 15ch;
    margin-bottom: 1rem;
    font-size: clamp(3.75rem, calc(2rem + 4vw), 5.5rem);
  }

  :root body.home-page .hero p {
    margin-bottom: 0.75rem;
    font-size: 1rem;
    line-height: 1.42;
  }

  :root body.home-page .hero-actions {
    margin-top: 1rem;
  }

  :root body.home-page .hero-card {
    padding: 1.1rem 1.25rem;
  }

  :root body.home-page .hero-card li {
    padding: 0.7rem 0;
  }
}

/* The compact masthead keeps the nav as a scrollable section rail on the dark
   ground, so the base cream link styles and lime-pill CTA carry it; only the
   rail's top rule is set here. */
@media (max-width: 1100px) {
  .site-header .nav > nav {
    border-top: 1px solid var(--graza-rule-on-dark);
  }

  /* Tablets are touch-first, so the footer link columns take the full 44px
     treatment here rather than only on phones. */
  .footer-section a {
    min-width: 44px;
    min-height: 44px;
  }

  .footer-bottom a {
    min-height: 44px;
  }

  .footer-section ul {
    gap: 0;
  }
}

/* Phone tier of the rail: step the mono links down to the label size so all
   four fit without scrolling on 360px-and-up screens. */
@media (max-width: 520px) {
  .nav-links {
    gap: 0.1rem;
  }

  .nav-links a {
    padding: 0.4rem 0.35rem;
    font-size: var(--graza-type-label);
  }
}

@media (max-width: 900px) {
  .home-page .hero-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .home-page .hero-card {
    max-width: 680px;
  }

  .home-page [data-home-section="services"] .container {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }

  .home-page .hero-copy > h1 {
    order: 1;
  }

  .home-page .hero-copy > .hero-sub {
    order: 2;
  }

  /* The paragraph moves below the buttons here, so space it from them. */
  .home-page .hero-copy > .hero-actions {
    order: 3;
    margin-bottom: 1.5rem;
  }

  .home-page .hero-copy > p:not(.hero-sub) {
    order: 4;
  }

  

  

  .home-page #talks[data-home-section="talks"] .blog-card .content {
    grid-template-columns: 1fr;
    gap: 0.75rem;
  }

  .home-page [data-home-section="contact"] .contact {
    grid-template-columns: 1fr;
    gap: 2rem;
  }

  .home-page [data-home-section="contact"] .contact form {
    width: 100%;
    max-width: 680px;
    grid-column: 1;
    grid-row: auto;
  }

  .home-page [data-home-section="team"] .social-links a {
    min-width: 44px;
    min-height: 44px;
  }

  /* The 44px link targets no longer fit beside the location in one row, and
     space-between centering strands the location between wrapped
     link lines. Stack the row instead. */
  .home-page [data-home-section="team"] .team-footer {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }

  .work-card h2 {
    overflow-wrap: break-word;
  }

  .footer-content {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .footer-about {
    grid-column: 1 / -1;
  }

  .footer-section:nth-child(2),
  .footer-section:nth-child(3) {
    grid-column: auto;
  }
}

@media (max-width: 699px) {
  .home-page [data-home-section="team"] .team-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .home-page [data-home-section="testimonials"] .card-grid {
    grid-template-columns: 1fr;
  }

  .home-page [data-home-section="testimonials"] .testimonial:first-child {
    grid-column: 1;
  }

  /* One column: rules run between the quotes only. */
  .home-page [data-home-section="testimonials"] .testimonial:nth-child(n) {
    padding-inline: 0;
    border-right: 0;
    border-bottom: 2px solid var(--graza-rule-on-dark);
  }

  .home-page [data-home-section="testimonials"] .testimonial:last-child {
    border-bottom: 0;
  }

  .home-page [data-home-section="blog"] .blog-card,
  .home-page [data-home-section="blog"] .blog-card:first-child,
  .home-page [data-home-section="blog"] .blog-card:nth-child(2) {
    grid-column: 1 / -1;
  }
}

@media (max-width: 600px) {
  .home-page .hero-actions {
    display: grid;
  }

  .home-page [data-home-section="services"] .card-grid,
  .home-page [data-home-section="blog"] .card-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .home-page [data-home-section="services"] .card {
    --service-marker-gutter: 1.5rem;
    min-height: 0;
    padding: 2rem 1.5rem;
  }

  
  .home-page [data-home-section="contact"] .contact form {
    padding: 1.5rem;
  }

  .home-page [data-home-section="team"] .team-card {
    grid-template-rows: auto minmax(0, 1fr);
  }

  .home-page [data-home-section="team"] .team-card img {
    height: auto;
    aspect-ratio: 1;
  }

  .home-page [data-home-section="testimonials"] .testimonial {
    padding-block: 2rem;
  }

  /* Skip the author line: this selector outranks its small UI type. */
  body.home-page [data-home-section="testimonials"] .testimonial p:not(.author) {
    font-size: clamp(1.3125rem, calc(1.2rem + 0.75vw), 1.5rem);
    line-height: 1.16;
  }

  :root body.home-page [data-home-section="testimonials"] .testimonial:first-child p:first-child {
    font-size: clamp(1.75rem, calc(1.55rem + 1vw), 2rem);
  }

  .blog-post h1 {
    overflow-wrap: break-word;
  }

  .footer-content {
    grid-template-columns: minmax(0, 1fr);
  }

  .footer-section:nth-child(2),
  .footer-section:nth-child(3) {
    grid-column: 1;
  }
}

@media (max-width: 380px) {
  .nav {
    gap: 0.5rem;
  }

  .nav-brand {
    gap: 0.4rem;
    font-size: 1.05rem;
  }

  /* Keep the wordmark on the narrowest phones — wrap it to two lines beside
     the smaller logo rather than dropping the name. */
  .nav-brand span {
    white-space: normal;
    line-height: 1;
  }

  .nav-brand img {
    height: 40px;
  }

  :root body.home-page .hero h1 {
    font-size: 2.75rem;
  }

  :root body.home-page .hero-copy > .hero-actions {
    margin-top: 0.75rem;
  }

  :root body.home-page [data-home-section="clients"] .logo-strip {
    column-gap: 1rem;
  }

  :root body.home-page [data-home-section="clients"] .logo-strip a {
    flex-basis: 120px;
  }
}

@media (max-width: 900px) and (max-height: 500px) {
  .home-page .hero-grid {
    gap: 1.5rem;
  }

  :root body.home-page .hero h1 {
    max-width: none;
    margin-bottom: 0.75rem;
    font-size: clamp(2.4rem, calc(1.75rem + 4vw), 3.25rem);
  }

  :root body.home-page .hero p {
    margin-bottom: 0.65rem;
    font-size: 0.9375rem;
    line-height: 1.4;
  }

  :root body.home-page .hero-copy > .hero-actions {
    order: 2;
    margin: 0.75rem 0;
  }

  :root body.home-page .hero-copy > .hero-sub {
    order: 3;
  }
}

/* Reduced motion gets the static contour artwork purely in CSS, so it holds
   even before (or without) hero-attractor.js adding the fallback class. */
@media (prefers-reduced-motion: reduce) {
  .home-page .attractor-background {
    opacity: 0.14;
    background-color: var(--graza-ink);
    -webkit-mask: url("/assets/images/studio-contours.svg") center / cover no-repeat;
    mask: url("/assets/images/studio-contours.svg") center / cover no-repeat;
  }
}

/* ==== Print edition: mastheads, type scale, and section grounds =============== */

/* The print edition gives the site a journal and print-shop character:
   book typography, flat inks, square plates, captioned figures, and the
   2014 logotype as a masthead. */

@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/newsreader-latin-opsz-wght.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: 'Newsreader';
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/newsreader-latin-opsz-wght-italic.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('/assets/fonts/ibm-plex-mono-latin-400.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('/assets/fonts/ibm-plex-mono-latin-500.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;
}

/* ---- Tokens ------------------------------------------------------------ */

/* ---- Type -------------------------------------------------------------- */

h1,
h2,
.page-hero h1,
.home-page .hero h1,
.work-card h2,
.publications h2,
.blog-post h1,
.featured-post__content h2,
.home-page [data-home-section="contact"] .contact > h2 {
  letter-spacing: -0.022em;
}

main h3,
.nav-brand,
.nav-brand span,
.home-page [data-home-section="talks"] .blog-card h3,
.home-page [data-home-section="testimonials"] .testimonial p {
  letter-spacing: -0.012em;
}

/* ---- Buttons ----------------------------------------------------------- */

.button,
.home-page .button {
  min-height: 46px;
  border: 2px solid var(--graza-ink);
  font-family: var(--graza-font-mono);
  font-size: var(--graza-type-ui);
  line-height: 1.3;
  text-transform: uppercase;
  white-space: nowrap;
  border-radius: var(--print-radius);
  box-shadow: none;
  font-weight: 500;
  letter-spacing: 0.06em;
}

.button:is(:hover, :focus-visible),
.home-page .button:is(:hover, :focus-visible) {
  box-shadow: none;
  transform: none;
}

.button.secondary:is(:hover, :focus-visible) {
  background: var(--graza-ink);
  color: var(--graza-cream);
}

.button.primary:is(:hover, :focus-visible) {
  background: var(--graza-ink);
  color: var(--graza-cream);
}

.nav-cta,
.nav-cta:is(:hover, :focus-visible) {
  border-radius: var(--print-radius);
  box-shadow: none;
  font-weight: 500;
  letter-spacing: 0.06em;
}

@media (min-width: 48rem) and (max-width: 1100px) {
  .home-page .hero {
    min-height: 0;
  }
}

.home-page .hero :focus-visible {
  outline-color: var(--graza-ink);
}

/* The dots print at full strength around the masthead and fade behind the
   copy, so no trail crosses the headline or the list at full ink. The
   fallback keeps its own contour mask. */
@media (prefers-reduced-motion: no-preference) {
  .home-page .attractor-background:not(.attractor-background--fallback) {
    -webkit-mask-image: linear-gradient(#000 0 14rem, rgb(0 0 0 / 0.3) 22rem);
    mask-image: linear-gradient(#000 0 14rem, rgb(0 0 0 / 0.3) 22rem);
  }
}

.home-page .hero-masthead {
  display: block;
  position: relative;
  z-index: 2;
  margin-bottom: clamp(1.5rem, 2.5vw, 2.25rem);
  text-align: center;
}

.home-page .hero-masthead img {
  display: block;
  width: min(100%, 19rem);
  height: auto;
  margin: 0 auto clamp(0.75rem, 1.5vw, 1.1rem);
}

/* A newspaper nameplate: double rule over the dateline, single rule under. */
:root body.home-page .hero p.hero-dateline {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.35rem 1.5rem;
  max-width: none;
  margin: 0;
  padding: 0.6rem 0.25rem;
  color: var(--graza-ink);
  background: var(--graza-cream);
  border-top: 5px double var(--graza-ink);
  border-bottom: 2px solid var(--graza-ink);
  font-family: var(--graza-font-mono);
  font-size: var(--graza-type-label);
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
}

.home-page .hero h1 em {
  color: var(--coral);
  font-style: italic;
}

/* The note under the lede was a 15px footnote beside an 18px list. */
.home-page .hero .hero-copy > p:not(.hero-sub) {
  font-size: 1.0625rem;
}

.home-page .hero .hero-sub {
  color: var(--graza-ink);
  font-size: clamp(1.25rem, calc(1.1rem + 0.45vw), 1.5rem);
  font-weight: 400;
  line-height: 1.4;
}

/* ---- What we do: the one dark green panel with neon accents ------------- */

.home-page [data-home-section="services"] :focus-visible {
  outline-color: var(--graza-lime);
}

.home-page [data-home-section="services"] .card-grid,
.home-page [data-home-section="services"] .card {
  border-color: var(--graza-rule-on-dark);
}

.home-page [data-home-section="services"] .card h3,
.home-page [data-home-section="services"] .card p {
  color: var(--graza-cream);
}

.home-page [data-home-section="services"] .card-grid {
  border-top: 0;
  counter-reset: service;
}

.home-page [data-home-section="services"] .card {
  grid-template-columns: 3rem minmax(0, 0.85fr) minmax(0, 1.15fr);
  column-gap: clamp(1.5rem, 3vw, 3rem);
  padding-left: 0;
  counter-increment: service;
}

/* Lime italic numerals echo the hero's numbered list and replace the dots. */
.home-page [data-home-section="services"] .card::before {
  content: counter(service, decimal-leading-zero);
  color: var(--graza-lime);
  font-family: var(--graza-font-display);
  font-size: 1.75rem;
  font-style: italic;
  line-height: 1;
}

/* Phones keep the numeral beside the title and drop the text under it. */
@media (max-width: 760px) {
  .home-page [data-home-section="services"] .card {
    grid-template-columns: 2.5rem minmax(0, 1fr);
    row-gap: 0.75rem;
  }

  .home-page [data-home-section="services"] .card p {
    grid-column: 2;
  }
}

.home-page [data-home-section="services"] .card a:hover {
  color: var(--graza-lime);
}

.home-page [data-home-section="contact"] .contact form {
  border-radius: 0;
}

@media (max-width: 760px) {
  
  .home-page [data-home-section="contact"] .contact form {
    border-radius: 0;
  }
}

/* ---- Talks and contact ------------------------------------------------- */

/* Every label on the page: 13px mono, medium, tracked 0.1em. Only color
   changes from section to section. */
.home-page #talks[data-home-section="talks"] .blog-meta,
.home-page [data-home-section="clients"] .section-heading h2,
.home-page [data-home-section="testimonials"] .testimonial .author,
.home-page [data-home-section="contact"] .contact form label {
  font-family: var(--graza-font-mono);
  font-size: var(--graza-type-label);
  font-weight: 500;
  letter-spacing: 0.1em;
}

/* Newsreader runs wider than the base face, so the 12ch cap broke this one. */
.home-page [data-home-section="talks"] .section-heading h2 {
  max-width: none;
}

.home-page [data-home-section="contact"] .contact button:is(:hover, :focus-visible) {
  color: var(--graza-ink);
  background: var(--graza-cream);
  border-color: var(--graza-cream);
}

/* ---- Testimonials: hanging quotation marks ----------------------------- */

.home-page [data-home-section="testimonials"] .testimonial p:first-child {
  position: relative;
}

/* An absolutely placed mark keeps its inline spot, so shifting it by its own
   width hangs it in the margin and keeps the text edge straight. */
.home-page [data-home-section="testimonials"] .testimonial p:first-child::before {
  position: absolute;
  content: '\201C';
  color: var(--graza-lime);
  transform: translateX(-100%);
}

/* The closing mark follows the quote's last word in the same lime. */
.home-page [data-home-section="testimonials"] .testimonial p:not(.author)::after {
  content: '\201D';
  color: var(--graza-lime);
}

/* ---- Homepage type scale ----------------------------------------------- */

/* One size per level: 90 hero, 64 sections, 42 lead titles, 30 item titles,
   18 body, 13 labels. Section headings at 82-90px had crowded the hero. */
.home-page .section-heading h2 {
  font-size: clamp(2.5rem, calc(1.6rem + 2.8vw), 4rem);
}

/* ---- The same scale on every other page -------------------------------- */

/* Section headings on the blog and publications pages join the 64px row. */
.section-heading h2,
.publications h2,
.influential-papers > h2 {
  font-size: clamp(2.5rem, calc(1.6rem + 2.8vw), 4rem);
}

/* Blog cards and paper titles are item titles, like the home blog row. */
.card-grid--editorial .blog-card h3,
.influential-paper h3 {
  font-size: clamp(1.5rem, calc(1.25rem + 0.6vw), 1.875rem);
}

/* Body copy is 18px everywhere; this rule had pinned 17px. */
.page-hero p {
  font-size: 1.125rem;
}

/* Labels: 13px mono, medium, tracked 0.1em, on every page. The blog's tags
   mixed bold and medium on one line, and the publications ran 11.5px. */
.meta-chip,
.blog-topic,
.blog-meta,
.blog-card-meta .blog-meta,
.influential-paper__meta,
.influential-paper dt,
.citation-chart__title {
  font-size: var(--graza-type-label);
  font-weight: 500;
  letter-spacing: 0.1em;
}

.home-page [data-home-section="team"] .team-card .content strong,
.home-page [data-home-section="testimonials"] .testimonial:first-child p:first-child {
  font-size: clamp(1.875rem, calc(1.4rem + 1.2vw), 2.625rem);
  letter-spacing: -0.022em;
  line-height: 1.08;
}

.home-page [data-home-section="services"] .card h3,
.home-page [data-home-section="blog"] .blog-card h3,
.home-page [data-home-section="talks"] .blog-card h3,
.home-page [data-home-section="testimonials"] .testimonial p {
  font-size: clamp(1.5rem, calc(1.25rem + 0.6vw), 1.875rem);
  letter-spacing: -0.012em;
  line-height: 1.15;
}

/* Newsreader sets small for its size, so 17px body copy read faint. */
.home-page [data-home-section="clients"] p,
.home-page [data-home-section="team"] .team-card p,
.home-page [data-home-section="blog"] .blog-card p,
.home-page #talks[data-home-section="talks"] .blog-card p,
.home-page [data-home-section="contact"] .contact > p {
  font-size: 1.125rem;
  line-height: 1.55;
}

/* ---- Section grounds: paper, tan, ink, after the lime strip ----------- */

/* The portraits stand on the tan ground without a card frame. */
.home-page [data-home-section="team"] .team-card,
.home-page [data-home-section="team"] .team-card:nth-child(2) {
  background: transparent;
  border: 0;
}

.home-page [data-home-section="team"] .team-grid {
  gap: clamp(2rem, 4vw, 3.5rem);
  border: 0;
}

.home-page [data-home-section="team"] .team-card img {
  width: 100%;
  margin: 0;
}

.home-page [data-home-section="team"] .team-card .team-footer {
  margin-top: auto;
  padding-top: 0.75rem;
  border-top: 2px solid var(--graza-ink);
}

/* The longer bio ran into the footer rule, so it keeps a gap above it. */
.home-page [data-home-section="team"] .team-card p:has(+ .team-footer) {
  margin-bottom: 1.25rem;
}

/* Talk labels take the coral accent on tan, like every slug on paper. */
.home-page #talks[data-home-section="talks"] .blog-card .blog-meta {
  color: var(--coral);
}

/* Every dark section heading is lime, like What we do and contact. */
.home-page [data-home-section="testimonials"] .section-heading h2 {
  color: var(--graza-lime);
}

.home-page [data-home-section="testimonials"] .testimonial:nth-child(n) {
  background: transparent;
}

.home-page [data-home-section="contact"] .contact,
.home-page [data-home-section="contact"] .contact > p,
.home-page [data-home-section="contact"] .contact a,
.home-page [data-home-section="contact"] .contact form label {
  color: var(--graza-cream);
}

.home-page [data-home-section="contact"] .contact form {
  align-self: start;
  background: transparent;
  border-color: var(--graza-rule-on-dark);
}

/* An ink outline vanishes on the dark ground, and dark coral reads 1.9:1. */
.home-page [data-home-section="contact"] .contact :is(input, textarea):focus-visible,
.home-page [data-home-section="contact"] .contact a:focus-visible {
  outline-color: var(--graza-lime);
}

.home-page [data-home-section="contact"] .contact :is(input, textarea):user-invalid {
  outline-color: var(--graza-coral);
}

/* ---- Square plates ----------------------------------------------------- */

.home-page [data-home-section="blog"] .blog-card,
.featured-post,
.card-grid--editorial .blog-card,
.home-page [data-home-section="team"] .team-card img,
.blog-post .hero-image,
.blog-post .content img,
.work-card img,
.work-card > a img {
  border-radius: var(--print-radius);
}

@media (max-width: 760px) {
  .home-page [data-home-section="team"] .team-card img {
    border-radius: var(--print-radius);
  }
}

/* ---- Figures: real plots printed in one ink on the card's color -------- */

.card-figure {
  display: flex;
  flex-direction: column;
  margin: 0;
  background: var(--figure-paper, var(--graza-coral-tint));
  border-bottom: 2px solid var(--graza-ink);
}

/* Grayscale plus multiply turns each matplotlib palette into one ink, so
   four different charting styles read as one printed set. */
.home-page [data-home-section="blog"] .blog-card .card-figure img,
.card-grid--editorial .blog-card .card-figure img {
  width: 100%;
  height: clamp(13rem, 22vw, 20rem);
  aspect-ratio: auto;
  padding: 1.25rem 1.25rem 0.5rem;
  object-fit: scale-down;
  background: transparent;
  border: 0;
  filter: grayscale(1) contrast(1.2);
  mix-blend-mode: multiply;
}

/* The A/B histogram's pastel bars sit near white, so contrast alone bleaches
   them. Dimming first, then a steep contrast, keeps white paper white and
   prints the bars mid-grey. The card selectors repeat to outrank the shared
   figure filter. */
.home-page [data-home-section="blog"] .blog-card .card-figure--faint img,
.card-grid--editorial .blog-card .card-figure--faint img {
  filter: grayscale(1) brightness(0.62) contrast(4);
}

/* The featured post prints its figure like the cards, at full width. */
.featured-post__media.card-figure {
  aspect-ratio: auto;
  background: var(--graza-coral-tint);
  border-bottom: 2px solid var(--graza-ink);
}

.featured-post__media.card-figure img {
  width: 100%;
  height: auto;
  min-height: 0;
  max-height: 32rem;
  padding: clamp(1.25rem, 3vw, 2.5rem) clamp(1.25rem, 3vw, 2.5rem) 0.75rem;
  object-fit: contain;
  background: transparent;
  filter: grayscale(1) contrast(1.2);
  mix-blend-mode: multiply;
}

.card-figure figcaption {
  padding: 0 1.25rem 0.9rem;
  color: var(--graza-ink);
  font-family: var(--graza-font-mono);
  font-size: var(--graza-type-label);
  line-height: 1.45;
}

/* Each post keeps one plate tint wherever it appears: on home, on the blog
   index, and behind its own figures. Without a tone the plate is coral
   tint. Position in a grid used to decide it, so a post changed colour
   from page to page. */
[data-tone="yellow"] {
  --figure-paper: var(--graza-yellow);
}

[data-tone="sky"] {
  --figure-paper: var(--graza-sky);
}

[data-tone="pink"] {
  --figure-paper: var(--graza-pink);
}

/* Ink, not coral: deep coral measured 3.85:1 on the coral-tint plate. */
.card-figure figcaption span {
  margin-right: 0.4em;
  color: var(--graza-ink);
  font-weight: 500;
}

/* Four posts in two equal rows; the tint lives on the figure plate only.
   Phones keep the one-column grid, where a span would add empty tracks. */
@media (min-width: 601px) {
  .home-page [data-home-section="blog"] .blog-card:first-child,
  .home-page [data-home-section="blog"] .blog-card:nth-child(2) {
    grid-column: span 6;
  }
}

/* A one-line caption beside a two-line one pushed titles out of line. */
.home-page [data-home-section="blog"] .card-figure figcaption {
  min-height: calc(2 * 1.45em);
}

.home-page [data-home-section="blog"] .blog-card:nth-child(n) .content,
.home-page [data-home-section="blog"] .blog-card:nth-child(n)::after {
  background: var(--graza-cream);
}

.card-grid--editorial .blog-card:nth-child(n) {
  background: var(--graza-cream);
}

/* The three remaining post covers were decorative gradients. */
.blog-post .hero-image--decorative {
  display: none;
}

/* Newsreader sets small for its size; 19px in a 42rem column keeps lines
   near 75 characters instead of 100. */
.blog-post {
  /* Posts sit outside .container, so match its side gutters here. */
  margin: 0 auto;
  padding: 0;
  width: min(42rem, calc(100vw - 40px));
}

@media (max-width: 760px) {
  .blog-post {
    width: min(42rem, calc(100vw - 28px));
  }
}

/* ---- Labels: typed slugs instead of pills ------------------------------ */

.meta-chip,
.blog-topic,
.meta-chip--accent,
.blog-post > .article-meta .meta-chip--accent {
  padding: 0;
  color: var(--graza-ink);
  background: none;
  border: 0;
  border-radius: 0;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.meta-chip--accent,
.blog-post > .article-meta .meta-chip--accent,
.blog-topic {
  color: var(--coral);
  font-weight: 500;
}

/* ---- Work: a masthead column of eyebrow, logo, client, and years ------ */

.work-card > div {
  grid-column: 2;
  grid-row: 1 / -1;
}

/* A newspaper nameplate: the card's index on the left, its sector on the
   right, typed small. Each entry draws only its 2px divider and the plate's
   3px frame; hairlines here and under the column made five lines an entry.
   Coral deep clears 4.5:1 on every fill. */
.work-card > .work-eyebrow {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  grid-column: 1;
  grid-row: 1;
  margin: 0;
  color: var(--coral);
  font-family: var(--graza-font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  line-height: 1.3;
  text-transform: uppercase;
}

/* The client is the largest line in the column, set like a nameplate. */
.work-card > .work-meta {
  grid-column: 1;
  grid-row: 3;
  margin: 0;
  color: var(--graza-ink);
  font-family: var(--graza-font-display);
  font-size: clamp(1.25rem, calc(1.05rem + 0.45vw), 1.5rem);
  font-weight: 400;
  letter-spacing: -0.01em;
  line-height: 1.1;
}

/* The years close the masthead, typed in mono. A range pushes its end to
   the right edge; a single year sits on the left. */
.work-card .work-dates {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.75rem;
  color: var(--coral);
  font-family: var(--graza-font-mono);
  font-size: 0.8125rem;
  font-style: normal;
  letter-spacing: 0.04em;
  line-height: 1.3;
}

/* The dash stays in the text for readers and copy, but the rule layout
   needs it to vanish and hold the middle. */
.work-card .work-to {
  flex: 1 1 auto;
  overflow: hidden;
  color: transparent;
}

/* Both ends of a range share the line's coral. */
.work-card .work-end {
  color: inherit;
}

/* An acquisition note wrapped mid-phrase in the narrow column, so it gets
   its own smaller line under the client name. */
.work-card .work-note {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.72em;
  line-height: 1.3;
}

/* The years sit on their own line here, so the inline separator would dangle. */
.work-card .work-sep {
  display: none;
}

/* Every mark sits centered on a cream plate that fills the column at one
   height. A plate that hugged each mark left wide and narrow marks ragged
   against the masthead rules. */
.work-card img,
.work-card > a img {
  display: block;
  width: 100%;
  max-width: 100%;
  height: var(--work-mark-height);
  aspect-ratio: auto;
  padding: 0.6rem 0.8rem;
  object-fit: contain;
  object-position: center;
  border: 0;
  border-radius: var(--print-radius);
}


/* White wordmarks need an ink plate instead of the cream one. */
.work-card.work-card--dark-logo img {
  background: var(--graza-ink);
}

/* The cards print on paper as ruled rows. The three tints moved from the
   card ground to the logo plates, in the same rotation. */

.work-grid .work-card:nth-child(n) {
  padding-inline: 0;
  background: transparent;
  border-right: 0;
}

/* The section padding already sets the gap under the folio, as on Blog and
   Publications, so the first entry adds none of its own. */
.work-grid .work-card:first-child {
  padding-top: 0;
}

/* Plates are objects, so they take the 3px frame. */
.work-card:not(.work-card--dark-logo) img {
  border: 3px solid var(--graza-ink);
}

/* ---- Work contents: every entry on one screen, linked to its entry ---- */

/* The grid is itself the page container, so the contents get their own.
   Rows read down each column, like a printed contents page; the row count
   comes from the markup so the columns stay balanced. */
.work-contents {
  margin-bottom: clamp(3rem, 5vw, 4.5rem);
}

.work-contents ol {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(var(--work-contents-rows), auto);
  grid-auto-flow: column;
  column-gap: clamp(2rem, 4vw, 4rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.work-contents a {
  display: grid;
  grid-template-columns: 2.5rem minmax(0, 1fr) auto 8.5rem;
  gap: 1rem;
  align-items: baseline;
  padding: 0.6rem 0;
  color: inherit;
  text-decoration: none;
  border-top: 1px solid var(--graza-ink);
}

/* The last row of each column closes on the same 1px rule. */
.work-contents li:is(.work-contents__col-end, :last-child) a {
  border-bottom: 1px solid var(--graza-ink);
}

.work-contents__no,
.work-contents__sector,
.work-contents__years {
  color: var(--coral);
  font-family: var(--graza-font-mono);
  font-size: var(--graza-type-label);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.work-contents__years {
  text-align: right;
}

.work-contents__client {
  font-size: 1.125rem;
  line-height: 1.3;
}

.work-contents a:is(:hover, :focus-visible) .work-contents__client {
  text-decoration: underline;
  text-decoration-color: var(--coral);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.2em;
}

/* One column on phones; the sector drops so the client keeps its width. */
@media (max-width: 760px) {
  .work-contents ol {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-auto-flow: row;
  }

  .work-contents a {
    grid-template-columns: 2.2rem minmax(0, 1fr) auto;
  }

  .work-contents__sector {
    display: none;
  }

  .work-contents li.work-contents__col-end:not(:last-child) a {
    border-bottom: 0;
  }
}

/* Ai2's pink mark vanished on the coral plate its position would give it. */
.work-grid #ai2 img {
  background: var(--graza-sky);
}

.work-grid .work-card:nth-child(3n + 1):not(.work-card--dark-logo) img {
  background: var(--graza-coral-tint);
}

.work-grid .work-card:nth-child(3n + 2):not(.work-card--dark-logo) img {
  background: var(--graza-yellow);
}

.work-grid .work-card:nth-child(3n):not(.work-card--dark-logo) img {
  background: var(--graza-sky);
}

/* Dense link lists turn blotchy in semibold; book-weight links with a thin,
   low underline keep the paragraph even. */
.work-card > div a,
.blog-post .content a,
.team-card .content > p a {
  font-weight: 400;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

@media (max-width: 900px) {
  .work-card {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
  }

  .work-card > a,
  .work-card > img,
  .work-card > div,
  .work-card > .work-eyebrow,
  .work-card > .work-meta {
    grid-column: 1;
    grid-row: auto;
  }

  /* Source order puts the logo first; the eyebrow belongs above it. */
  .work-card > .work-eyebrow {
    order: -1;
  }
}

/* ---- Slug separators and phone nameplate ------------------------------- */

/* Without pill outlines the slugs need a typed separator between them. */
.meta-chip + .meta-chip::before,
.blog-topic + .blog-meta::before {
  content: '\00B7';
  margin-right: 0.6em;
  color: var(--muted);
}

@media (max-width: 640px) {
  :root body.home-page .hero p.hero-dateline {
    flex-direction: column;
    align-items: center;
    font-size: 0.8125rem;
    letter-spacing: 0.05em;
    text-align: center;
  }

  /* A full-width logo pushed the headline halfway down a phone screen. */
  .home-page .hero-masthead img {
    width: min(100%, 16rem);
  }
}

.blog-post > .article-meta .meta-chip + .meta-chip {
  position: relative;
}

.blog-post > .article-meta .meta-chip + .meta-chip::before {
  position: absolute;
  right: 100%;
  margin-right: 0.45em;
}

/* ---- Page mastheads: every page opens on paper ------------------------- */

.page-hero .container {
  position: relative;
  z-index: 2;
}

.page-hero .container:not(.page-masthead) > p {
  width: fit-content;
  margin-inline: auto;
  /* Paper under the subtitle keeps the dots from printing through it, as
     under the datelines. */
  padding: 0.15em 0.6em;
  color: var(--graza-ink);
  background: var(--graza-cream);
}

.page-hero .attractor-background {
  display: block;
}

@media (prefers-reduced-motion: no-preference) {
  .page-hero .attractor-background:not(.attractor-background--fallback) {
    -webkit-mask-image: linear-gradient(#000 0 14rem, rgb(0 0 0 / 0.3) 22rem);
    mask-image: linear-gradient(#000 0 14rem, rgb(0 0 0 / 0.3) 22rem);
  }
}

.page-hero .attractor-background.attractor-background--fallback {
  opacity: 0.14;
  background-color: var(--graza-ink);
  -webkit-mask: url("/assets/images/studio-contours.svg") center / cover no-repeat;
  mask: url("/assets/images/studio-contours.svg") center / cover no-repeat;
}

.page-masthead {
  display: block;
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  text-align: center;
}

.page-hero .page-masthead .page-dateline {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.35rem 1.5rem;
  max-width: none;
  margin: 0;
  padding: 0.85rem 0.25rem;
  color: var(--graza-ink);
  /* Paper under the dateline keeps the dots from printing over its text. */
  background: var(--graza-cream);
  border-top: 0;
  border-bottom: 4px solid var(--graza-ink);
  font-family: var(--graza-font-mono);
  font-size: var(--graza-type-label);
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
}

.page-dateline__page {
  color: var(--coral);
}

/* The folio stays one row at every width: below 1024px it drops the lab
   line, and on the narrowest phones the cities too. */
@media (max-width: 1023px) {
  .page-hero .page-masthead .page-dateline {
    flex-wrap: nowrap;
    white-space: nowrap;
  }

  .page-hero .page-masthead .page-dateline > span:nth-child(2) {
    display: none;
  }
}

@media (max-width: 520px) {
  .page-dateline__where {
    display: none;
  }
}

/* Inner pages open on a folio that hangs off the nav: the page's name, the
   lab, and the dateline, closed by one thick rule. That rule opens the page,
   so the first section below drops its own (see the line weights). */
.page-hero--masthead {
  display: block;
  padding: 0;
  border-bottom: 0;
}

.page-hero--masthead .page-masthead {
  margin-top: 0;
}

/* ---- Publications: headings open on a 4px rule, not a plate ------------ */

.publications h2,
.influential-papers > h2 {
  width: auto;
  padding: 0.75rem 0 0;
  background: none;
  border-top: 4px solid var(--graza-ink);
}

/* ---- Citation chart: printed like the blog figures --------------------- */

.citation-chart__tick span,
.citation-chart__year {
  color: var(--graza-ink);
}

/* Deep coral: bright coral nearly vanished on the coral-tint plate. */
.citation-chart__column:last-child .citation-chart__bar {
  background: var(--coral);
}

/* The note closes the plate like a figure caption, on a rule. */
.citation-chart__note {
  margin: 0 calc(-1 * clamp(1rem, 2vw, 1.5rem));
  padding: 0.75rem clamp(1rem, 2vw, 1.5rem);
  color: var(--graza-ink);
  background: var(--graza-cream);
  border-top: 1px solid var(--graza-ink);
  line-height: 1.45;
}

/* ---- Review fixes: phones, headings, buttons, posts -------------------- */

/* "More research notes" lost its last letter at 320px on one forced line. */
@media (max-width: 359px) {
  .section-heading--single-line h2 {
    white-space: normal;
  }
}

/* 14px side gutters read cramped for a print page on phones. */
@media (max-width: 600px) {
  .container {
    width: min(100% - 40px, 1320px);
  }

  .blog-post {
    width: min(840px, calc(100vw - 40px));
  }
}

/* Short last lines such as a lone "out." read as widows. */
:is(h1, h2) {
  text-wrap: balance;
}

/* Primary buttons sit on paper, where lime measured 1.09:1 and showed only
   by its outline. Brand coral carries them; lime fills stay on dark green. */
.button.primary {
  color: var(--graza-ink);
  background: var(--graza-coral);
}

/* Post headings alternated coral and sky rules; one brand-coral rule now. */
.blog-post .content h2:nth-of-type(even) {
  border-bottom-color: var(--graza-coral);
}

/* Work entries ran 120 characters a line; hold them to a reading measure. */
.work-card > div > :is(p, ul) {
  max-width: 68ch;
}

/* Footer headings are h2s after the page content, so they opt out of the
   display heading rules and keep the 13px mono label style. */
.footer-section h2 {
  margin: 0 0 1rem;
  font-size: var(--graza-type-label);
  font-weight: 500;
  letter-spacing: 0.1em;
  line-height: 1.3;
  text-transform: uppercase;
  text-wrap: wrap;
}

/* ---- Publications: a margin column, as on the work page ---------------- */

/* Wide screens use the full measure: rank and venue sit in a left column,
   and each catalog heading holds the rail beside its list. */
@media (min-width: 901px) {
  .influential-paper {
    grid-template-columns: minmax(0, 1fr) minmax(0, 3fr);
    grid-template-rows: auto auto 1fr;
    column-gap: clamp(2rem, 4vw, 4rem);
  }

  .influential-paper::before {
    grid-column: 1;
    grid-row: 1;
  }

  .influential-paper > .influential-paper__meta {
    grid-column: 1;
    grid-row: 2;
    margin: 0.75rem 0 0;
  }

  .influential-paper > h3 {
    grid-column: 2;
    grid-row: 1 / span 2;
  }

  .influential-paper > dl {
    grid-column: 2;
    grid-row: 3;
  }

  /* Each group is its own grid, so a sticky heading stays beside its own
     list and never slides over the next group's heading. */
  .publication-group {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 3fr);
    column-gap: clamp(2rem, 4vw, 4rem);
    align-items: start;
  }

  .publication-group + .publication-group {
    margin-top: clamp(3rem, 5vw, 4.5rem);
  }

  /* The heading stays in view beside its list while the reader scrolls. */
  .publication-group > h2 {
    grid-column: 1;
    position: sticky;
    top: 6.5rem;
    margin: 0;
    font-size: clamp(1.875rem, calc(1.4rem + 1.2vw), 2.625rem);
  }

  .publication-group > ul {
    grid-column: 2;
    margin: 0;
    border-top: 4px solid var(--graza-ink);
  }
}

/* ---- Post figures: numbered, with the alt text as the caption ---------- */

/* Post figures print like the card figures: a 3px frame around the post's
   tinted plate, the chart on a paper matte, and a mono caption at the foot,
   set flush left. */
.post-figure {
  margin: 0;
  padding: clamp(0.75rem, 2vw, 1.25rem) clamp(0.75rem, 2vw, 1.25rem) 0;
  background: var(--figure-paper, var(--graza-coral-tint));
  border: 3px solid var(--graza-ink);
}

/* Consecutive figures, like the SHAP post's five panels, stack into one
   plate that shares edges, instead of frames 19px apart reading double. */
.post-figure + .post-figure {
  margin-top: -1.2rem;
  border-top: 0;
}

.blog-post .content .post-figure img {
  padding: 0.5rem;
  border: 0;
  border-radius: 0;
}

.post-figure figcaption {
  padding: 0.75rem 0 0.9rem;
  color: var(--graza-ink);
  font-family: var(--graza-font-mono);
  font-size: var(--graza-type-label);
  line-height: 1.45;
  text-align: left;
}

.post-figure figcaption span {
  margin-right: 0.4em;
  color: var(--graza-ink);
  font-weight: 500;
}

/* ---- Link arrows: a fixed head and a shaft that stretches -------------- */

/* A no-break space keeps the arrow on the last word's line. The padding is
   the arrow's length, and the mask draws a head on the right plus a shaft
   across the rest, so a hover that widens the box lengthens the line. Form
   buttons submit rather than go somewhere, so they carry no arrow. Paper
   links rest as a printer's square instead; see below. */
a.button::after,
.publications li a::after,
.influential-paper h3 a::after {
  content: "\00A0";
  display: inline;
  margin-left: 0.2em;
  padding-right: 0.6em;
  background-color: currentColor;
  -webkit-mask:
    var(--arrow-head) right center / 0.48em 0.72em no-repeat,
    linear-gradient(#000 0 0) right 0.05em top 50% / calc(100% - 0.05em) 0.1em no-repeat;
  mask:
    var(--arrow-head) right center / 0.48em 0.72em no-repeat,
    linear-gradient(#000 0 0) right 0.05em top 50% / calc(100% - 0.05em) 0.1em no-repeat;
  font-weight: 400;
}

@media (prefers-reduced-motion: no-preference) {
  a.button::after,
  .publications li a::after,
  .influential-paper h3 a::after {
    transition: padding-right 0.2s ease;
  }
}

a.button:is(:hover, :focus-visible)::after,
.publications li a:is(:hover, :focus-visible)::after,
.influential-paper h3 a:is(:hover, :focus-visible)::after {
  padding-right: 1.35em;
}

/* Paper links rest as a small coral square, a printer's mark, and stretch
   into the arrow on hover: the square flattens into the shaft while the
   head grows in. The head layer has no size at rest. */
.publications li a::after,
.influential-paper h3 a::after {
  padding-right: 0.5em;
  -webkit-mask-size: 0 0, 0.5em 0.5em;
  mask-size: 0 0, 0.5em 0.5em;
}

.publications li a:is(:hover, :focus-visible)::after,
.influential-paper h3 a:is(:hover, :focus-visible)::after {
  -webkit-mask-size: 0.48em 0.72em, calc(100% - 0.05em) 0.1em;
  mask-size: 0.48em 0.72em, calc(100% - 0.05em) 0.1em;
}

@media (prefers-reduced-motion: no-preference) {
  .publications li a::after,
  .influential-paper h3 a::after {
    transition: padding-right 0.25s ease, -webkit-mask-size 0.25s ease, mask-size 0.25s ease;
  }
}

/* ---- Posts end on the same square, as a magazine article does ---------- */

/* The cookie policy shares the post layout but is not an article to end. */
article.blog-post:not(.blog-post--policy) .content::after {
  content: "";
  justify-self: start;
  width: 0.6em;
  height: 0.6em;
  margin-top: 0.5rem;
  background: var(--coral);
}

/* ---- How we work: three phases in ruled columns ----------------------- */

.process-phases {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: clamp(1.5rem, 3vw, 2.5rem) 0 0;
  padding: 0;
  list-style: none;
  border-top: 2px solid var(--graza-ink);
}

@media (max-width: 760px) {
  .process-phases {
    grid-template-columns: minmax(0, 1fr);
  }
}

.process-phase {
  padding-top: 1rem;
}

.process-phase__when {
  margin: 0;
  color: var(--coral);
  font-family: var(--graza-font-mono);
  font-size: var(--graza-type-label);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.process-phase h3 {
  margin: 0.35rem 0 0.5rem;
  font-size: clamp(1.5rem, calc(1.25rem + 0.6vw), 1.875rem);
  /* Display type at 1.6 left two-line titles floating apart. */
  line-height: 1.1;
}

/* Each phase opens on a big italic coral numeral, like the hero's
   deliverables list, ahead of its duration. */
.process-phases {
  counter-reset: phase;
}

.process-phase {
  counter-increment: phase;
}

.process-phase__when::before {
  content: counter(phase);
  margin-right: 0.55rem;
  color: var(--coral);
  font-family: var(--graza-font-display);
  font-size: 2.75rem;
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 0.8;
  text-transform: none;
  vertical-align: -0.12em;
}

/* Twelve squares, one per week of the longest sprint, sit under each
   duration. Solid weeks always run; striped weeks run when the work needs
   them; blank weeks stay on the tint. */
.week-boxes {
  display: grid;
  grid-template-columns: repeat(12, 0.85rem);
  gap: 4px;
  margin: 0.7rem 0 0.9rem;
}

.week-boxes > span {
  aspect-ratio: 1;
  background: var(--graza-tint);
}

.week-boxes > .is-min {
  background: var(--coral);
}

.week-boxes > .is-max {
  background: repeating-linear-gradient(
    -45deg,
    var(--coral) 0 2px,
    transparent 2px 4.5px
  );
}

/* Side by side, the phases share rows so their lists start level. */
@media (min-width: 761px) {
  .process-phase {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    row-gap: 0;
    align-content: start;
  }
}

.process-phase > p:not(.process-phase__when) {
  margin: 0 0 0.75rem;
  font-size: 1.125rem;
}

.process-phase ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.process-phase li {
  padding: 0.45rem 0;
  border-top: 1px solid var(--graza-rule);
  font-size: 1.125rem;
  line-height: 1.4;
}

/* ---- Line weights ------------------------------------------------------- */

/* 4px opens a section, 3px frames an object, 2px divides rows, and 1px
   marks list items. No two thick rules sit back to back: the folio's rule
   opens each inner page, so the first section under it starts without one,
   and the last ranked paper hands over to the catalog's own 4px opener. */
.page-hero--masthead + .section .influential-papers > h2 {
  padding-top: 0;
  border-top: 0;
}

.influential-paper:last-child {
  border-bottom: 0;
}

.featured-post,
.card-grid--editorial .blog-card,
.home-page [data-home-section="blog"] .blog-card,
.citation-chart {
  border-width: 3px;
}

/* On home each section heading stands on its own 4px shelf, in the
   heading's colour: ink on paper, lime on dark green. The ground colours
   already mark where a section starts, so the seams carry no rule. The
   client strip's label has no shelf; the strip's ink edges make it a
   printed band. */
.home-page .section-heading h2,
.home-page [data-home-section="contact"] .contact > h2 {
  max-width: none;
  margin-bottom: 1.1rem;
  padding-bottom: 0.3em;
  border-bottom: 4px solid currentColor;
}

.home-page [data-home-section="clients"] .section-heading h2 {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: 0;
}

/* The shelf opens these lists, so their own first rule would double it. */
.home-page [data-home-section="services"] .section-heading {
  border-bottom: 0;
}

.home-page #talks[data-home-section="talks"] .blog-card:first-child {
  border-top: 0;
}

/* How we work reads as newspaper columns, with 2px rules between phases. */
.process-phases {
  gap: 0;
}

.process-phase {
  padding-right: clamp(1.25rem, 2.5vw, 2.25rem);
}

.process-phase + .process-phase {
  padding-left: clamp(1.25rem, 2.5vw, 2.25rem);
  border-left: 2px solid var(--graza-ink);
}

/* Stacked on phones, the column rules turn into row rules. */
@media (max-width: 760px) {
  .process-phase {
    padding-right: 0;
  }

  .process-phase + .process-phase {
    margin-top: 1rem;
    padding-left: 0;
    border-top: 2px solid var(--graza-ink);
    border-left: 0;
  }
}

.card-figure,
.featured-post__media.card-figure {
  border-bottom-width: 3px;
}

/* ---- Print ---------------------------------------------------------------- */

/* Print what the screen shows: keep the grounds and the chart's bars, which
   browsers drop by default, and leave out the moving parts and the call to
   action. */
@media print {
  html {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .site-header {
    position: static;
  }

  .nav-deck,
  .nav-cta,
  .attractor-background,
  .skip-link {
    display: none;
  }
}

.home-page .site-footer {
  padding-top: clamp(2rem, 4vw, 3rem);
}

/* ---- Post cards: aligned rows and a printed-card lift ------------------ */

/* Cards in a row share their rows, so a two-line caption no longer pushes
   one title below its neighbour's. Phones stack the cards, so they skip it. */
@media (min-width: 601px) {
  .home-page [data-home-section="blog"] .blog-card,
  .card-grid--editorial .blog-card {
    display: grid;
    grid-row: span 3;
    grid-template-rows: subgrid;
    row-gap: 0;
  }
}

/* On hover a card lifts off the page like a printed card picked up: it
   shifts up and left onto a hard ink shadow, with no blur. */
.home-page [data-home-section="blog"] .blog-card:is(:hover, :focus-visible),
.card-grid--editorial .blog-card:is(:hover, :focus-visible) {
  box-shadow: 5px 5px 0 var(--graza-ink);
  transform: translate(-5px, -5px);
}

@media (prefers-reduced-motion: no-preference) {
  .home-page [data-home-section="blog"] .blog-card,
  .card-grid--editorial .blog-card {
    transition: transform 0.15s ease, box-shadow 0.15s ease;
  }
}
