@import url("https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;500;700&family=Inter:wght@400;500;700&display=swap");

:root {
  --bg: #f4f1fb;
  --bg-soft: #faf8ff;
  --ink: #1e1b16;
  --ink-soft: #5b564c;
  --ink-faint: #6f6a60;
  --line: rgba(30, 27, 22, 0.12);
  --mist-1: #f3c869;
  --mist-2: #e8598f;
  --mist-3: #9b5de5;
  --accent: #6d28d9;
  --max: 1280px;
  --divider-gap: 48px; /* space between a divider and the content on either side of it */

  --font-display: "Inter Tight", system-ui, sans-serif;
  --font-body: "Inter", system-ui, sans-serif;

  /* type scale: two families only (display + body), never italic */
  --fs-xs: 11px;
  --fs-sm: 13px;
  --fs-base: 15px;
  --fs-md: 17px;
  --fs-lg: 21px;
  --fs-xl: 26px;
  --fs-2xl: 44px;
  --fs-h4: clamp(22px, 2.6vw, 28px);
  --fs-h3: clamp(26px, 3.4vw, 40px);
  --fs-h2: clamp(32px, 4vw, 48px);
  --fs-h1: clamp(36px, 5vw, 60px);
  --fs-display: clamp(48px, 8vw, 108px);

  --ls-tight: -0.01em;
  --ls-label: 0.08em;
  --ls-wide: 0.12em;
}

html[data-theme="dark"] {
  --bg: #1a212c;
  --bg-soft: #222b38;
  --ink: #ece9f7;
  --ink-soft: #b3b3cc;
  --ink-faint: #8d95a5;
  --line: rgba(236, 233, 247, 0.12);
  --mist-1: #8098b3;
  --mist-2: #445267;
  --mist-3: #5b7290;
  --accent: #a78bfa;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  transition: background 0.25s ease, color 0.25s ease;
}

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

.display {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--ls-tight);
}

.container {
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 32px;
}

/* ---------- Nav ---------- */

.nav {
  position: relative;
  z-index: 20;
}

.nav-inner {
  max-width: var(--max);
  margin: 0 auto;
  padding: 32px 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.logo {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-xl);
}

.nav-right {
  display: flex;
  align-items: center;
  gap: 16px;
}

.nav-links {
  display: flex;
  gap: 32px;
}

.nav-link {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: 4px;
  border-bottom: 1px solid transparent;
}

.nav-link.is-active {
  border-bottom-color: var(--ink);
}

.nav-link:hover {
  color: var(--ink-soft);
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: none;
  color: var(--ink);
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
}

.theme-toggle svg {
  width: 16px;
  height: 16px;
}

.theme-toggle .icon-sun {
  display: none;
}

html[data-theme="dark"] .theme-toggle .icon-sun {
  display: block;
}

html[data-theme="dark"] .theme-toggle .icon-moon {
  display: none;
}

.nav-toggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
  color: var(--ink);
}

.nav-toggle svg {
  display: block;
  width: 22px;
  height: 22px;
}

@media (max-width: 720px) {
  .nav-inner {
    padding: 16px 16px;
  }

  .nav-right {
    gap: 12px;
  }

  .nav-links {
    position: fixed;
    inset: 0;
    background: var(--bg-soft);
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 32px;
    padding: 0 32px;
    transform: translateX(100%);
    transition: transform 0.3s ease;
  }

  .nav-links.is-open {
    transform: translateX(0);
  }

  .nav-link {
    font-size: var(--fs-md);
  }

  .nav-toggle {
    display: block;
    position: relative;
    z-index: 30;
  }
}

/* ---------- Hero ---------- */

.hero {
  position: relative;
  padding: 96px 0 144px;
  overflow: hidden;
}

.hero-content {
  position: relative;
  z-index: 1;
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 32px;
}

.hero-name {
  font-size: var(--fs-display);
  line-height: 1.02;
  margin: 0 0 32px;
}

.hero-role {
  font-family: var(--font-body);
  font-size: clamp(var(--fs-sm), 1.4vw, var(--fs-base));
  font-weight: 500;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-soft);
  line-height: 1.7;
  max-width: 520px;
}

.hero-greeting {
  margin: 0 0 32px;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: var(--ink-soft);
}

/* time and location, pinned to the bottom corners of the hero */
.hero-meta {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 28px;
  z-index: 1;
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: var(--ink-soft);
}

.hero-meta-time {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

@media (max-width: 720px) {
  .hero-meta {
    padding: 0 16px;
    bottom: 22px;
  }
}

.hero-clock-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
}

.hero-clock-time {
  color: var(--ink);
  font-weight: 500;
}

/* ---------- Centred hero: dot-grid canvas on the plain page background ---------- */

/* Nav floats transparently over the hero, so the canvas runs behind it */
.nav--overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  background: none;
}

.hero--centered {
  /* nav height (36px toggle + 2 x 32px padding) + the original 120px on top;
     the bottom padding keeps the hero the same height as it was with the arrow */
  padding: 192px 0 256px;
}

@media (max-width: 720px) {
  .hero--centered {
    padding-top: 192px;
  }
}

/* where the process flow is visible, size the hero so the tallest loop-back arch (a semicircle, so its
   height scales with the flow's width) rises just into the text, with room left above the time and location */
@media (min-width: 1001px) {
  .hero--centered {
    padding-bottom: calc(64px + 0.236 * min(1200px, 100vw - 64px));
  }
}

/* Inner pages: same canvas, nav overlay and centred text as Home, in a shorter hero.
   Top padding = nav height (100px) + breathing room. */
.hero--page {
  padding: 144px 0 96px;
}

@media (max-width: 720px) {
  .hero--page {
    padding-top: 144px;
  }
}

.hero--page .case-title {
  margin: 0 auto;
}

/* case study / post content that starts right under the hero needs air below the hero */
.hero--page + .container {
  padding-top: 48px;
}

.hero--centered .hero-content {
  text-align: center;
  /* sits above the process flow so the text stays crisp where an arch passes behind it */
  z-index: 2;
}

.hero--centered .hero-role {
  margin: 0 auto;
  max-width: none;
  white-space: nowrap;
}

/* one line on wider screens; break after "inclusion-driven" on phones where it can't fit */
.hero-role-break {
  display: none;
}

@media (max-width: 720px) {
  .hero--centered .hero-role {
    white-space: normal;
  }

  .hero-role-break {
    display: inline;
  }
}

.hero-canvas {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* faint dot grid, fading out toward the bottom so the hero runs straight into the page */
.hero-canvas::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle at 11.5px 11.5px, color-mix(in srgb, var(--ink) 20%, transparent) 1.2px, transparent 1.9px);
  background-size: 22px 22px;
  /* whole-pixel offset (fallback first) so the dots stay round instead of smearing across half pixels */
  background-position: center top;
  background-position: round(down, 50%, 1px) 0;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.55) 45%, transparent 85%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.55) 45%, transparent 85%);
}

/* ---------- Design process flow with AI assistance (band below the hero text) ---------- */

.hero-flow {
  position: absolute;
  left: 50%;
  bottom: 106px;
  width: min(1200px, calc(100vw - 80px));
  height: auto;
  transform: translateX(-50%);
  z-index: 1;
  pointer-events: none;
  overflow: visible;
  --flow-line: color-mix(in srgb, var(--ink) 14%, transparent);
  --flow-node: color-mix(in srgb, var(--ink) 32%, transparent);
  --flow-label: color-mix(in srgb, var(--ink) 64%, transparent);
  --flow-gate-label: color-mix(in srgb, var(--ink) 76%, transparent);
  --flow-sub: color-mix(in srgb, var(--ink) 70%, transparent);
}

/* --flow-sw is set by script.js so strokes stay 2px on screen as the SVG scales; 2 (user units) is the fallback */
/* pathLength="1" lets a single 1 -> 0 dash offset reveal any path */
.hero-flow-line,
.hero-flow-arc {
  fill: none;
  stroke: var(--flow-line);
  stroke-width: var(--flow-sw, 2);
  stroke-dasharray: 1;
  stroke-dashoffset: 0;
}

.hero-flow-line {
  animation: flow-draw 3.6s linear 0.5s both;
}

/* the re-iteration arcs draw themselves once the line has passed the step they leave from */
.hero-flow-arc {
  animation: flow-draw var(--dur) ease-in-out var(--d) both;
}

.hero-flow-arrow {
  fill: none;
  stroke: var(--flow-node);
  stroke-width: var(--flow-sw, 2);
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: flow-fade 0.6s ease-out var(--d) both;
}

.hero-flow-node {
  animation: flow-fade 0.8s ease-out var(--d) both;
}

.hero-flow-node .ring {
  fill: none;
  stroke: var(--flow-line);
  stroke-width: var(--flow-sw, 2);
}

.hero-flow-node .dot {
  fill: var(--flow-node);
}

.hero-flow-node text {
  font-family: var(--font-body);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.14em;
  fill: var(--flow-label);
}

/* what AI does at each stage: a sparkle and two words, quieter than the stage name */
.hero-flow-node .sub text {
  font-family: var(--font-body);
  font-size: 9px;
  font-weight: 400;
  letter-spacing: 0.04em;
  fill: var(--flow-sub);
}

.hero-flow .spark {
  fill: var(--flow-sub);
}

/* cross-functional checkpoints: a solid accent badge with an overlapping-circles glyph on the line, labelled a shade darker than the stages */
.hero-flow-gate {
  animation: flow-fade 0.8s ease-out var(--d) both;
}

.hero-flow .badge circle:first-child {
  fill: var(--accent);
}

.hero-flow .badge .glyph {
  fill: none;
  stroke: var(--bg);
  stroke-width: 1.3;
}

.hero-flow-gate text {
  font-family: var(--font-body);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.06em;
  fill: var(--flow-gate-label);
}

@keyframes flow-draw {
  from { stroke-dashoffset: 1; }
  to { stroke-dashoffset: 0; }
}

@keyframes flow-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-flow-line,
  .hero-flow-arc,
  .hero-flow-arrow,
  .hero-flow-node,
  .hero-flow-gate {
    animation: none;
  }
}

/* the AI notes and checkpoint labels get too small to read below this width; the collaboration badges stay */
@media (max-width: 1160px) {
  .hero-flow-node .sub,
  .hero-flow-gate text {
    display: none;
  }
}

/* the labels get too small to read below this width, so the flow is hidden */
@media (max-width: 1000px) {
  .hero-flow {
    display: none;
  }
}

.scroll-cue {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  margin-top: 96px;
  color: var(--ink);
}

.scroll-cue svg {
  width: 26px;
  height: 26px;
}

/* ---------- Sections ---------- */

section {
  position: relative;
}

.section {
  padding: 96px 0;
}

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 48px;
  flex-wrap: wrap;
}

.section-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h2);
  margin: 0;
}

/* quote used as a section headline (Home story): same voice as the About pullquote, sized to fit the narrow column */
.section-title--quote {
  font-weight: 500;
  font-size: var(--fs-h3);
  line-height: 1.3;
}

.section-title--quote .accent {
  color: var(--accent);
}

.section-note {
  max-width: 380px;
  color: var(--ink-soft);
  font-size: var(--fs-base);
  line-height: 1.6;
}

.kicker {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 12px;
}

/* ---------- Story / intro ---------- */

/* the two columns are sized to their content and centred as one block */
.story-grid {
  display: grid;
  grid-template-columns: 360px minmax(0, 660px);
  justify-content: center;
  gap: 48px;
}

@media (max-width: 860px) {
  .story-grid {
    grid-template-columns: minmax(0, 660px);
    gap: 16px;
  }
}

.story-text {
  max-width: 660px;
  margin-left: auto;
  margin-right: auto;
  font-size: var(--fs-md);
  line-height: 1.8;
  color: var(--ink-soft);
}

.story-text p {
  margin: 0 0 16px;
}

.cta-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding: 16px 32px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  transition: background 0.2s ease;
}

.cta-button:hover {
  background: var(--accent);
}

.company-strip {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 48px;
  /* narrow enough that the logos wrap into two even rows, not one long row and a couple of strays */
  max-width: 900px;
  margin: 32px auto 0;
  --logo-scale: 1.2; /* grows every logo by the same factor, so their proportions to each other stay the same */
}

@media (max-width: 720px) {
  .company-strip {
    --logo-scale: 1;
  }
}

/* the divider above the strip already provides the space */
.divider + .container > .company-strip {
  margin-top: 0;
}

.company-strip-label {
  /* full-width row so the logos start on the line below */
  flex: 0 0 100%;
  text-align: center;
  margin-bottom: -6px;
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-faint);
}

.company-name {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--ink-soft);
}

/* One-colour brand logos: flattened to a single tone, full ink on hover */
.brand-logo {
  display: block;
  height: calc(var(--h, 28px) * var(--logo-scale, 1));
  width: auto;
  filter: brightness(0);
  opacity: 0.45;
  /* --dy compensates for uneven padding inside each logo file so the artwork centres on the same line */
  transform: translateY(calc(var(--dy, 0px) * var(--logo-scale, 1)));
  transition: opacity 0.2s ease;
}

.brand-logo:hover {
  opacity: 1;
}

html[data-theme="dark"] .brand-logo {
  filter: brightness(0) invert(1);
  opacity: 0.4;
}

html[data-theme="dark"] .brand-logo:hover {
  opacity: 1;
}

/* ---------- Canvas divider: a slice of the hero's dot grid between sections ---------- */

.divider {
  height: 66px; /* three 22px dot rows, matching the hero grid */
  pointer-events: none;
  background-image: radial-gradient(circle at 11.5px 11.5px, color-mix(in srgb, var(--ink) 50%, transparent) 1.2px, transparent 1.9px);
  background-size: 22px 22px;
  background-position: center;
  background-position: round(down, 50%, 1px) 0;
  /* fade out at both ends, and on the top and bottom rows */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 35%, #000 65%, transparent),
    linear-gradient(to bottom, transparent, #000 50%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent, #000 35%, #000 65%, transparent),
    linear-gradient(to bottom, transparent, #000 50%, transparent);
  mask-composite: intersect;
  margin: var(--divider-gap) 0;
}

/* the hero's time and location sit 28px (22px on phones) above the hero's bottom edge */
.hero + .divider {
  margin-top: calc(var(--divider-gap) - 32px);
}

@media (max-width: 720px) {
  :root {
    --divider-gap: 36px;
  }

  .hero + .divider {
    margin-top: calc(var(--divider-gap) - 16px);
  }
}

/* sections and blocks that touch a divider drop their own padding, so the divider's margin sets the spacing */
.section--flush {
  padding: 0;
}

.story-text p:last-child {
  margin-bottom: 0;
}

/* the divider stands in for the footer's hairline */
.divider + .footer {
  border-top: none;
  padding-top: 0;
}

/* ---------- Pull quote ---------- */

.pullquote {
  padding: 64px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.pullquote p {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--fs-h3);
  line-height: 1.35;
  max-width: 900px;
  margin: 0;
}

.pullquote .accent {
  color: var(--accent);
}

/* ---------- Featured work (rows: 1/3 image, 2/3 text, sides alternate, hairlines between; used on Home and Portfolio) ---------- */

.feature-list {
  display: flex;
  flex-direction: column;
}

.feature {
  --feature-ink: var(--ink);
  --feature-soft: var(--ink-soft);
  --feature-line: var(--line);
  display: block;
  color: var(--feature-ink);
  padding: 0;
}

/* hairlines sit only between rows; the dotted dividers above and below the list stand in for the outer edges */
.feature + .feature {
  border-top: 1px solid var(--line);
}

.feature:first-child {
  padding-top: 0;
}

.feature:last-child {
  padding-bottom: 0;
}

/* the whole row is the link */
.feature-inner {
  --tile-bg: var(--bg); /* what the row looks like right now; the tile's knocked-out shapes match it */
  display: flex;
}

a.feature .feature-inner {
  transition: background-color 0.2s ease;
}

a.feature:hover .feature-inner,
a.feature:focus-visible .feature-inner {
  --tile-bg: color-mix(in srgb, var(--accent) 12%, var(--bg));
  background: var(--tile-bg); /* light purple wash: lilac on cream in light mode, a cool tint on navy in dark */
}

a.feature:focus-visible {
  outline: none;
}

a.feature:focus-visible .feature-inner {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

/* odd rows: image left, text right (DOM order). even rows: image right, text left */
@media (min-width: 1001px) {
  .feature-list > .feature:nth-child(even) .feature-inner {
    flex-direction: row-reverse;
  }
}

.feature-content {
  flex: 0 0 calc(100% * 2 / 3); /* text takes two thirds of the row, padding included */
  min-width: 0;
  padding: 32px 32px;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

/* title, blurb and badges use the same type as the Writing list (.post-title, .post-excerpt, .post-status) */
.feature-title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  margin: 0 0 8px;
}

.feature-desc {
  color: var(--feature-soft);
  font-size: var(--fs-base);
  line-height: 1.7;
  max-width: 620px;
  margin: 0 0 12px;
}

.feature .tag {
  color: var(--ink-faint);
  border-color: var(--feature-line);
}

.feature-media {
  position: relative;
  flex: 0 0 calc(100% / 3); /* the tile takes one third of the row, flush to the panel border */
  min-width: 0;
  min-height: 320px;
  overflow: hidden;
}

/* layer 1: the hero's dot grid as its own element, fading toward the tile edges so the drawing sits in a soft spotlight.
   The fade is a mask, not a colour overlay, so the tile takes on whatever the row is (page background or the hover wash) */
.feature-canvas {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(circle at 10.5px 10.5px, color-mix(in srgb, var(--ink) 20%, transparent) 1.2px, transparent 1.9px);
  background-size: 20px 20px;
  background-position: center;
  background-position: round(down, 50%, 1px) round(down, 50%, 1px);
  -webkit-mask-image: radial-gradient(ellipse at center, #000 20%, transparent 78%);
  mask-image: radial-gradient(ellipse at center, #000 20%, transparent 78%);
}

/* ---------- Work tiles: an outline drawing of the project. Complete at rest; it redraws when the row is hovered, like the hero flow ---------- */

/* layer 2: the drawing, stacked above the dot canvas */
.tile {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  --tile-ink: color-mix(in srgb, var(--ink) 62%, transparent);
  --tile-mute: color-mix(in srgb, var(--ink) 28%, transparent);
  --tile-fill: color-mix(in srgb, var(--ink) 26%, transparent);
}

.t-l,
.t-m,
.t-a,
.t-b {
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.t-l { stroke: var(--tile-ink); }  /* main outline */
.t-m { stroke: var(--tile-mute); } /* placeholder text lines and secondary structure */
.t-a { stroke: var(--accent); }    /* the one accent moment: the match, the AI, the approval */
.t-b { stroke: var(--bg); }        /* glyph drawn on a solid accent badge */
.t-k { stroke-width: 4.5; }

.t-fa { fill: var(--accent); stroke: none; }
.t-fi { fill: var(--tile-fill); stroke: none; }
.t-fb { fill: var(--tile-bg); transition: fill 0.2s ease; } /* knocks the dots out behind a shape, in the row's own background */

.tile text {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  fill: var(--tile-ink);
}

/* draw (pathLength="1" lets one dash offset reveal any shape), pop, slide, fade and travel-along-a-path share one --d delay */
.t-d {
  stroke-dasharray: 1 2;
  stroke-dashoffset: 0;
}

.t-p,
.t-pulse {
  transform-box: fill-box;
  transform-origin: center;
}

.t-dots {
  stroke-dasharray: 1.5 7;
}

.t-go {
  offset-distance: 100%;
  offset-rotate: 0deg;
}

.t-gone {
  opacity: 0;
}

@media (prefers-reduced-motion: no-preference) {
  :is(.feature:hover, a.feature:focus-visible) .t-d { animation: tile-draw 0.8s ease-in-out var(--d, 0s) both; }
  :is(.feature:hover, a.feature:focus-visible) .t-p { animation: tile-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) var(--d, 0s) both; }
  :is(.feature:hover, a.feature:focus-visible) .t-s { animation: tile-slide 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) var(--d, 0s) both; }
  :is(.feature:hover, a.feature:focus-visible) .t-f { animation: tile-fade 0.8s ease-out 0.6s both; }
  :is(.feature:hover, a.feature:focus-visible) .t-go { animation: tile-go 1.4s ease-in-out 0.3s both; }
  :is(.feature:hover, a.feature:focus-visible) .t-gone { animation-name: tile-go-fade; }
  :is(.feature:hover, a.feature:focus-visible) .t-pulse { animation: tile-pulse 1.6s ease-in-out 1.6s infinite; }
}

@keyframes tile-draw {
  from { stroke-dashoffset: 1; }
  to { stroke-dashoffset: 0; }
}

@keyframes tile-pop {
  from { opacity: 0; transform: scale(0.4); }
  to { opacity: 1; transform: none; }
}

@keyframes tile-slide {
  from { opacity: 0; transform: translate(var(--fx, 0), var(--fy, 0)); }
  to { opacity: 1; transform: none; }
}

@keyframes tile-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes tile-go {
  from { offset-distance: 0%; }
  to { offset-distance: 100%; }
}

@keyframes tile-go-fade {
  from { offset-distance: 0%; opacity: 1; }
  85% { opacity: 1; }
  to { offset-distance: 100%; opacity: 0; }
}

@keyframes tile-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.22); }
}

/* ---------- RECs tile: a reconciliation, not a drawing. Two documents drift in from either edge and meet, the AI star bursts,
   one document snaps over the other, offset so the one underneath is only partly shown (the break), and the unmatched rows (magenta-purple) are left to deal with.
   Complete at rest (overlapped, breaks flagged). script.js adds .is-armed (rewinds it to the start, paused) and, once the tile
   scrolls into view, .is-playing (runs it once). It is not tied to hover. ---------- */
.tile-rec {
  --burst: 0.55s; /* the moment the documents meet (0.04s beat + 0.51s approach); the snap-over, burst and breaks are all timed from it */
  --rec-play: paused;
}

/* magenta-purple = something to deal with (RECs' unmatched rows, eNOL's damage); the accent is the resolution */
:is(.tile-rec, .tile-enol) { --tile-warn: #a21caf; }
html[data-theme="dark"] :is(.tile-rec, .tile-enol) { --tile-warn: #e879f9; }
.tile-rec.is-playing { --rec-play: running; }

.rec-flash,
.rec-ring,
.rec-spark,
.rec-star {
  opacity: 0; /* only ever seen mid-sequence */
}

.rec-ok,
.rec-flash,
.rec-ring,
.rec-spark,
.rec-star {
  transform-box: fill-box;
  transform-origin: center;
}

.rec-ring {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
}

.rec-flash,
.rec-spark { fill: var(--accent); }

/* the few sparkles the sequence ends on: drawn where they rest, still, outside the documents */
.rec-keep {
  fill: var(--accent);
  transform-box: fill-box;
  transform-origin: center;
}

.tile-rec .rec-band {
  fill: color-mix(in srgb, var(--tile-warn) 22%, transparent);
  stroke: none;
}

.tile-rec .rec-warn { stroke: var(--tile-warn); }

@media (prefers-reduced-motion: no-preference) {
  .tile-rec.is-armed .rec-src--l { animation: rec-from-l 0.51s linear 0.04s both; }
  .tile-rec.is-armed .rec-src--r { animation: rec-from-r 0.51s linear 0.04s both; }
  .tile-rec.is-armed .rec-flash { animation: rec-flash 0.19s linear var(--burst) forwards; }
  .tile-rec.is-armed .rec-ring { animation: rec-ring 0.32s linear calc(var(--burst) + var(--j, 0s)) forwards; }
  .tile-rec.is-armed .rec-spark { animation: rec-spark 0.28s linear calc(var(--burst) + var(--j, 0s)) forwards; }
  .tile-rec.is-armed .rec-star { animation: rec-star-burst 0.43s linear var(--burst) both; }
  .tile-rec.is-armed .rec-keep { opacity: 0; animation: rec-keep 0.28s linear calc(var(--burst) + var(--j, 0s)) forwards; }
  .tile-rec.is-armed .rec-ok { animation: rec-pop 0.09s cubic-bezier(0.34, 1.56, 0.64, 1) var(--d) both; }
  .tile-rec.is-armed .rec-break { animation: rec-fade 0.09s ease-out var(--d) both; }

  /* held at the first frame until .is-playing; sits after the rules above and its :is() outweighs them, so it always wins */
  .tile-rec.is-armed :is(.rec-src, .rec-flash, .rec-ring, .rec-spark, .rec-keep, .rec-star, .rec-ok, .rec-break) {
    animation-play-state: var(--rec-play);
  }
}

/* both documents travel in a straight line at a constant speed, sliding one over the other as they meet: no easing, no pause */
@keyframes rec-from-l { from { transform: translate(-106px, -30px); } }
@keyframes rec-from-r { from { transform: translateX(112px); } }

@keyframes rec-flash {
  from { opacity: 0.55; transform: scale(0.3); }
  to { opacity: 0; transform: scale(1.7); }
}

@keyframes rec-ring {
  from { opacity: 0.9; transform: scale(0.2); }
  to { opacity: 0; transform: scale(var(--s, 7)); }
}

@keyframes rec-spark {
  from { opacity: 1; transform: translate(0, 0) scale(0.4); }
  70% { opacity: 1; }
  to { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(1.1); }
}

/* the star is born big at the point of impact, then shrinks away to nothing right there */
@keyframes rec-star-burst {
  0% { opacity: 1; transform: scale(0); }
  25% { opacity: 1; transform: scale(3.7); }
  100% { opacity: 0; transform: scale(0); }
}

/* the sparkles that stay fly out from the impact and come to rest at their place */
@keyframes rec-keep {
  from { opacity: 1; transform: translate(var(--fx), var(--fy)) scale(0.3); }
  to { opacity: 1; transform: none; }
}

@keyframes rec-pop { from { opacity: 0; transform: scale(0.4); } }
@keyframes rec-fade { from { opacity: 0; } }

/* ---------- eNOL tile: a claim, told fast, in one second. The car starts already damaged, a form appears on top of it and its
   three fields fill in one by one, an AI sparkle reviews it, and the car is put right. Complete at rest (car whole, no form) --
   this final picture is also what shows under reduced motion or with no JS, so it has to read as finished on its own.
   script.js adds .is-armed (rewinds it to the start, paused) and .is-playing (runs it once) as the tile scrolls into view.
   Not tied to hover.
   Timeline (s): 0-0.16 pause on the damaged car / 0.16-0.3 form pops on / 0.36-0.76 fields fill / 0.7-0.92 sparkle reviews / 0.78-1.0 car put right ---------- */
.tile-enol { --enol-play: paused; }
.tile-enol.is-playing { --enol-play: running; }

.enol-damage,
.enol-ring,
.enol-form,
.enol-spark {
  opacity: 0; /* only ever seen mid-sequence; at rest the car is simply whole */
}

.enol-car,
.enol-ring,
.enol-form,
.enol-spark {
  transform-box: fill-box;
  transform-origin: center;
}

.enol-car { transform-origin: 0 100%; } /* pivots on the rear bumper, so the front is what lifts and crumples */

.enol-type { stroke-dasharray: 1 2; }
.tile-enol .enol-warn { stroke: var(--tile-warn); }
.enol-spark { fill: var(--accent); }

.enol-ring {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
}

@media (prefers-reduced-motion: no-preference) {
  .tile-enol.is-armed .enol-car { animation: enol-car 1s linear both; }
  .tile-enol.is-armed .enol-damage { animation: enol-damage 1s linear both; }
  .tile-enol.is-armed .enol-form { animation: enol-form-life 1s linear both; }
  .tile-enol.is-armed .enol-spark { animation: enol-spark 1s linear both; }
  .tile-enol.is-armed .enol-type { animation: tile-draw 0.1s linear var(--d) both; }
  .tile-enol.is-armed .enol-ring { animation: enol-ring 0.12s linear 0.88s forwards; } /* not `both`: its first frame must stay hidden until the fix */

  /* held at the first frame until .is-playing; the :is() outweighs the rules above, so it always wins */
  .tile-enol.is-armed :is(.enol-car, .enol-damage, .enol-form, .enol-spark, .enol-type, .enol-ring) {
    animation-play-state: var(--enol-play);
  }
}

/* damaged from the start and held there for a beat, so the "before" registers, then held through the form, then put right with a little bounce */
@keyframes enol-car {
  0%, 80% { transform: scaleX(0.94) rotate(-2deg); }
  92% { transform: scale(1.04); animation-timing-function: ease-out; }
  100% { transform: none; }
}

@keyframes enol-damage {
  0%, 80% { opacity: 1; }
  90%, 100% { opacity: 0; }
}

/* a pause on the damaged car with no form yet, then the form pops on, holds while its fields fill, then dismisses as the sparkle finishes reviewing */
@keyframes enol-form-life {
  0%, 16% { opacity: 0; transform: scale(0.5); animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); }
  30% { opacity: 1; transform: scale(1.05); animation-timing-function: ease-in; }
  36%, 76% { opacity: 1; transform: none; }
  90%, 100% { opacity: 0; transform: scale(0.92); }
}

@keyframes enol-spark {
  0%, 70% { opacity: 0; transform: scale(0) rotate(-25deg); }
  78% { opacity: 1; transform: scale(1.25) rotate(6deg); animation-timing-function: ease-in-out; }
  84% { transform: scale(0.95) rotate(-4deg); }
  92%, 100% { opacity: 0; transform: scale(1.1); }
}

@keyframes enol-ring {
  from { opacity: 0.8; transform: scale(0.3); }
  to { opacity: 0; transform: scale(7); }
}

/* ---------- Post-Trade tile: told the same way as RECs, in one second. The two tickets arrive at a constant speed and one snaps
   over the other, offset -- but nothing is left exposed as a break here, it's a clean settle. A filled check roundel bursts at the
   point of impact and vanishes (like RECs' AI star), and a few smaller roundels of different sizes fly out and come to rest around
   the tickets: Post-Trade's answer to RECs' resting sparkles, a settled check instead of an AI spark.
   Complete at rest (tickets overlapped, roundels resting) -- this final picture is also what shows under reduced motion or with no
   JS, so it has to read as finished on its own, not just mid-animation. script.js adds .is-armed (rewinds it to the start, paused)
   and .is-playing (runs it once) as the tile scrolls into view. Not tied to hover.
   Timeline (s): 0-0.4 tickets arrive / 0.4 impact / 0.4-0.83 roundel bursts and vanishes / 0.4-0.73 flash + rings / 0.5-0.96 checks rest ---------- */
.tile-pt { --pt-play: paused; }
.tile-pt.is-playing { --pt-play: running; }

.pt-flash,
.pt-ring,
.pt-burst {
  opacity: 0; /* only ever seen mid-sequence, as the tickets meet */
}

.pt-flash,
.pt-ring,
.pt-burst {
  transform-box: fill-box;
  transform-origin: center;
}

.pt-flash { fill: var(--accent); }

.pt-ring {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
}

/* the roundels that stay: drawn where they rest, visible by default (the reduced-motion/no-JS picture), and flown in on top when animated */
.pt-keep { transform-box: fill-box; transform-origin: center; }

@media (prefers-reduced-motion: no-preference) {
  .tile-pt.is-armed .pt-src--l { animation: pt-slide-l 0.4s linear both; }
  .tile-pt.is-armed .pt-src--r { animation: pt-slide-r 0.4s linear both; }
  .tile-pt.is-armed .pt-flash { animation: rec-flash 0.5s linear 0.4s forwards; }
  .tile-pt.is-armed .pt-ring { animation: rec-ring 0.32s linear calc(0.4s + var(--j, 0s)) forwards; }
  .tile-pt.is-armed .pt-burst { animation: rec-star-burst 0.43s linear 0.4s both; }
  .tile-pt.is-armed .pt-keep { opacity: 0; animation: rec-keep 0.32s linear calc(0.5s + var(--j, 0s)) forwards; }

  /* held at the first frame until .is-playing; the :is() outweighs the rules above, so it always wins */
  .tile-pt.is-armed :is(.pt-src--l, .pt-src--r, .pt-flash, .pt-ring, .pt-burst, .pt-keep) {
    animation-play-state: var(--pt-play);
  }
}

@keyframes pt-slide-l { from { transform: translateX(-190px); } }
@keyframes pt-slide-r { from { transform: translateX(200px); } }

@media (prefers-reduced-motion: reduce) {
  a.feature .feature-inner,
  a.post-item::before {
    transition: none;
  }
}

@media (max-width: 1000px) {
  .feature-inner {
    flex-direction: column;
  }
  .feature-content {
    flex: none;
    padding: 32px 16px 32px;
  }
  .feature-media {
    flex: none;
    min-height: 0;
    aspect-ratio: 4 / 3;
  }
}

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tag {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 12px;
}

.view-all {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 48px;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 4px;
}

.view-all svg {
  width: 16px;
  height: 16px;
}

/* ---------- Timeline (About) ---------- */

.timeline {
  display: flex;
  flex-direction: column;
}

.timeline-item {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 32px;
  padding: 32px 0;
  border-top: 1px solid var(--line);
}

/* the dotted dividers around the list stand in for its first and last rules */
.timeline-item:first-child {
  border-top: none;
}

.timeline-when {
  font-family: var(--font-body);
  color: var(--ink-faint);
  font-size: var(--fs-sm);
  font-weight: 500;
}

.timeline-role {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-lg);
  margin: 0 0 4px;
}

.timeline-org {
  font-size: var(--fs-base);
  font-weight: 400;
  color: var(--ink-soft);
  margin: 0 0 12px;
}

.timeline-desc {
  color: var(--ink-soft);
  font-size: var(--fs-base);
  line-height: 1.7;
  max-width: 640px;
}

.timeline-desc ul {
  margin: 12px 0 0;
  padding-left: 16px;
}

.timeline-desc li {
  margin-bottom: 8px;
}

/* recognition under a role: a leading Tabler icon in place of the bullet */
.timeline-desc .timeline-awards {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  gap: 12px;
}

.timeline-desc .timeline-awards li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 0;
}

.timeline-awards svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--accent);
}

.timeline-award-title {
  margin: 0;
  font-weight: 700;
  line-height: 1.4;
  color: var(--ink);
}

.timeline-award-sub {
  margin: 4px 0 0;
  line-height: 1.5;
}

/* several positions at one company (LinkedIn style): each role hangs off a thin thread, newest first */
.timeline-roles {
  margin-top: 32px;
}

.timeline-role-item {
  position: relative;
  padding: 0 0 32px 32px;
}

.timeline-role-item:last-child {
  padding-bottom: 0;
}

.timeline-role-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ink-faint);
}

.timeline-role-item.is-current::before {
  background: var(--accent);
}

.timeline-role-item:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 4px;
  top: 24px;
  bottom: -4px;
  width: 1px;
  background: var(--line);
}

/* one position at a company: the dates already sit in the left column, so no thread or dot, just the role under the company */
.timeline-roles--single {
  margin-top: 16px;
}

.timeline-roles--single .timeline-role-item {
  padding: 0;
}

.timeline-roles--single .timeline-role-item::before {
  display: none;
}

.timeline-roles--single .timeline-subrole {
  margin-bottom: 8px;
}

.timeline-subrole {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-md);
  margin: 0 0 4px;
}

.timeline-dates {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--ink-faint);
  margin: 0 0 12px;
}

@media (max-width: 700px) {
  .timeline-item {
    grid-template-columns: 1fr;
    gap: 8px;
  }
}

/* ---------- Contact ---------- */

.contact-links {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.contact-link {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 32px 0;
  border-top: 1px solid var(--line);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h4);
}

.contact-link:first-child {
  border-top: none;
}

.contact-link .go {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-faint);
}

.contact-link:hover .go {
  color: var(--ink);
}

.card-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 16px;
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink);
  border-bottom: 1px solid var(--ink);
  padding-bottom: 4px;
  width: fit-content;
}

.card-link svg {
  width: 13px;
  height: 13px;
}

/* ---------- Case study ---------- */

.case-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 32px;
}

.case-back svg {
  width: 15px;
  height: 15px;
}

.case-title {
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  margin: 0 0 32px;
  max-width: 860px;
}

.case-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}

@media (max-width: 800px) {
  .case-meta {
    grid-template-columns: repeat(2, 1fr);
  }
}

.case-meta-label {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 8px;
}

.case-meta-value {
  font-size: var(--fs-base);
  font-weight: 700;
  line-height: 1.5;
}

.case-placeholder {
  border: 1px dashed var(--line);
  border-radius: 4px;
  background: var(--bg-soft);
  min-height: 340px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px;
}

.case-placeholder span {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--ink-faint);
  max-width: 360px;
  line-height: 1.6;
}

/* sections are separated by the dotted dividers; the divider's margin sets the spacing */
.case-section {
  padding: 0;
}

.case-section-title {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-faint);
  max-width: 760px;
  margin: 0 auto 16px; /* same centred column as the copy below it */
}

.case-prose {
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
  font-size: var(--fs-md);
  line-height: 1.8;
  color: var(--ink-soft);
}

.case-prose p {
  margin: 0 0 12px;
}

.case-prose p:last-child {
  margin-bottom: 0;
}

.case-note {
  display: block;
  margin-top: 8px;
  font-size: var(--fs-sm);
  color: var(--ink-faint);
}

.case-list {
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
  padding-left: 12px;
  color: var(--ink-soft);
  font-size: var(--fs-md);
  line-height: 1.8;
}

.case-list li {
  margin-bottom: 12px;
}

.case-award {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  max-width: 640px;
  margin-top: 16px;
}

.case-award svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--accent);
}

.case-award-title {
  font-weight: 700;
  margin: 0 0 4px;
}

.case-award-sub {
  font-size: var(--fs-base);
  color: var(--ink-soft);
  margin: 0;
}

/* in a case study the award sits in the same centred column as the copy */
.case-section .case-award {
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
}

.case-footer-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.case-footer-nav a {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
}

/* ---------- Writing ---------- */

.post-list {
  display: flex;
  flex-direction: column;
}

.post-item {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 32px;
  padding: 32px 0;
  border-top: 1px solid var(--line);
}

/* the dotted divider above the list stands in for the first rule */
.post-item:first-child {
  border-top: none;
}

/* a post with a page is one link: the whole row is clickable */
a.post-item {
  color: inherit;
}

a.post-item .post-title {
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
  transition: text-decoration-color 0.2s ease;
}

a.post-item:hover .post-title,
a.post-item:focus-visible .post-title {
  text-decoration-color: var(--accent);
}

a.post-item:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 4px;
}

/* hover wash, same lilac as the feature rows: a flat rectangle that bleeds 24px past the text on each side (inside the 40px page gutter) and keeps 12px clear of the hairlines */
a.post-item {
  position: relative;
  isolation: isolate;
}

a.post-item::before {
  content: "";
  position: absolute;
  inset: 12px -24px;
  z-index: -1;
  background: transparent;
  transition: background-color 0.2s ease;
}

a.post-item:hover::before,
a.post-item:focus-visible::before {
  background: color-mix(in srgb, var(--accent) 12%, var(--bg));
}

.post-date {
  font-family: var(--font-body);
  color: var(--ink-faint);
  font-size: var(--fs-sm);
  font-weight: 500;
}

.post-title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  margin: 0 0 8px;
}

.post-excerpt {
  color: var(--ink-soft);
  font-size: var(--fs-base);
  line-height: 1.7;
  max-width: 620px;
  margin: 0 0 12px;
}

.post-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-faint);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 12px;
}

.post-status.is-draft::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

@media (max-width: 700px) {
  .post-item {
    grid-template-columns: 1fr;
    gap: 8px;
  }
}

.post-body {
  max-width: 720px;
  margin-left: auto;
  margin-right: auto;
  font-size: var(--fs-md);
  line-height: 1.85;
  color: var(--ink-soft);
}

.post-body h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-xl);
  color: var(--ink);
  margin: 48px 0 16px;
}

.post-body p {
  margin: 0 0 16px;
}

.post-placeholder-note {
  display: block;
  padding: 16px 12px;
  border: 1px dashed var(--line);
  border-radius: 4px;
  background: var(--bg-soft);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  color: var(--ink-faint);
  margin-bottom: 32px;
}

/* ---------- Footer ---------- */

.footer {
  border-top: 1px solid var(--line);
  padding: 32px 0;
}

.footer-inner {
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  color: var(--ink-faint);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
}

.footer a:hover {
  color: var(--ink);
}

/* ---------- Recognition and testimonials: swipe row (home, contact) ---------- */

.swipe-head {
  align-items: center;
  margin-bottom: 32px;
}

.swipe-head .kicker {
  margin: 0;
}

.swipe-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* "1–3 of 5": which cards are in view, out of the total */
.swipe-count {
  margin-right: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  white-space: nowrap;
}

.swipe-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: none;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.2s ease, opacity 0.2s ease;
}

.swipe-btn svg {
  width: 16px;
  height: 16px;
}

.swipe-btn:hover:not(:disabled) {
  border-color: var(--ink);
}

.swipe-btn:disabled {
  opacity: 0.35;
  cursor: default;
}

.swipe-track {
  display: flex;
  gap: 32px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}

.swipe-track::-webkit-scrollbar {
  display: none;
}

.swipe-track:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 6px;
}

/* three cards in view on desktop, two on tablet, one and a peek of the next on phones */
.swipe-track > * {
  flex: 0 0 calc((100% - 56px) / 3);
  scroll-snap-align: start;
}

.swipe-bar {
  position: relative;
  height: 2px;
  margin-top: 32px;
  border-radius: 2px;
  background: var(--line);
}

.swipe-thumb {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  border-radius: 2px;
  background: var(--ink);
  transition: left 0.15s ease-out;
}

/* everything fits, so there is nothing to swipe */
[data-swipe].is-static .swipe-controls,
[data-swipe].is-static .swipe-bar {
  display: none;
}

/* awards and testimonials share the same card treatment in the swipe row */
.swipe-track .case-award,
.testimonial {
  margin: 0;
  max-width: none;
  display: flex;
  flex-direction: column;
  gap: 32px;
  padding: 32px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 4px;
}

.swipe-track .case-award {
  justify-content: flex-start;
  gap: 16px;
}

.testimonial {
  justify-content: space-between;
}

.swipe-track .case-award svg {
  width: 30px;
  height: 30px;
  margin-top: 0;
}

.swipe-track .case-award-title {
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1.25;
  margin: 0 0 8px;
}

/* reserve two lines so the award titles line up whether or not the subtitle wraps */
.swipe-track .case-award-sub {
  line-height: 1.5;
  min-height: 3em;
}

.testimonial blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 19px;
  line-height: 1.55;
}

.testimonial blockquote::before {
  content: "\201C";
  display: block;
  font-size: 44px;
  line-height: 0.8;
  margin-bottom: 12px;
  color: var(--accent);
}

.testimonial figcaption {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.testimonial-role {
  color: var(--ink-faint);
}

@media (max-width: 1000px) {
  .swipe-track > * {
    flex-basis: calc((100% - 28px) / 2);
  }
}

@media (max-width: 600px) {
  .swipe-track {
    gap: 16px;
  }
  .swipe-track > * {
    flex-basis: 84%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .swipe-thumb,
  .swipe-btn {
    transition: none;
  }
}
