/* NX Century v2 : Hero Collective x Siena Film Foundation blend, light-first. */

/* ---------- texture ---------- */
.grain {
  position: fixed; inset: -50%;
  width: 200%; height: 200%;
  pointer-events: none; z-index: 90;
  opacity: 0.34;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.35'/%3E%3C/svg%3E");
  mix-blend-mode: multiply;
}
html[data-theme="dark"] .grain { mix-blend-mode: screen; opacity: 0.20; }

/* ---------- viewfinder corner dots (shared signature) ---------- */
.vf { position: relative; }
.vf > .vf-dot {
  position: absolute; width: 7px; height: 7px;
  background: var(--ink); border-radius: 50%;
  z-index: 6; pointer-events: none;
}
.vf > .vf-dot.tl { top: -3.5px; left: -3.5px; }
.vf > .vf-dot.tr { top: -3.5px; right: -3.5px; }
.vf > .vf-dot.bl { bottom: -3.5px; left: -3.5px; }
.vf > .vf-dot.br { bottom: -3.5px; right: -3.5px; }

/* ---------- brand corner ---------- */
.brand {
  position: fixed; top: 18px; left: var(--gutter);
  display: flex; align-items: center; gap: 0.6rem;
  z-index: 120; text-decoration: none;
  padding: 0.35rem 0.55rem;
  border-radius: 12px;
  background: color-mix(in srgb, var(--paper) 82%, transparent);
  backdrop-filter: blur(6px);
}
.brand__mark { border-radius: 8px; }
.brand__word {
  font-family: var(--font-display);
  font-weight: 800; font-size: 0.82rem;
  letter-spacing: 0.14em;
}

/* ---------- floating nav card ---------- */
.navcard {
  position: fixed; top: 18px; right: var(--gutter);
  width: min(324px, calc(100vw - 2 * var(--gutter)));
  background: var(--card-bg);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  z-index: 120;
  box-shadow: var(--shadow);
}
.navcard__top { display: flex; align-items: stretch; }
.navcard__now {
  flex: 1; display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.7rem;
  text-align: left; min-width: 0;
}
.navcard__thumb {
  flex: none; width: 38px; height: 38px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: 8px; overflow: hidden;
  background: var(--paper-2);
}
.navcard__nowtext { display: flex; flex-direction: column; min-width: 0; }
.navcard__nowlabel {
  font-size: 0.58rem; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--muted);
}
.navcard__section {
  font-family: var(--font-display); font-weight: 800;
  font-size: 0.95rem; letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.navcard__chev { flex: none; margin-left: auto; transition: transform 0.25s ease; }
.navcard__now[aria-expanded="true"] .navcard__chev { transform: rotate(180deg); }
.navcard__burger {
  flex: none; width: 56px;
  display: grid; place-items: center;
  border-left: 1px solid var(--line-strong);
}
.burger { display: block; width: 20px; }
.burger i {
  display: block; height: 2px; background: var(--ink);
  margin: 4px 0; transition: transform 0.28s ease, opacity 0.2s ease;
}
.navcard__burger[aria-expanded="true"] .burger i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.navcard__burger[aria-expanded="true"] .burger i:nth-child(2) { opacity: 0; }
.navcard__burger[aria-expanded="true"] .burger i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.navcard__tags {
  display: grid; grid-template-columns: 1fr 1fr 1fr;
  border-top: 1px solid var(--line-strong);
}
.navcard__tags span {
  padding: 0.32rem 0.4rem;
  font-size: 0.6rem; letter-spacing: 0.18em; text-transform: uppercase;
  text-align: center; color: var(--ink-soft);
  white-space: nowrap;
}
.navcard__tags span + span { border-left: 1px solid var(--line); }

.navcard__menu { border-top: 1px solid var(--line-strong); padding: 0.4rem 0 0.65rem; }
.navmenu { counter-reset: nav; list-style: none; margin: 0; padding: 0; }
.navmenu a {
  display: flex; align-items: baseline; gap: 0.8rem;
  padding: 0.45rem 0.9rem;
  text-decoration: none;
}
.navmenu__idx {
  font-size: 0.68rem; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.navmenu__label {
  font-family: var(--font-display); font-weight: 800;
  font-size: 1.55rem; letter-spacing: 0.02em; text-transform: uppercase;
  line-height: 1.1;
  transition: color 0.18s ease, transform 0.18s ease;
}
.navmenu a:hover .navmenu__label,
.navmenu a:focus-visible .navmenu__label { color: var(--red-deep); transform: translateX(4px); }
.navcard__utils {
  display: flex; flex-wrap: wrap; gap: 0.4rem 1rem;
  padding: 0.55rem 0.9rem 0;
  border-top: 1px solid var(--line);
  margin-top: 0.4rem;
}
.navcard__utils a, .navcard__utils button {
  font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-soft); text-decoration: none;
}
.navcard__utils a:hover, .navcard__utils button:hover { color: var(--red-deep); }
.navcard__copy {
  padding: 0.5rem 0.9rem 0;
  font-size: 0.62rem; color: var(--muted); letter-spacing: 0.08em;
}

/* ---------- shared section chrome ---------- */
.section { padding: var(--sp-6) 0; }
.section__inner { max-width: 1240px; margin: 0 auto; padding: 0 var(--gutter); }
.section__head {
  display: grid; gap: 1.2rem;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  align-items: end;
  margin-bottom: var(--sp-5);
}
.section__head--tight { margin-bottom: var(--sp-4); grid-template-columns: 1fr; }
.section__label {
  grid-column: 1 / -1;
  font-size: 0.7rem; letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: 0.4rem;
}
.section__label 
.section__title {
  font-family: var(--font-display);
  font-weight: 850; font-stretch: 112%;
  font-size: clamp(2.1rem, 5vw, 3.9rem);
  line-height: 0.98; letter-spacing: -0.015em;
  text-transform: uppercase;
}
.section__title em {
  font-family: var(--font-serif); font-style: italic; font-weight: 480;
  text-transform: none; letter-spacing: 0;
  color: var(--red-deep);
}
.section__title--sm { font-size: clamp(1.6rem, 3.4vw, 2.6rem); }
.section__aside {
  color: var(--muted); font-size: var(--text-sm); max-width: 34ch;
  justify-self: end; padding-bottom: 0.4rem;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.85rem 1.7rem;
  border-radius: var(--radius-pill);
  font-weight: 600; font-size: 0.95rem;
  text-decoration: none;
  transition: transform 0.18s ease, background 0.18s ease, color 0.18s ease;
}
.btn--primary { background: var(--red); color: #fff; }
.btn--primary:hover { background: var(--red-deep); transform: translateY(-2px); }
.btn--ghost { border: 1px solid var(--line-strong); color: var(--ink); }
.btn--ghost:hover { border-color: var(--red-deep); color: var(--red-deep); transform: translateY(-2px); }
.btn--lg { padding: 1.05rem 2.2rem; font-size: 1.05rem; }

/* ---------- tag strip (Siena cell strip) ---------- */
.tagstrip {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  border: 1px solid var(--line-strong);
  border-radius: 6px; overflow: hidden;
  background: var(--card-bg);
}
.tagstrip span {
  padding: 0.3rem 0.45rem;
  font-family: var(--font-body);
  font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase;
  text-align: center; color: var(--ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tagstrip span + span { border-left: 1px solid var(--line); }

/* ---------- HERO ---------- */
.hero {
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding: calc(var(--header-h) + 2.25rem) var(--gutter) 4rem;
  max-width: 1400px; margin: 0 auto;
  position: relative;
}
.hero__eyebrow {
  font-size: 0.72rem; letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: clamp(1rem, 3vh, 2.2rem);
}

.kinetic {
  font-family: var(--font-display);
  font-weight: 900; font-stretch: 116%;
  text-transform: uppercase;
  line-height: 0.88; letter-spacing: -0.02em;
  font-size: clamp(3rem, 10vw, 8.6rem);
  margin: 0 0 clamp(1.4rem, 3.2vh, 2.4rem);
  display: flex; flex-direction: column;
}
.kinetic__row { display: block; overflow: hidden; padding-bottom: 0.06em; }
.kinetic__row--2 { margin-left: clamp(1.5rem, 9vw, 9rem); }
.kinetic__row--3 { margin-left: clamp(0.5rem, 4vw, 3.5rem); }
.kin-word { display: inline-block; white-space: nowrap; }
.kin-word--red { color: var(--red); }
.kin-word--outline {
  color: transparent;
  -webkit-text-stroke: 2.5px var(--ink);
}
/* kinetic reveal */
.js .kin-word .kin-ch {
  display: inline-block;
  transform: translateY(115%);
  animation: kin-rise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  animation-delay: var(--d, 0s);
}
@keyframes kin-rise { to { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  .js .kin-word .kin-ch { transform: none; animation: none; }
}

.hero__lower {
  display: grid; gap: 2.5rem;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  align-items: end;
}
.hero__sub { max-width: 46ch; color: var(--ink-soft); font-size: var(--text-lg); line-height: 1.5; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 1.6rem; }

.hero__card {
  margin: 0; justify-self: end;
  width: min(430px, 100%);
  transform: rotate(1.4deg);
}
.hero__card video {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover;
  border-radius: 18px;
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow);
}
.hero__card .tagstrip { margin-top: 0.55rem; }



 }

/* ---------- SERVICES : numbered capability rows ---------- */
.services { background: var(--paper-2); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.caps { display: block; }
.cap {
  display: grid; gap: 0.5rem 2rem;
  grid-template-columns: 5.5rem minmax(0, 1.2fr) minmax(0, 1.6fr) auto;
  align-items: baseline;
  padding: 1.9rem 0;
  border-top: 1px solid var(--line-strong);
  transition: background 0.2s ease;
}
.cap:last-child { border-bottom: 1px solid var(--line-strong); }
.cap:hover { background: color-mix(in srgb, var(--red) 4%, transparent); }
.cap__idx {
  font-family: var(--font-display); font-weight: 700;
  color: var(--red-deep); font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
}
.cap__name {
  font-family: var(--font-display); font-weight: 850; font-stretch: 110%;
  font-size: clamp(1.35rem, 2.6vw, 2.1rem);
  text-transform: uppercase; line-height: 1;
  letter-spacing: -0.01em;
}
.cap__list { color: var(--muted); font-size: var(--text-sm); line-height: 1.6; }
.cap__scope {
  font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-soft);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 0.32rem 0.75rem;
  white-space: nowrap; justify-self: end;
}

/* ---------- WORK : asymmetric floating rail ---------- */
.rail-wrap { overflow: hidden; }
.rail {
  display: flex; gap: clamp(1.2rem, 3vw, 2.6rem);
  overflow-x: auto;
  padding: 3.2rem var(--gutter) 3.6rem;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail-card {
  flex: none;
  width: clamp(280px, 34vw, 470px);
  text-decoration: none;
  scroll-snap-align: center;
  transition: transform 0.35s ease;
}
.rail-card:nth-child(odd) { transform: translateY(-14px) rotate(-0.7deg); }
.rail-card:nth-child(even) { transform: translateY(22px) rotate(0.8deg); }
.rail-card:hover { transform: translateY(0) rotate(0deg) scale(1.015); }
.rail-card--wide { width: clamp(320px, 46vw, 640px); }
.rail-card--tall { width: clamp(250px, 26vw, 360px); }
.rail-card video {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
  border-radius: var(--radius-card);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow);
  background: var(--paper-2);
}
.rail-card--wide video { aspect-ratio: 16 / 10; }
.rail-card__meta { display: block; padding: 0.9rem 0.25rem 0; }
.rail-card__client {
  display: block;
  font-family: var(--font-display); font-weight: 850; font-stretch: 110%;
  font-size: 1.3rem; text-transform: uppercase; letter-spacing: 0;
  margin-bottom: 0.5rem;
}
.rail-card__desc {
  display: block;
  color: var(--muted); font-size: var(--text-sm); line-height: 1.5;
  margin-top: 0.6rem;
  max-width: 40ch;
  opacity: 0; transform: translateY(6px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.rail-card:hover .rail-card__desc,
.rail-card:focus-visible .rail-card__desc { opacity: 1; transform: none; }
@media (hover: none) { .rail-card__desc { opacity: 1; transform: none; } }

.rail-foot {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 0.4rem;
}
.rail-counter {
  font-family: var(--font-display); font-weight: 800;
  font-size: 1.5rem; font-variant-numeric: tabular-nums;
}
.rail-counter #rail-current { color: var(--red-deep); }
.rail-controls { display: flex; gap: 0.6rem; }
.rail-btn {
  width: 48px; height: 48px;
  display: grid; place-items: center;
  border: 1px solid var(--line-strong); border-radius: 50%;
  transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}
.rail-btn:hover { background: var(--ink); color: var(--paper); transform: translateY(-2px); }

/* ---------- CLIENT LOGOS ---------- */
/* Client logos run as a marquee rather than a fixed grid: five logos in a
   static row reads as "these are all of them", where a moving strip reads as
   an ongoing roster. Two identical tracks, translated exactly -50%, so the
   loop closes on a matching frame with no visible seam. */
.logo-marquee {
  position: relative;
  overflow: clip;
  /* Feather both edges so logos enter and leave rather than pop at a hard cut. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
}
.logo-track {
  display: flex;
  width: max-content;
  gap: clamp(0.9rem, 2vw, 1.6rem);
  margin: 0;
  padding: 0;
  list-style: none;
  /* Duration scales with the wider track to keep a constant pixel
     speed: roughly 90px/s, about twice the old pace. */
  animation: logo-scroll 50s linear infinite;
  will-change: transform;
}
@keyframes logo-scroll {
  from { transform: translate3d(0, 0, 0); }
  /* -50% is exactly one full set, because the track holds the set twice. */
  to   { transform: translate3d(-50%, 0, 0); }
}
/* Let someone stop it to actually read a logo. */
.logo-marquee:hover .logo-track,
.logo-marquee:focus-within .logo-track {
  animation-play-state: paused;
}
.logo-track .logo-cell {
  flex: 0 0 clamp(190px, 22vw, 250px);
}
.logo-cell {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.9rem;
  padding: 1.6rem 1.1rem 1.2rem;
  background: var(--card-bg);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  min-height: 172px;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.logo-cell:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.logo-cell img {
  max-height: 84px; width: auto; max-width: 100%;
  object-fit: contain;
  margin: auto 0;
}
.logo-cell__name {
  font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted);
}

/* ---------- MANIFESTO ---------- */
.manifesto {
  position: relative;
  min-height: 92svh;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  text-align: center;
  padding: var(--sp-6) var(--gutter);
  overflow: hidden;
  background: #0d0c09;
}
.manifesto__media { position: absolute; inset: 0; }
.manifesto__media video {
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0.52;
  filter: saturate(0.85) contrast(1.05);
}
.manifesto__media::after {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(ellipse at center, rgba(13,12,9,0.15) 0%, rgba(13,12,9,0.72) 100%);
}
.manifesto__stack { position: relative; z-index: 2; }
.manifesto__row {
  display: flex; align-items: baseline; justify-content: center;
  gap: clamp(0.6rem, 2vw, 1.6rem);
  font-family: var(--font-display); text-transform: uppercase;
  line-height: 0.92;
}
.mani-sm {
  font-weight: 700; font-stretch: 105%;
  font-size: clamp(1.1rem, 3.2vw, 2.6rem);
  color: #e2574d;
}
.mani-sm--dot { color: var(--red); }
.mani-big {
  font-weight: 900; font-stretch: 118%;
  font-size: clamp(3.2rem, 11vw, 10rem);
  color: #f2ecdf;
  letter-spacing: -0.02em;
}
.manifesto__body {
  position: relative; z-index: 2;
  max-width: 52ch; margin-top: 2.2rem;
  color: rgba(242, 236, 223, 0.85);
  font-size: var(--text-base);
}

.stat dt {
  font-size: 0.58rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(242, 236, 223, 0.6);
  margin-bottom: 0.45rem;
}
.stat dd {
  margin: 0;
  font-family: var(--font-display); font-weight: 850; font-stretch: 112%;
  font-size: clamp(1.7rem, 4vw, 2.7rem);
  color: #f2ecdf; line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* ---------- CTA ---------- */
.cta { padding-bottom: var(--sp-6); }
.cta__inner { text-align: center; max-width: 900px; }
.cta .section__label { margin-bottom: 1rem; }
.cta__title {
  font-family: var(--font-display); font-weight: 900; font-stretch: 114%;
  font-size: clamp(2.6rem, 7.5vw, 6.2rem);
  text-transform: uppercase; line-height: 0.95; letter-spacing: -0.02em;
}
.cta__title em {
  font-family: var(--font-serif); font-style: italic; font-weight: 480;
  text-transform: lowercase; color: var(--red-deep); letter-spacing: 0;
}
.cta__body { max-width: 52ch; margin: 1.6rem auto 0; color: var(--muted); }
.cta__actions {
  display: flex; flex-wrap: wrap; gap: 0.9rem; justify-content: center;
  margin-top: 2.4rem;
}

/* ---------- FOOTER (Siena ledger) ---------- */
.footer {
  border-top: 1px solid var(--line-strong);
  padding: var(--sp-5) var(--gutter) 2.2rem;
  max-width: 1400px; margin: 0 auto;
}

.stamp img { border-radius: 10px; animation: stamp-counter 36s linear infinite; }
 }
@keyframes stamp-counter { to { transform: rotate(-360deg); } }

.footer__ledger { margin-bottom: 3.4rem; }
.ledger-line {
  border-top: 1px solid var(--line-strong);
  text-align: center;
  padding: 0.35rem 0;
  overflow: hidden;
}
.ledger-line:last-child { border-bottom: 1px solid var(--line-strong); }
.ledger-line span {
  display: inline-block;
  font-family: var(--font-display); font-weight: 900; font-stretch: 116%;
  font-size: clamp(2.6rem, 9vw, 8rem);
  line-height: 1.02; letter-spacing: -0.01em;
  text-transform: uppercase;
}
.ledger-line:nth-child(2) span { color: var(--red-deep); }

.footer__cols {
  display: grid; gap: 2.6rem;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr) minmax(0, 1.2fr);
  align-items: start;
  margin-bottom: 3rem;
}
.footer-col__label {
  font-size: 0.66rem; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
  margin-bottom: 1rem;
}
.pill-form {
  display: flex; align-items: center; gap: 0.5rem;
  border: 2px dotted var(--line-strong);
  border-radius: var(--radius-pill);
  padding: 0.35rem 0.35rem 0.35rem 1.2rem;
  max-width: 360px;
}
.pill-form__input {
  flex: 1; min-width: 0;
  background: none; border: none; outline: none;
  font: inherit; color: var(--ink);
  font-size: 0.95rem;
}
.pill-form__input::placeholder { color: var(--muted); }
.pill-form__btn {
  flex: none; width: 42px; height: 42px;
  display: grid; place-items: center;
  background: var(--ink); color: var(--paper);
  border-radius: 50%;
  transition: background 0.18s ease, transform 0.18s ease;
}
.pill-form__btn:hover { background: var(--red-deep); color: #fff; transform: translateX(2px); }
.pill-form__note { margin-top: 0.7rem; font-size: 0.75rem; color: var(--muted); }

.footer-links li + li { margin-top: 0.35rem; }
.footer-links a {
  text-decoration: none;
  font-family: var(--font-display); font-weight: 700;
  font-size: 0.95rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-soft);
}
.footer-links a:hover { color: var(--red-deep); }

.footer-inq {
  font-size: 0.66rem; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--red-deep); margin-bottom: 0.5rem;
}
.footer-email {
  display: inline-block;
  font-family: var(--font-display); font-weight: 850; font-stretch: 108%;
  font-size: clamp(1.2rem, 2.4vw, 1.9rem);
  text-transform: uppercase; letter-spacing: -0.01em;
  text-decoration: underline;
  text-decoration-thickness: 3px; text-underline-offset: 6px;
  text-decoration-color: var(--red);
  word-break: break-word;
  transition: color 0.18s ease;
}
.footer-email:hover { color: var(--red-deep); }
.footer-phone { margin-top: 0.8rem; }
.footer-phone a { color: var(--ink-soft); text-decoration: none; font-weight: 600; }
.footer-phone a:hover { color: var(--red-deep); }

.footer__bottom {
  display: flex; flex-wrap: wrap; gap: 0.6rem 2rem;
  justify-content: space-between;
  border-top: 1px solid var(--line);
  padding-top: 1.4rem;
  font-size: 0.78rem; color: var(--muted);
}
.footer__social { display: flex; gap: 0.6rem; }
.footer__social a { color: var(--ink-soft); text-decoration: none; }
.footer__social a:hover { color: var(--red-deep); }

/* ---------- reveals ---------- */
.js .reveal { opacity: 0; transform: translateY(26px); transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1); }
.js .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; }
}

/* ---------- responsive ---------- */
@media (max-width: 1080px) {
  .cap { grid-template-columns: 4rem minmax(0, 1fr) auto; }
  .cap__list { grid-column: 2 / -1; }
}

@media (max-width: 860px) {
  :root { --header-h: 72px; }
  .brand { top: 12px; }
  .brand__word { display: none; }
  .navcard { top: 12px; width: min(300px, calc(100vw - 92px - var(--gutter))); }
  .hero { padding-top: calc(var(--header-h) + 4.5rem); }
  .hero__lower { grid-template-columns: 1fr; }
  .hero__card { justify-self: start; width: min(430px, 100%); transform: none; }
  .section__head { grid-template-columns: 1fr; align-items: start; }
  .section__aside { justify-self: start; }
  .cap {
    grid-template-columns: 1fr;
    gap: 0.55rem;
    padding: 1.5rem 0;
  }
  .cap__list { grid-column: auto; }
  .cap__scope { justify-self: start; }
  .logo-ledger { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .logo-cell:last-child { grid-column: 1 / -1; }
  
  .footer__cols { grid-template-columns: 1fr; gap: 2.2rem; }
  .rail-card:nth-child(odd), .rail-card:nth-child(even) { transform: none; }
  .rail-card { width: min(78vw, 380px); }
  .rail-card--wide { width: min(88vw, 520px); }
  .rail-card--tall { width: min(70vw, 320px); }
}

@media (max-width: 420px) {
  .navcard { width: calc(100vw - 88px - var(--gutter)); }
  .navcard__nowlabel { display: none; }
  .kinetic { font-size: clamp(2.2rem, 12.5vw, 3.4rem); }
  .kinetic__row--2 { margin-left: 1rem; }
  .kinetic__row--3 { margin-left: 0.4rem; }
  .kin-word--outline { -webkit-text-stroke-width: 1.6px; }
  .btn { width: 100%; }
  .cta__actions .btn { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .logo-track { animation: none; }
}

/* ============================================================
   WORK: Siena-style index grid
   Replaces the scattered rail. Every project gets an identical frame
   and an identical field set (category / client / title / meta), which
   is what makes a portfolio read as a body of work instead of a pile
   of one-offs. Order carries no ranking, so the index numbers are
   labels, not a leaderboard.
   ============================================================ */
.film-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
  gap: clamp(1.6rem, 3vw, 2.8rem) clamp(1.2rem, 2.4vw, 2rem);
}

.film-card__link {
  display: grid;
  gap: 1.1rem;
  text-decoration: none;
  color: inherit;
}

/* Ratio-locked so a mix of vertical and horizontal masters still lines up. */
.film-card__frame {
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 14px;
  border: 1px solid var(--line-strong);
  background: var(--card-bg);
}
.film-card__frame video,
.film-card__frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.19, 1, 0.22, 1);
}
.film-card__link:hover .film-card__frame video,
.film-card__link:focus-visible .film-card__frame video {
  transform: scale(1.04);
}

.film-card__idx {
  position: absolute;
  top: 0.85rem;
  left: 0.9rem;
  z-index: 2;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  padding: 0.3rem 0.5rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(8px);
  color: #fff;
}

.film-card__body { display: grid; gap: 0.4rem; }

.film-card__cat {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent, #e0403a);
}
.film-card__client {
  font-size: clamp(1.15rem, 1.7vw, 1.45rem);
  font-weight: 700;
  line-height: 1.15;
}
.film-card__title {
  font-size: 0.94rem;
  line-height: 1.4;
  opacity: 0.7;
}
.film-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.15rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.5;
}
.film-card__meta > span + span::before {
  content: "/";
  margin-right: 0.5rem;
  opacity: 0.5;
}
.film-card__cta {
  margin-top: 0.5rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}
.film-card__cta i {
  transition: transform 0.3s cubic-bezier(0.19, 1, 0.22, 1);
  font-style: normal;
}
.film-card__link:hover .film-card__cta i { transform: translateX(5px); }

/* ============================================================
   CASE STUDY PAGES  (/work/*.html)
   Siena's film-detail structure: full-bleed opener, centred category
   over an oversized name with rules running through it, credits in dark
   cells, a gallery strip, then next-project cards.
   ============================================================ */

.case__bar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem clamp(1rem, 4vw, 2.6rem);
  background: color-mix(in srgb, var(--paper) 78%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line-strong);
}
.case__home { display: inline-flex; align-items: center; gap: 0.6rem; text-decoration: none; color: inherit;
  font-weight: 700; letter-spacing: 0.04em; font-size: 0.9rem; }
.case__back { text-decoration: none; color: inherit; font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.7; }
.case__back:hover { opacity: 1; }

.case__hero { position: relative; height: min(74vh, 660px); overflow: hidden; background: var(--ink); }
.case__hero-media { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Title block. The rules sit behind the name and are clipped by the text's
   own background, which is what produces Siena's struck-through look. */
.case__title-block {
  position: relative;
  text-align: center;
  padding: clamp(2.6rem, 6vw, 4.6rem) clamp(1rem, 4vw, 2.6rem) clamp(1.6rem, 3vw, 2.4rem);
}
.case__cat {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.7rem; letter-spacing: 0.22em; text-transform: uppercase;
  opacity: 0.6; margin: 0 0 1rem;
}
.case__title {
  position: relative; margin: 0;
  font-size: clamp(2.4rem, 8vw, 6.4rem);
  line-height: 0.95; letter-spacing: -0.03em; text-transform: uppercase;
  font-weight: 800;
}
.case__title::before,
.case__title::after {
  content: ""; position: absolute; left: 0; right: 0; height: 1px;
  background: var(--line-strong); opacity: 0.5;
}
.case__title::before { top: 32%; }
.case__title::after  { top: 68%; }
.case__title span { position: relative; z-index: 1; background: var(--paper); padding-inline: 0.35em; }

.case__sub { margin: 1rem auto 0; max-width: 34ch; font-size: clamp(1rem, 1.6vw, 1.2rem); opacity: 0.7; }

.case__facts {
  display: flex; flex-wrap: wrap; justify-content: center; gap: clamp(1.2rem, 4vw, 3rem);
  margin: 2rem 0 0; padding: 0; list-style: none;
}
.case__facts li { display: grid; gap: 0.3rem; }
.case__facts span {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.62rem; letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.5;
}
.case__facts b { font-size: 0.98rem; font-weight: 600; }

.case__body {
  display: grid; gap: clamp(1.4rem, 3vw, 2.4rem);
  max-width: 68ch; margin-inline: auto;
  padding: clamp(2rem, 5vw, 3.6rem) clamp(1rem, 4vw, 2.6rem);
}
.case__lede { margin: 0; font-size: clamp(1.15rem, 2.1vw, 1.5rem); line-height: 1.45; font-weight: 500; }
.case__prose { display: grid; gap: 1.1rem; }
.case__prose p { margin: 0; line-height: 1.7; opacity: 0.82; }

.case__h2 {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase;
  opacity: 0.55; margin: 0 0 1.4rem; font-weight: 500;
}
.case__h2--pill {
  display: inline-block; opacity: 1;
  padding: 0.4rem 0.9rem; border-radius: 999px;
  border: 1px solid var(--line-strong);
}

.case__credits, .case__delivered, .case__gallery {
  padding: clamp(1.6rem, 4vw, 3rem) clamp(1rem, 4vw, 2.6rem);
  max-width: 1180px; margin-inline: auto;
}

.credit-grid {
  display: grid; gap: 0.6rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
}
.credit {
  display: grid; gap: 0.4rem; align-content: center;
  min-height: 96px; padding: 1rem 1.2rem;
  border-radius: 12px;
  background: var(--ink); color: var(--paper);
  text-align: center;
}
.credit__role {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6rem; letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.6;
}
.credit__name { font-weight: 600; font-size: 1rem; }

.delivered-list {
  display: grid; gap: 0; margin: 0; padding: 0; list-style: none;
  border-top: 1px solid var(--line-strong);
}
.delivered-list li {
  padding: 0.95rem 0.2rem;
  border-bottom: 1px solid var(--line-strong);
  font-size: 1.02rem;
}

.case__gallery { max-width: 1400px; }
.shot-strip {
  display: grid; gap: 0.8rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  margin-top: 1.2rem;
}
.shot { position: relative; margin: 0; aspect-ratio: 4 / 5; overflow: hidden; border-radius: 12px; background: var(--ink); }
.shot video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.case__next {
  display: grid; gap: 0.8rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  padding: clamp(2rem, 5vw, 3.4rem) clamp(1rem, 4vw, 2.6rem);
  max-width: 1180px; margin-inline: auto;
}
.nextcard {
  position: relative; overflow: hidden;
  display: grid; gap: 0.4rem; align-content: end;
  min-height: 190px; padding: 1.4rem;
  border-radius: 14px; border: 1px solid var(--line-strong);
  text-decoration: none; color: inherit; background: var(--card-bg);
  transition: transform 0.35s cubic-bezier(0.19, 1, 0.22, 1);
}
.nextcard:hover { transform: translateY(-4px); }
.nextcard--all { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.nextcard__label {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6rem; letter-spacing: 0.18em; text-transform: uppercase; opacity: 0.6;
}
.nextcard__title { font-size: clamp(1.4rem, 3vw, 2rem); font-weight: 800; line-height: 1.05; text-transform: uppercase; }
.nextcard__cta { font-family: var(--font-mono, ui-monospace, monospace); font-size: 0.68rem; letter-spacing: 0.13em; text-transform: uppercase; opacity: 0.75; }
.nextcard__thumb {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0.22; z-index: -1;
}

.case__foot {
  border-top: 1px solid var(--line-strong);
  padding: clamp(2rem, 5vw, 3.4rem) clamp(1rem, 4vw, 2.6rem);
  text-align: center; display: grid; gap: 1rem;
}
.case__foot-mark { margin: 0; font-weight: 700; letter-spacing: 0.05em; }
.case__foot-big {
  margin: 0; font-size: clamp(1.3rem, 5vw, 3rem); font-weight: 800;
  text-transform: uppercase; letter-spacing: -0.02em; line-height: 1.05;
}
.case__foot-meta { display: flex; flex-wrap: wrap; justify-content: center; gap: 1.2rem; margin: 0; }
.case__foot-meta a {
  color: inherit; text-decoration: none;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.7;
}
.case__foot-meta a:hover { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .nextcard, .film-card__frame video { transition: none; }
}

/* ============================================================
   INTERIOR PAGES: services / locations / industries / about / contact
   Deliberately quieter than the homepage. These are read, not
   experienced: someone landed here from a search with a question,
   and the job is to answer it without making them hunt.
   ============================================================ */

.page main { padding-top: clamp(5rem, 12vh, 8rem); }

.phero {
  max-width: 60rem;
  margin-inline: auto;
  padding: clamp(1rem, 4vw, 2.4rem) clamp(1rem, 5vw, 2.6rem) clamp(1.6rem, 4vw, 2.6rem);
  display: grid; gap: 1.1rem;
}
.phero__kicker {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.68rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--accent, #e0403a);
}
.phero__h1 {
  margin: 0;
  font-size: clamp(2.1rem, 5.6vw, 4rem);
  line-height: 1.02; letter-spacing: -0.03em; font-weight: 800;
  text-wrap: balance;
}
.phero__lede {
  margin: 0; max-width: 46ch;
  font-size: clamp(1.05rem, 1.9vw, 1.3rem); line-height: 1.5; opacity: 0.75;
}
.phero__cta {
  justify-self: start; margin-top: 0.4rem;
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.85rem 1.4rem; border-radius: 999px;
  background: var(--ink); color: var(--paper); text-decoration: none;
  font-weight: 600; font-size: 0.95rem;
  transition: transform 0.25s cubic-bezier(0.19, 1, 0.22, 1);
}
.phero__cta:hover { transform: translateY(-2px); }
.phero__cta i { font-style: normal; }

.pbody, .plist, .qa, .xlinks, .pcontact {
  max-width: 60rem; margin-inline: auto;
  padding: clamp(1.2rem, 3vw, 2rem) clamp(1rem, 5vw, 2.6rem);
}
.pbody { display: grid; gap: 1.1rem; }
.pbody p { margin: 0; line-height: 1.75; max-width: 66ch; opacity: 0.86; }
.pbody--rule { border-top: 1px solid var(--line-strong); padding-top: clamp(1.6rem, 4vw, 2.4rem); }

.plist__head, .qa__head, .xlinks__head {
  margin: 0 0 1rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase;
  opacity: 0.55; font-weight: 500;
}
.plist__items { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--line-strong); }
.plist__items li {
  padding: 0.9rem 0.1rem; border-bottom: 1px solid var(--line-strong);
  line-height: 1.5;
}

/* Question headings. Plain h3 + p, no accordion: the answer must be in the
   served HTML and directly extractable, which is the whole AEO point. */
.qa__list { display: grid; gap: 1.6rem; }
.qa__item { display: grid; gap: 0.5rem; }
.qa__q { margin: 0; font-size: clamp(1.05rem, 2vw, 1.25rem); font-weight: 700; line-height: 1.3; }
.qa__a { margin: 0; line-height: 1.7; opacity: 0.82; max-width: 66ch; }

.xlinks__grid {
  display: grid; gap: 0.7rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
}
.xlink {
  display: grid; gap: 0.35rem; align-content: center;
  min-height: 104px; padding: 1.1rem 1.2rem;
  border: 1px solid var(--line-strong); border-radius: 12px;
  background: var(--card-bg); text-decoration: none; color: inherit;
  transition: transform 0.25s cubic-bezier(0.19, 1, 0.22, 1);
}
.xlink:hover { transform: translateY(-3px); }
.xlink__label {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6rem; letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.55;
}
.xlink__title { font-weight: 700; font-size: 1.02rem; line-height: 1.25; }

.pcontact { display: grid; gap: 0; border-top: 1px solid var(--line-strong); }
.pcontact__row {
  display: grid; grid-template-columns: minmax(7rem, 12rem) 1fr; gap: 1rem;
  padding: 0.95rem 0.1rem; border-bottom: 1px solid var(--line-strong);
  align-items: baseline;
}
.pcontact__label {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.64rem; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.55;
}
.pcontact__val { font-size: 1.02rem; }
a.pcontact__val { text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 640px) {
  .pcontact__row { grid-template-columns: 1fr; gap: 0.25rem; }
}

/* ============================================================
   FILM NOISE: every section after the hero
   Real film grain moves. steps() is the whole trick: interpolating
   the transform reads as a texture sliding across the page, while
   snapping between positions reads as grain sitting IN the image.
   The layer is oversized so the jumps never expose an edge.
   ============================================================ */
.section, .manifesto { position: relative; isolation: isolate; }

.section::after,
.manifesto::after {
  content: "";
  position: absolute;
  inset: -140px;
  width: calc(100% + 280px);
  height: calc(100% + 280px);
  pointer-events: none;
  z-index: 2;
  opacity: 0.30;
  mix-blend-mode: multiply;
  background-image: var(--film-noise);
  animation: film-jitter 0.85s steps(1) infinite;
}
/* On dark sections multiply would crush to black: screen lifts instead. */
[data-theme="dark"] .section::after,
[data-theme="dark"] .manifesto::after,
.manifesto::after {
  mix-blend-mode: screen;
  opacity: 0.2;
}

@keyframes film-jitter {
  0%   { transform: translate3d(0, 0, 0); }
  10%  { transform: translate3d(-16px, 9px, 0); }
  20%  { transform: translate3d(19px, -13px, 0); }
  30%  { transform: translate3d(-22px, -8px, 0); }
  40%  { transform: translate3d(13px, 18px, 0); }
  50%  { transform: translate3d(-10px, -19px, 0); }
  60%  { transform: translate3d(23px, 7px, 0); }
  70%  { transform: translate3d(-18px, 15px, 0); }
  80%  { transform: translate3d(9px, -22px, 0); }
  90%  { transform: translate3d(-13px, 12px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .section::after, .manifesto::after { animation: none; }
}

/* ============================================================
   NAV MORPH :  CTA at rest → NX mark docked bottom-left on scroll
   Two states on <html>: data-nav="rest" and data-nav="docked".
   Everything animates from those; JS only flips the attribute.
   ============================================================ */
.navcard {
  transition:
    top 0.6s cubic-bezier(0.65, 0, 0.35, 1),
    left 0.6s cubic-bezier(0.65, 0, 0.35, 1),
    right 0.6s cubic-bezier(0.65, 0, 0.35, 1),
    bottom 0.6s cubic-bezier(0.65, 0, 0.35, 1),
    transform 0.6s cubic-bezier(0.65, 0, 0.35, 1),
    border-radius 0.5s ease,
    padding 0.5s ease,
    background 0.4s ease;
}

.navcard__cta {
  display: flex; align-items: center; gap: 0.7rem;
  text-decoration: none; color: inherit;
  padding: 0.15rem 0.1rem;
}
.navcard__mark {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 9px;
  background: var(--card-bg); border: 1px solid var(--line-strong);
  overflow: hidden;
}
.navcard__mark img { width: 22px; height: 22px; object-fit: contain; }
.navcard__ctatext { display: grid; gap: 0.1rem; overflow: hidden; }
.navcard__ctalabel {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.56rem; letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.55;
  white-space: nowrap;
}
.navcard__ctaword {
  font-weight: 700; font-size: 0.95rem; letter-spacing: -0.01em; white-space: nowrap;
}
.navcard__arrow { flex: 0 0 auto; opacity: 0.7; transition: transform 0.3s cubic-bezier(0.19,1,0.22,1); }
.navcard__cta:hover .navcard__arrow { transform: translateX(4px); }

/* ---- docked: collapse to the mark, park bottom-left ---- */
[data-nav="docked"] .navcard {
  top: auto;
  right: auto;
  bottom: clamp(1rem, 3vh, 1.6rem);
  left: clamp(1rem, 3vw, 1.6rem);
  border-radius: 999px;
  padding: 0.45rem;
}
/* The service tags are context for the CTA; they have no job once docked. */
[data-nav="docked"] .navcard__tags { display: none; }

[data-nav="docked"] .navcard__ctatext,
[data-nav="docked"] .navcard__arrow {
  max-width: 0;
  opacity: 0;
  transform: translateX(-6px);
  pointer-events: none;
}
.navcard__ctatext, .navcard__arrow {
  max-width: 12rem; opacity: 1;
  transition: max-width 0.5s cubic-bezier(0.65,0,0.35,1), opacity 0.3s ease, transform 0.4s ease;
}
[data-nav="docked"] .navcard__cta { gap: 0; padding: 0; }
[data-nav="docked"] .navcard__mark {
  width: 42px; height: 42px; border-radius: 999px;
}
[data-nav="docked"] .navcard__mark img { width: 26px; height: 26px; }

/* The brand wordmark top-left would duplicate the docked mark. */
[data-nav="docked"] .brand__word { opacity: 0; transform: translateX(-8px); }
.brand__word { transition: opacity 0.35s ease, transform 0.45s ease; }

/* Menu opens upward when docked, or it would run off the bottom. */
[data-nav="docked"] .navcard__menu {
  top: auto;
  bottom: calc(100% + 0.6rem);
}

@media (prefers-reduced-motion: reduce) {
  .navcard, .navcard__ctatext, .navcard__arrow, .brand__word { transition: none; }
}

/* ============================================================
   HERO: fluted-glass bed
   The <video> is only a texture source for the shader; the canvas
   paints over it. Both sit behind the hero content, dimmed enough
   that the headline stays the loudest thing in the frame.
   ============================================================ */
.hero { position: relative; isolation: isolate; }
.hero > *:not(.hero__glass) { position: relative; z-index: 1; }

.hero__glass {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--paper);
}
.hero__glass video,
.hero__glass canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* The raw video is the fallback. Once the shader has painted a frame it
   sets data-glass-on and the source is hidden, so there is never a moment
   of double image. */
/* The glass is texture, not an image. Held well below full strength so a
   bright frame in the source can never come up behind the copy and take
   the contrast with it: legibility must not depend on which frame the
   video happens to be showing. */
.hero__glass canvas { opacity: 0; transition: opacity 0.9s ease; }
.hero__glass[data-glass-on] canvas { opacity: 0.55; }
[data-theme="dark"] .hero__glass[data-glass-on] canvas { opacity: 0.42; }
.hero__glass[data-glass-on] video { opacity: 0; }
.hero__glass video { opacity: 0.5; transition: opacity 0.6s ease; }

/* Scrim: the glass is texture, not content. Without this the headline
   fights the refraction and both lose. */
.hero__glass::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Never fully opaque at the top: a solid band that ends inside the
     viewport reads as a hard-edged box behind the headline, which is
     exactly how it looked on a short mobile hero. Ease the whole way. */
  background:
    linear-gradient(to bottom,
      rgba(246, 241, 231, 0.86) 0%,
      rgba(246, 241, 231, 0.62) 28%,
      rgba(246, 241, 231, 0.58) 62%,
      rgba(246, 241, 231, 0.88) 100%);
}
[data-theme="dark"] .hero__glass::after {
  background:
    linear-gradient(to bottom,
      rgba(14, 13, 10, 0.82) 0%,
      rgba(14, 13, 10, 0.54) 28%,
      rgba(14, 13, 10, 0.5) 62%,
      rgba(14, 13, 10, 0.86) 100%);
}

@media (prefers-reduced-motion: reduce) {
  .hero__glass canvas { display: none; }
  .hero__glass video { opacity: 0.35; }
}

/* ============================================================
   CLIENTS: quiet label, tight to the hero
   The logos are the content; a full section header competed with
   them and pushed the strip a screen away from the hero it belongs to.
   ============================================================ */
.section.clients {
  /* Sits directly under the hero, so it takes almost none of the
     standard section rhythm at the top. */
  padding-top: clamp(1rem, 2.5vh, 1.75rem);
  padding-bottom: var(--sp-5, 3rem);
}
.clients__note {
  margin: 0 0 clamp(0.9rem, 2vw, 1.4rem);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.45;
}

/* ============================================================
   HERO GLASS: full bleed
   .hero is capped at 1400px and centred, so an inset:0 child stops
   at that box and leaves bars either side on a wide display. Break
   the glass out to the viewport while the content stays in the grid.
   ============================================================ */
.hero__glass {
  left: 50%;
  right: auto;
  width: 100vw;
  max-width: 100vw;
  transform: translateX(-50%);
}

/* ============================================================
   FILM NOISE: heavier, and always moving
   Two layers doing different jobs. The ::after snaps on steps() , 
   that is the flicker, and it is what makes it read as grain sitting
   IN the image rather than a texture laid over it. The ::before
   drifts continuously underneath, so there is motion even between
   snaps and the frame never looks momentarily static.
   ============================================================ */
.section::after,
.manifesto::after {
  opacity: 0.30;
  animation-duration: 0.85s;
}
[data-theme="dark"] .section::after,
[data-theme="dark"] .manifesto::after,
.manifesto::after {
  opacity: 0.18;
}

.section::before,
.manifesto::before {
  content: "";
  position: absolute;
  inset: -140px;
  width: calc(100% + 280px);
  height: calc(100% + 280px);
  pointer-events: none;
  z-index: 2;
  opacity: 0.2;
  mix-blend-mode: overlay;
  background-image: var(--film-noise-fine);
  animation: film-drift 16s linear infinite;
}

@keyframes film-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-120px, 120px, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .section::before, .manifesto::before { animation: none; }
}

/* ============================================================
   Brand wordmark: scrolls away, not pinned
   The docked nav toggle already gives a persistent way home once
   you are down the page, so a second fixed logo is redundant chrome
   sitting over the content.
   ============================================================ */
.brand {
  position: absolute;
}

/* ============================================================
   100vw breakout without the scrollbar overflow
   100vw counts the scrollbar, so a full-bleed child is ~15px wider
   than the visible page and the body scrolls sideways. overflow-x:
   clip trims it WITHOUT creating a scroll container: unlike hidden,
   which would break every position:sticky element on the page,
   including the pinned reel.
   ============================================================ */
html, body { overflow-x: clip; }

/* ============================================================
   MOBILE  (≤ 720px)
   The desktop chrome is sized for a 1400px column. Dropped onto a
   390px screen the nav pill alone took 73% of the width and the body
   copy ran at 20.8px, so the hero needed a full screen of scrolling
   before it said anything. Everything below is about giving the
   words the room instead of the furniture.
   ============================================================ */
@media (max-width: 720px) {

  /* ---- nav: collapse to a compact control ---- */
  .navcard {
    top: 12px;
    right: var(--gutter);
    left: auto;
    width: auto;
    padding: 0.3rem;
    border-radius: 999px;
  }
  /* The CTA words and the service tags are desktop affordances. On a
     phone the burger is the control and the menu carries the CTA. */
  .navcard__ctatext,
  .navcard__arrow,
  .navcard__tags {
    display: none;
  }
  .navcard__top { gap: 0.25rem; }
  .navcard__cta { padding: 0; gap: 0; }
  .navcard__mark { width: 34px; height: 34px; border-radius: 999px; }
  .navcard__mark img { width: 21px; height: 21px; }
  .navcard__burger { width: 38px; height: 38px; }

  .navcard__menu {
    position: fixed;
    top: 68px; right: var(--gutter); left: var(--gutter);
    max-height: calc(100svh - 90px);
    overflow-y: auto;
  }
  [data-nav="docked"] .navcard__menu {
    top: auto; bottom: 68px;
  }

  /* ---- brand: smaller, quieter ---- */
  .brand { top: 14px; padding: 0.25rem 0.4rem; gap: 0.4rem; }
  .brand__mark { width: 28px; height: 28px; }
  .brand__word { font-size: 0.72rem; letter-spacing: 0.06em; }

  /* ---- hero: tighten so the headline lands above the fold ---- */
  .hero {
    min-height: auto;
    padding: calc(var(--header-h) + 1.5rem) var(--gutter) 2.5rem;
  }
  .hero__eyebrow { font-size: 0.62rem; letter-spacing: 0.16em; }
  .kinetic { font-size: clamp(2.4rem, 13vw, 3.4rem) !important; line-height: 0.94; }
  .hero__lower { gap: 1.6rem; }
  .hero__sub {
    font-size: 1rem;
    line-height: 1.55;
    max-width: 100%;
  }
  .hero__actions { gap: 0.6rem; }
  .btn { padding: 0.85rem 1.2rem; font-size: 0.92rem; }
  .hero__card { margin-top: 0.4rem; }

  /* ---- sections: consistent, tighter rhythm ---- */
  .section { padding: clamp(2.6rem, 9vw, 3.6rem) 0; }
  .section.clients { padding-top: 1.1rem; }
  .section__head { grid-template-columns: minmax(0, 1fr); gap: 0.7rem; }
  .section__title { font-size: clamp(1.85rem, 9vw, 2.5rem); line-height: 1.04; }
  .section__aside { font-size: 0.95rem; }
  .clients__note { font-size: 0.6rem; letter-spacing: 0.18em; }

  /* Logo strip scaled to the screen rather than the desktop cell size. */
  .logo-track .logo-cell { flex: 0 0 clamp(140px, 44vw, 178px); }
  .logo-cell { min-height: 116px; padding: 1rem 0.8rem; }

  /* ---- work reel (stacked fallback) ---- */
  .rinfo__title { font-size: clamp(1.9rem, 10vw, 2.6rem); }
  .rinfo__sub { font-size: 0.97rem; }
  .rinfo__meta { gap: 1.1rem; }
  .reel__frame { border-radius: 14px; }

  /* ---- manifesto ---- */
  .manifesto { padding-block: clamp(3rem, 12vw, 4.5rem); }
  .manifesto__body { font-size: 1rem; }

  /* ---- interior pages ---- */
  .phero__h1 { font-size: clamp(1.9rem, 9.5vw, 2.6rem); }
  .phero__lede { font-size: 1rem; }
  .qa__q { font-size: 1.02rem; }

  /* ---- footer ---- */
  .footer__cols { grid-template-columns: minmax(0, 1fr); gap: 1.8rem; }
}

/* Very narrow phones: stop the wordmark competing with the nav. */
@media (max-width: 380px) {
  .brand__word { display: none; }
}

/* On a phone the reel copy runs full width and left-aligned, so a pill
   docked bottom-left lands directly on top of the metadata and the CTA.
   Desktop keeps bottom-left, where there is a clear margin beside the
   two-column layout. */
@media (max-width: 720px) {
  [data-nav="docked"] .navcard {
    left: auto;
    right: clamp(1rem, 4vw, 1.6rem);
  }
  [data-nav="docked"] .navcard__menu {
    left: auto;
    /* Match the pill's own inset: flush to the viewport edge read as
       a panel that had slipped off the side. */
    right: clamp(1rem, 4vw, 1.6rem);
    width: min(74vw, 268px);
  }
}

/* Meta columns: plain blocks, not nested grids.
   As grid items inside a grid row they were being stretched to the tallest
   column, and their own inner grid then distributed that extra height , 
   pushing values out of line with their labels. align-self:start plus
   block layout removes both effects. */
.rinfo__meta > div {
  display: block;
  align-self: start;
}
.rinfo__meta dt { margin-bottom: 0.28rem; }
.rinfo__meta dd { margin: 0; }

/* ============================================================
   Nav menu: opaque, and above everything it overlaps
   It had no background at all and no stacking context of its own,
   so the page showed straight through it and interleaved with it.
   ============================================================ */
.navcard__menu {
  position: relative;
  z-index: 2;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  box-shadow: 0 18px 48px -12px rgba(0, 0, 0, 0.55);
}
@media (max-width: 720px) {
  .navcard__menu {
    position: fixed;
    z-index: 130;          /* above .navcard (120) and the grain (60) */
    background: var(--paper);
    padding: 1rem 1.1rem 1.2rem;
    box-shadow: 0 24px 60px -10px rgba(0, 0, 0, 0.7);
  }
}

/* ============================================================
   Brand wordmark: no chip behind it
   ============================================================ */
.brand {
  background: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: 0;
  border-radius: 0;
  padding: 0;
}

/* ============================================================
   Viewport units on the reel
   svh is the SMALL viewport (URL bar visible). Sizing the tall
   container in svh while the browser reports a larger viewport once
   the bar retracts leaves extra scrollable height at the end of the
   section. dvh tracks the live viewport, so the container and the
   sticky stage always agree.
   ============================================================ */
.reel { height: calc((var(--rf-count) + 1) * 100dvh); }
.reel__stage { height: 100dvh; }
@media (max-width: 900px) {
  .reel { height: calc((var(--rf-count) + 1) * 100dvh); }
  .reel__stage { height: 100dvh; }
}

/* ============================================================
   CLIENTS: logos on the ground, not on cards
   The cards existed to solve a real problem: several of these logos
   are black artwork on a transparent background, so they vanish on a
   dark section. A cream tile behind each one fixed the visibility and
   created a row of mismatched swatches.

   Rendering every logo as a flat white silhouette solves the same
   problem without the tiles, and has the side benefit of unifying a
   set drawn in wildly different palettes. Colour returns on hover.
   ============================================================ */
.logo-cell {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0 clamp(0.6rem, 1.6vw, 1.2rem);
  min-height: 0;
  height: clamp(56px, 7vw, 78px);
  transition: opacity 0.3s ease;
}
.logo-cell:hover {
  transform: none;
  box-shadow: none;
}
.logo-cell img {
  width: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  /* brightness(0) flattens any artwork to black, invert(1) lifts it to
     white: works regardless of the logo's original colours. */
  filter: brightness(0) invert(1);
  opacity: 0.52;
  transition: opacity 0.3s ease, filter 0.3s ease;
}
.logo-cell:hover img,
.logo-marquee:hover .logo-cell img {
  opacity: 0.78;
}
.logo-cell:hover img {
  opacity: 1;
}
/* The mark carries the name; a caption under each one turned the strip
   into a table. */
.logo-cell__name { display: none; }

/* Light theme: flatten to black instead of white. */
html[data-theme="light"] .logo-cell img { filter: brightness(0); }

.logo-track {
  align-items: center;
  gap: clamp(1.8rem, 5vw, 4rem);
}
.logo-track .logo-cell { flex: 0 0 auto; }

@media (max-width: 720px) {
  .logo-cell { height: clamp(42px, 11vw, 58px); padding-inline: 0.5rem; }
  .logo-track { gap: clamp(1.4rem, 7vw, 2.4rem); }
}

/* The viewfinder corner marks framed the old cards. With the cards gone
   they float around the artwork with nothing to register against. */
.logo-cell .vf-dot { display: none; }

/* The strip is a single row now, so it needs a row's worth of space,
   not a card grid's. */
.section.clients { padding-bottom: clamp(1.6rem, 4vw, 2.6rem); }
.logo-marquee { padding-block: clamp(0.4rem, 1.5vw, 0.9rem); }

/* ============================================================
   SERVICES: two pillars resolving into one engine
   The old layout was four equal cards, which flattened a real
   hierarchy: two halves that combine, plus two secondary paths.
   The plus sign and the summary band below carry that argument,
   so the structure of the section is the pitch.
   ============================================================ */
.engine {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: stretch;
  gap: clamp(1rem, 2.5vw, 2rem);
  margin-top: clamp(1.6rem, 4vw, 2.6rem);
}
.engine__plus {
  align-self: center;
  margin: 0;
  font-family: var(--font-display, sans-serif);
  font-size: clamp(1.6rem, 3vw, 2.6rem);
  font-weight: 800;
  line-height: 1;
  opacity: 0.32;
}

.pillar {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: clamp(1.4rem, 3vw, 2.2rem);
  border: 1px solid var(--line-strong);
  border-radius: 16px;
  background: var(--card-bg);
}
.pillar__idx {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  color: var(--accent, #e0403a);
}
.pillar__name {
  margin: 0;
  font-size: clamp(1.35rem, 2.6vw, 2rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-weight: 800;
}
.pillar__lead { margin: 0; line-height: 1.6; opacity: 0.82; }
.pillar__points {
  margin: 0.3rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.5rem;
  border-top: 1px solid var(--line-strong);
  padding-top: 0.9rem;
}
.pillar__points li {
  position: relative;
  padding-left: 1.05rem;
  font-size: 0.94rem;
  line-height: 1.45;
  opacity: 0.78;
}
.pillar__points li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent, #e0403a);
}
.pillar__link,
.alt__link {
  margin-top: auto;
  padding-top: 1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  text-decoration: none;
  color: inherit;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.pillar__link em,
.alt__link em {
  font-style: normal;
  transition: transform 0.3s cubic-bezier(0.19, 1, 0.22, 1);
}
.pillar__link:hover em,
.alt__link:hover em { transform: translateX(5px); }

/* The band that states what the two pillars add up to. */
.engine__sum {
  margin-top: clamp(1rem, 2.5vw, 1.6rem);
  padding: clamp(1.2rem, 3vw, 1.9rem);
  border: 1px solid var(--accent, #e0403a);
  border-radius: 16px;
  display: grid;
  gap: 0.4rem;
  text-align: center;
}
.engine__sum-label {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.64rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.6;
}
.engine__sum-name {
  margin: 0;
  font-size: clamp(1.5rem, 3.4vw, 2.4rem);
  font-weight: 800;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  color: var(--accent, #e0403a);
}
.engine__sum-note {
  margin: 0.2rem auto 0;
  max-width: 58ch;
  line-height: 1.55;
  opacity: 0.75;
  font-size: 0.96rem;
}

.alt-services {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: clamp(0.8rem, 2vw, 1.2rem);
  margin-top: clamp(1rem, 2.5vw, 1.6rem);
}
.alt {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: clamp(1.1rem, 2.4vw, 1.6rem);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
}
.alt__name { margin: 0; font-size: 1.1rem; font-weight: 700; }
.alt__copy { margin: 0; font-size: 0.94rem; line-height: 1.55; opacity: 0.75; }

@media (max-width: 860px) {
  .engine { grid-template-columns: minmax(0, 1fr); }
  .engine__plus { justify-self: center; padding-block: 0.2rem; }
}

/* Optical sizing. Constraining only by height let a wide wordmark render
   five times the width of a compact emblem: Jiffy Lube at 326px next to
   DOSC at 59px. Capping width as well brings them into the same weight
   class, which is what makes a logo strip read as a set. */
.logo-cell img {
  max-width: clamp(110px, 13vw, 175px);
  max-height: 100%;
}
/* Tall, near-square marks need more height to carry the same presence as a
   long horizontal wordmark. */
.logo-cell img[src*="cow-cat"] {
  max-height: 128%;
}
@media (max-width: 720px) {
  .logo-cell img { max-width: clamp(78px, 26vw, 120px); }
}

/* Sub-label under each pillar name: "Content & social" / "Web & search".
   The pillar names are the promise; these say what the work actually is. */
.pillar__kicker {
  margin: -0.5rem 0 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.5;
}

/* Who it's for. Qualifying the reader is what turns a capability list into
   an offer: without it every service sounds like it's for everyone. */
.pillar__who,
.alt__who {
  margin: 0.2rem 0 0;
  padding-top: 0.85rem;
  border-top: 1px solid var(--line-strong);
  font-size: 0.9rem;
  line-height: 1.5;
  opacity: 0.72;
}
.pillar__who span,
.alt__who span {
  display: block;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.58rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.6;
  margin-bottom: 0.3rem;
}
.alt__who {
  border-top: 0;
  padding-top: 0.2rem;
  font-style: italic;
  opacity: 0.6;
}
.alt__idx {
  margin: 0 0 0.1rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  opacity: 0.45;
}

/* ============================================================
   NAV MENU: grouped, full site
   Was four same-page anchors on the homepage and a different flat
   list elsewhere, so most of the site was unreachable depending on
   where you were standing. One grouped menu now ships on every page.
   ============================================================ */
.navmenu {
  display: grid;
  gap: 0.9rem;
}
.navmenu__group { display: grid; gap: 0.25rem; }
.navmenu__group-label {
  margin: 0 0 0.15rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.56rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.42;
}
.navmenu__list { margin: 0; padding: 0; list-style: none; display: grid; gap: 0.1rem; }
.navmenu__list a {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.3rem 0.4rem;
  margin-inline: -0.4rem;
  border-radius: 7px;
  text-decoration: none;
  color: inherit;
  transition: background 0.18s ease, opacity 0.18s ease;
}
.navmenu__list a:hover { background: var(--card-bg); }
.navmenu__idx {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.56rem;
  letter-spacing: 0.1em;
  opacity: 0.4;
  min-width: 1.3em;
}
.navmenu__label { font-size: 0.98rem; font-weight: 600; letter-spacing: -0.01em; }

/* The page you are on, marked rather than linked into the void. */
.navmenu__list li.is-here a { opacity: 0.55; }
.navmenu__list li.is-here .navmenu__label { color: var(--accent, #e0403a); opacity: 1; }

/* Thirteen links needs room; keep the panel scrollable rather than tall. */
.navcard__menu {
  width: min(84vw, 320px);
  max-height: min(72svh, 620px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
@media (max-width: 720px) {
  .navcard__menu { width: auto; max-height: calc(100svh - 110px); }
  [data-nav="docked"] .navcard__menu { width: min(74vw, 268px); }
  .navmenu { gap: 0.75rem; }
  .navmenu__label { font-size: 0.92rem; }
}

/* ============================================================
   NAV MENU: collapsed
   Thirteen rows at once was a wall. Six top-level rows, with the
   three category groups collapsing via <details> so the panel opens
   short and expands only where you ask. No JS: keyboard and screen
   readers get the disclosure behaviour for free.
   ============================================================ */
.navmenu { display: grid; gap: 0.1rem; }

.navmenu__top {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.55rem 0.5rem;
  margin-inline: -0.5rem;
  border-radius: 8px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  list-style: none;              /* kill the default marker */
  transition: background 0.16s ease;
}
.navmenu__top::-webkit-details-marker { display: none; }
.navmenu__top:hover { background: var(--card-bg); }
.navmenu__top .navmenu__label {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.012em;
}
.navmenu__chev {
  margin-left: auto;
  opacity: 0.45;
  transition: transform 0.25s cubic-bezier(0.19, 1, 0.22, 1);
}
.navmenu__group[open] > .navmenu__top .navmenu__chev { transform: rotate(180deg); }
.navmenu__group[open] > .navmenu__top { background: var(--card-bg); }

/* Children indent under their category and read one weight quieter. */
.navmenu__list {
  margin: 0.15rem 0 0.5rem;
  padding: 0 0 0 0.7rem;
  list-style: none;
  display: grid;
  gap: 0.05rem;
  border-left: 1px solid var(--line-strong);
}
.navmenu__list a {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  padding: 0.34rem 0.5rem;
  border-radius: 7px;
  text-decoration: none;
  color: inherit;
  transition: background 0.16s ease;
}
.navmenu__list a:hover { background: var(--card-bg); }
.navmenu__list .navmenu__label { font-size: 0.93rem; font-weight: 500; opacity: 0.85; }

.navmenu__idx {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.54rem;
  letter-spacing: 0.1em;
  opacity: 0.35;
  min-width: 1.3em;
}

.navmenu__top.is-here .navmenu__label,
.navmenu__list li.is-here .navmenu__label {
  color: var(--accent, #e0403a);
  opacity: 1;
}

/* Opens short now, so it rarely needs to scroll at all. */
.navcard__menu { width: min(80vw, 292px); max-height: min(76svh, 640px); }
@media (max-width: 720px) {
  .navcard__menu { width: auto; max-height: calc(100svh - 110px); }
  [data-nav="docked"] .navcard__menu { width: min(74vw, 268px); }
}

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

/* ============================================================
   Menu padding
   The rows carry margin-inline: -0.5rem so their hover fill bleeds
   past the text. That needs the panel to have horizontal padding to
   bleed INTO: without it the rows overflow the panel edge, which
   measured as -7px on desktop. Padding here is set to leave the fill
   comfortably inside and the text further in still.
   ============================================================ */
.navcard__menu {
  padding: 1.15rem 1.25rem 1.25rem;
}
.navmenu__top {
  padding: 0.6rem 0.55rem;
  margin-inline: -0.55rem;
}
.navmenu__list {
  margin: 0.2rem 0 0.65rem;
  padding-left: 0.85rem;
}
.navmenu__list a {
  padding: 0.4rem 0.55rem;
  margin-inline: -0.55rem;
}
/* The socials row and copyright sat hard against the bottom edge. */
.navcard__utils {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line-strong);
}
.navcard__copy { margin: 0.7rem 0 0; }

@media (max-width: 720px) {
  .navcard__menu { padding: 1.2rem 1.3rem 1.3rem; }
}

/* Socials + theme toggle: keep them on one line where they fit, and wrap
   as a unit rather than orphaning "Light mode" onto its own row. */
.navcard__utils {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem 1rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.63rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.navcard__utils a,
.navcard__utils button {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  opacity: 0.6;
  cursor: pointer;
  text-decoration: none;
  font: inherit;
  letter-spacing: inherit;
  transition: opacity 0.16s ease;
}
.navcard__utils a:hover,
.navcard__utils button:hover { opacity: 1; }

/* Indent + alignment fix.
   Removing the child index numbers also removed the width that was indenting
   them, so children sat level with their parent and the hierarchy vanished.
   And <a> vs <summary> defaults put Work 5px right of Services. Both are
   normalised here rather than left to element defaults. */
.navmenu__top {
  display: flex;
  box-sizing: border-box;
}
a.navmenu__top,
summary.navmenu__top {
  padding-left: 0.55rem;
  padding-right: 0.55rem;
}
.navmenu__list {
  /* Deep enough that the child block reads as contained by its heading. */
  padding-left: 1.75rem;
  margin-left: 0.15rem;
}
.navmenu__list a { margin-inline: -0.4rem; padding-inline: 0.4rem; }

/* base.css has `ul[role="list"] { margin: 0; padding: 0 }`: specificity
   (0,1,1), which outranks a bare `.navmenu__list` at (0,1,0) no matter how
   late it appears. That silently zeroed the child indent. Matching on the
   element as well brings this to (0,2,1) so it actually applies. */
.navmenu__group ul.navmenu__list {
  margin: 0.2rem 0 0.65rem;
  padding-left: 1.75rem;
}

/* ============================================================
   Client logo exceptions
   The strip renders logos as white silhouettes so a set drawn in
   different palettes reads as one row. Doing Tattoo is the exception:
   it is a detailed badge whose lettering is knocked out of the ring,
   and flattening it produced an unreadable disc. It keeps its own
   colour, desaturated slightly so it still sits with the others.
   ============================================================ */
/* Doing Tattoo is a detailed badge: flattening it to a silhouette produced
   an unreadable disc, so it keeps its artwork and goes monochrome instead.
   Brightness is lifted rather than inverted: the ring is the light element
   and the lettering is knocked out of it, so lifting keeps the design the
   right way round and readable against the dark ground. */
.logo-cell img[src*="doing-tattoo"] {
  filter: grayscale(1) brightness(1.55) contrast(1.1);
  opacity: 0.6;
}
.logo-cell:hover img[src*="doing-tattoo"] {
  filter: grayscale(1) brightness(1.7) contrast(1.1);
  opacity: 1;
}
html[data-theme="light"] .logo-cell img[src*="doing-tattoo"] {
  filter: grayscale(1) contrast(1.15) brightness(0.85);
}

/* Circular badges need more height than a horizontal wordmark to carry the
   same optical weight. Euphoria is no longer in this group: trimming its
   79% transparent margin made it a normal-proportioned wordmark. */
.logo-cell img[src*="cow-cat"],
.logo-cell img[src*="doing-tattoo"] {
  max-height: 132%;
}
.logo-cell img[src*="euphoria"] { max-height: 100%; }

/* ============================================================
   Client logos as links
   Each mark that has a case study links to it. A subtle lift only , 
   the strip is ambient, and a loud hover on a moving row is noise.
   ============================================================ */
.logo-cell__link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  text-decoration: none;
  color: inherit;
}
.logo-cell__link img {
  transition: opacity 0.28s ease, filter 0.28s ease;
}
/* Glow: a soft white bloom around the mark, nothing more. */
.logo-cell__link:hover img,
.logo-cell__link:focus-visible img {
  opacity: 1;
  filter: brightness(0) invert(1)
          drop-shadow(0 0 7px rgba(255, 255, 255, 0.55))
          drop-shadow(0 0 18px rgba(255, 255, 255, 0.25));
}
/* Doing Tattoo keeps its own monochrome treatment, so it needs its own
   hover rather than inheriting the silhouette filter above. */
.logo-cell__link:hover img[src*="doing-tattoo"],
.logo-cell__link:focus-visible img[src*="doing-tattoo"] {
  filter: grayscale(1) brightness(1.7) contrast(1.1)
          drop-shadow(0 0 7px rgba(255, 255, 255, 0.45))
          drop-shadow(0 0 18px rgba(255, 255, 255, 0.2));
}
html[data-theme="light"] .logo-cell__link:hover img {
  filter: brightness(0) drop-shadow(0 0 8px rgba(0, 0, 0, 0.3));
}
.logo-cell__link:focus-visible { outline: 2px solid var(--accent, #e0403a); outline-offset: 6px; border-radius: 8px; }

/* Hovering a logo also hovers the strip, so `.logo-marquee:hover .logo-cell img`
   (0,3,1) outranks a plain `.logo-cell__link:hover img` (0,2,1) and would win
   the opacity. Scoping the hover under .logo-marquee brings it to (0,4,1). */
.logo-marquee .logo-cell__link:hover img,
.logo-marquee .logo-cell__link:focus-visible img {
  opacity: 1;
  filter: brightness(0) invert(1)
          drop-shadow(0 0 7px rgba(255, 255, 255, 0.55))
          drop-shadow(0 0 18px rgba(255, 255, 255, 0.25));
}
.logo-marquee .logo-cell__link:hover img[src*="doing-tattoo"],
.logo-marquee .logo-cell__link:focus-visible img[src*="doing-tattoo"] {
  opacity: 1;
  filter: grayscale(1) brightness(1.7) contrast(1.1)
          drop-shadow(0 0 7px rgba(255, 255, 255, 0.45))
          drop-shadow(0 0 18px rgba(255, 255, 255, 0.2));
}
html[data-theme="light"] .logo-marquee .logo-cell__link:hover img {
  filter: brightness(0) drop-shadow(0 0 8px rgba(0, 0, 0, 0.3));
}

/* ============================================================
   Logo sizing: nothing exceeds its cell
   The >100% max-heights on the circular badges were overflowing the
   78px cell by 25px, and the marquee's overflow:clip cropped them.
   Everything fits inside now; the cell is a little taller so the
   round marks still carry weight without breaking out.
   ============================================================ */
.logo-cell { height: clamp(60px, 7.6vw, 88px); }
.logo-cell img,
.logo-cell img[src*="cow-cat"],
.logo-cell img[src*="doing-tattoo"],
.logo-cell img[src*="euphoria"] {
  max-height: 100%;
  max-width: clamp(115px, 13.5vw, 182px);
}
/* The link is a hit area, not a layout box: it must not resize the mark. */
.logo-cell__link {
  width: auto;
  height: 100%;
  max-width: 100%;
}
@media (max-width: 720px) {
  .logo-cell { height: clamp(46px, 12vw, 62px); }
  .logo-cell img,
  .logo-cell img[src*="cow-cat"],
  .logo-cell img[src*="doing-tattoo"],
  .logo-cell img[src*="euphoria"] { max-width: clamp(80px, 27vw, 124px); }
}



/* ============================================================
   WEBSITE PORTFOLIO: archive drawer
   Panels overlap like files pulled part-way out of a drawer, each
   with a rotated index tab. Hovering pulls one forward. Screenshots
   rather than live iframes: four of these sites send X-Frame-Options
   or frame-ancestors, so a third of the row would be an empty box.
   ============================================================ */
.sites {
  padding: clamp(1.2rem, 3vw, 2rem) 0 clamp(2rem, 5vw, 3rem);
  border-bottom: 1px solid var(--line-strong);
}
.sites__head {
  margin-top: clamp(1.4rem, 3.5vw, 2.2rem);
  max-width: 60rem;
  margin-inline: auto;
  padding-inline: clamp(1rem, 5vw, 2.6rem);
  display: grid;
  gap: 0.8rem;
}
.sites__kicker {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.64rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--accent, #e0403a);
}
.sites__title {
  margin: 0;
  font-size: clamp(2rem, 5.4vw, 3.6rem);
  line-height: 1.02; letter-spacing: -0.03em; font-weight: 800;
}
.sites__title em { font-style: italic; color: var(--accent, #e0403a); }
.sites__note { margin: 0; max-width: 52ch; line-height: 1.55; opacity: 0.72; }

/* The drawer scrolls horizontally: a row of overlapping files is the
   whole idea, and stacking them vertically would lose it. */
.filedrawer {
  display: flex;
  gap: 0;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  padding: 0 clamp(1rem, 5vw, 2.6rem) 1.4rem;
  scrollbar-width: thin;
}
.filedrawer::-webkit-scrollbar { height: 6px; }
.filedrawer::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 99px; }

.filecard {
  flex: 0 0 auto;
  scroll-snap-align: center;
  /* Negative margin creates the overlap. Kept to roughly the tab width:
     at -121px each card hid a third of its own copy behind the next file,
     which looked like the drawer idea and read like a bug. */
  margin-left: clamp(-62px, -4.4vw, -40px);
  transition: margin 0.45s cubic-bezier(0.19, 1, 0.22, 1);
}
.filecard:first-child { margin-left: 0; }
.filecard:hover, .filecard:focus-within { margin-right: clamp(40px, 4.4vw, 62px); }

.filecard__link {
  display: flex;
  text-decoration: none;
  color: inherit;
  height: clamp(320px, 46vh, 460px);
}

/* Rotated index tab: the spine of the file. */
.filecard__tab {
  flex: 0 0 auto;
  width: clamp(34px, 3.4vw, 44px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.2rem;
  padding: 1rem 0;
  writing-mode: vertical-rl;
  background: var(--card-bg);
  border: 1px solid var(--line-strong);
  border-right: 0;
  border-radius: 12px 0 0 12px;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  transition: background 0.35s ease, color 0.35s ease;
}
.filecard__code { opacity: 0.45; }
.filecard__tabname { font-weight: 600; }
.filecard__link:hover .filecard__tab,
.filecard__link:focus-visible .filecard__tab {
  background: var(--accent, #e0403a);
  color: #fff;
}

.filecard__body {
  width: clamp(280px, 34vw, 420px);
  display: grid;
  grid-template-rows: 1fr auto;
  border: 1px solid var(--line-strong);
  border-radius: 0 12px 12px 0;
  overflow: hidden;
  background: var(--paper);
  box-shadow: -14px 0 34px -22px rgba(0, 0, 0, 0.8);
  transition: box-shadow 0.4s ease, border-color 0.3s ease;
}
.filecard__link:hover .filecard__body { border-color: var(--accent, #e0403a); }

.filecard__shot { position: relative; overflow: hidden; background: var(--ink); }
.filecard__shot img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: top center;
  transition: transform 0.8s cubic-bezier(0.19, 1, 0.22, 1);
}
.filecard__link:hover .filecard__shot img { transform: scale(1.04); }

.filecard__meta {
  display: grid;
  gap: 0.3rem;
  padding: 0.9rem 1rem 1rem;
  /* Right inset clears the slice of this card that the next file covers,
     so no line of copy is ever half-hidden behind a neighbour. */
  padding-right: clamp(3.4rem, 5.6vw, 4.6rem);
  border-top: 1px solid var(--line-strong);
}
.filecard__url {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.58rem; letter-spacing: 0.06em; opacity: 0.45;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.filecard__name { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; }
.filecard__sector {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.55rem; letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.5;
}
.filecard__note { font-size: 0.84rem; line-height: 1.45; opacity: 0.68; }
.filecard__cta {
  margin-top: 0.35rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.75;
  display: inline-flex; align-items: center; gap: 0.4rem;
}
.filecard__cta em { font-style: normal; transition: transform 0.3s cubic-bezier(0.19,1,0.22,1); }
.filecard__link:hover .filecard__cta em { transform: translate(3px, -3px); }

@media (max-width: 720px) {
  /* Overlap at phone width leaves almost nothing of each card visible. */
  .filecard { margin-left: 0; }
  .filecard:hover, .filecard:focus-within { margin-right: 0; }
  .filedrawer { gap: 0.9rem; }
  .filecard__link { height: clamp(300px, 58vh, 400px); }
  .filecard__body { width: min(78vw, 320px); }
}

@media (prefers-reduced-motion: reduce) {
  .filecard, .filecard__shot img, .filecard__cta em, .filecard__body { transition: none; }
}

@media (max-width: 720px) {
  /* No overlap at phone width, so no inset needed either. */
  .filecard__meta { padding-right: 1rem; }
}

/* ============================================================
   WEBSITES STRIP (homepage)
   Sits under the work reel and answers it: the reel shows what gets
   people looking, this shows what they land on. Same marquee grammar
   as the client-logo row, so it reads as part of the page rather than
   a bolted-on portfolio.
   ============================================================ */
.section.websites { padding-bottom: clamp(2rem, 5vw, 3.4rem); }

.webstrip {
  position: relative;
  overflow: clip;
  margin-top: clamp(1.4rem, 3.5vw, 2.4rem);
  /* Feather both ends so cards enter and leave rather than popping. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
}
.webtrack {
  display: flex;
  width: max-content;
  gap: clamp(1rem, 2vw, 1.6rem);
  margin: 0; padding: 0.4rem 0 1rem;
  list-style: none;
  animation: web-scroll 72s linear infinite;
  will-change: transform;
}
@keyframes web-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
/* Stop it so a card can actually be read and clicked. */
.webstrip:hover .webtrack,
.webstrip:focus-within .webtrack { animation-play-state: paused; }

.webcard { flex: 0 0 clamp(260px, 27vw, 380px); }
.webcard__link { display: grid; gap: 0.6rem; text-decoration: none; color: inherit; }

.webcard__frame {
  display: block;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  overflow: hidden;
  background: var(--card-bg);
  transition: transform 0.5s cubic-bezier(0.19, 1, 0.22, 1),
              border-color 0.35s ease, box-shadow 0.5s ease;
}
.webcard__bar {
  display: flex; align-items: center; gap: 0.45rem;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--line-strong);
  background: color-mix(in srgb, var(--ink) 55%, transparent);
}
.webcard__bar i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.25; }
.webcard__bar span {
  margin-left: 0.3rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.55rem; letter-spacing: 0.05em; opacity: 0.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.webcard__shot { position: relative; display: block; aspect-ratio: 16 / 10; overflow: hidden; background: var(--ink); }
.webcard__shot img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: top center;
  transition: transform 0.9s cubic-bezier(0.19, 1, 0.22, 1);
}
.webcard__link:hover .webcard__frame,
.webcard__link:focus-visible .webcard__frame {
  transform: translateY(-6px);
  border-color: var(--accent, #e0403a);
  box-shadow: 0 22px 46px -22px rgba(0, 0, 0, 0.7);
}
.webcard__link:hover .webcard__shot img { transform: scale(1.05); }

.webcard__meta { display: flex; align-items: baseline; justify-content: space-between; gap: 0.7rem; }
.webcard__name { font-size: 0.95rem; font-weight: 700; }
.webcard__sector {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.54rem; letter-spacing: 0.15em; text-transform: uppercase; opacity: 0.45;
}

.websites__cta {
  display: inline-flex; align-items: center; gap: 0.5rem;
  margin-top: clamp(0.8rem, 2vw, 1.4rem);
  padding: 0.75rem 1.3rem; border-radius: 999px;
  border: 1px solid var(--line-strong); text-decoration: none; color: inherit;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.68rem; letter-spacing: 0.15em; text-transform: uppercase;
  transition: background 0.3s ease, color 0.3s ease;
}
.websites__cta:hover { background: var(--ink); color: var(--paper); }
.websites__cta em { font-style: normal; transition: transform 0.3s cubic-bezier(0.19,1,0.22,1); }
.websites__cta:hover em { transform: translateX(5px); }

@media (max-width: 720px) {
  .webcard { flex: 0 0 clamp(210px, 62vw, 280px); }
  .webtrack { animation-duration: 52s; }
}
@media (prefers-reduced-motion: reduce) {
  .webtrack { animation: none; }
  .webstrip { overflow-x: auto; }
}

/* The work reel and the websites strip are one argument: what gets people
   looking, then what they land on. Two full section paddings stacked between
   them (112px + 112px) read as a break in that thought. Tightened at this
   junction only; every other section keeps the standard rhythm. */
.section.work { padding-bottom: clamp(1.4rem, 3.4vw, 3.4rem); }
.section.websites { padding-top: clamp(1.4rem, 3.4vw, 3.4rem); }

/* ============================================================
   BOOKING PAGE
   The scheduler sits as high as it can. Everything under it exists
   for someone who scrolled past instead of booking: reassurance,
   then proof, then the ways to reach us that are not a calendar.
   ============================================================ */
.booking {
  max-width: 62rem;
  margin-inline: auto;
  padding: clamp(0.5rem, 2vw, 1.2rem) clamp(1rem, 5vw, 2.6rem) clamp(1.6rem, 4vw, 2.6rem);
}
.booking__frame {
  border: 1px solid var(--line-strong);
  border-radius: 16px;
  overflow: hidden;
  background: var(--card-bg);
  /* Calendly sets its own height inline; this keeps the box from
     collapsing to nothing while the widget script is still loading. */
  min-height: 700px;
}
.booking__fallback {
  margin: 0;
  padding: clamp(1.4rem, 4vw, 2.4rem);
  line-height: 1.6;
}
.booking__fallback a { color: var(--accent, #e0403a); }

/* Three promises, numbered because they are a sequence: reply, call, quote. */
.promises {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: clamp(0.9rem, 2vw, 1.4rem);
  max-width: 62rem;
  margin-inline: auto;
  padding: 0 clamp(1rem, 5vw, 2.6rem) clamp(1.6rem, 4vw, 2.4rem);
}
.promise {
  display: grid;
  gap: 0.4rem;
  align-content: start;
  padding: clamp(1rem, 2.4vw, 1.4rem);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
}
.promise__n {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6rem; letter-spacing: 0.2em;
  color: var(--accent, #e0403a);
}
.promise__h { margin: 0; font-size: 1rem; font-weight: 700; line-height: 1.25; }
.promise__p { margin: 0; font-size: 0.9rem; line-height: 1.5; opacity: 0.7; }

/* Proof rows: work and websites, scrollable rather than stacked, so they
   stay a glance rather than another page of scrolling before the CTA. */
.proof {
  max-width: 1240px;
  margin-inline: auto;
  padding: clamp(1rem, 2.5vw, 1.6rem) 0;
}
.proof__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  padding: 0 clamp(1rem, 5vw, 2.6rem) 0.9rem;
}
.proof__h {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.68rem; letter-spacing: 0.2em; text-transform: uppercase;
  opacity: 0.55; font-weight: 500;
}
.proof__all {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.64rem; letter-spacing: 0.14em; text-transform: uppercase;
  text-decoration: none; color: inherit; opacity: 0.7;
}
.proof__all:hover { opacity: 1; color: var(--accent, #e0403a); }

.proof__row {
  display: flex;
  gap: clamp(0.7rem, 1.6vw, 1.1rem);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: 0 clamp(1rem, 5vw, 2.6rem) 0.6rem;
  scrollbar-width: thin;
}
.proof__row::-webkit-scrollbar { height: 5px; }
.proof__row::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 99px; }

.proof__card {
  flex: 0 0 clamp(140px, 20vw, 200px);
  scroll-snap-align: start;
  display: grid;
  gap: 0.4rem;
  text-decoration: none;
  color: inherit;
}
.proof__card--site { flex-basis: clamp(200px, 27vw, 268px); }
.proof__media {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  border-radius: 11px;
  border: 1px solid var(--line-strong);
  background: var(--ink);
  transition: border-color 0.3s ease, transform 0.4s cubic-bezier(0.19, 1, 0.22, 1);
}
.proof__media--site { aspect-ratio: 16 / 10; }
.proof__media video, .proof__media img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: top center;
}
.proof__card:hover .proof__media {
  transform: translateY(-3px);
  border-color: var(--accent, #e0403a);
}
.proof__name { font-size: 0.9rem; font-weight: 600; }
.proof__tag {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.55rem; letter-spacing: 0.12em; text-transform: uppercase; opacity: 0.45;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

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

/* ============================================================
   FAQ ACCORDION
   Answers stay in the served HTML for crawlers and answer engines,
   but a reader sees a list of questions instead of a page of prose.
   Native <details>, so keyboard and screen-reader behaviour is free
   and it still works with JavaScript off.
   ============================================================ */
.faq {
  max-width: 60rem;
  margin-inline: auto;
  padding: clamp(1.4rem, 3.5vw, 2.4rem) clamp(1rem, 5vw, 2.6rem);
}
.faq__head {
  margin: 0 0 1.1rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase;
  opacity: 0.55; font-weight: 500;
}
.faq__list { display: grid; border-top: 1px solid var(--line-strong); }
.faq__item { border-bottom: 1px solid var(--line-strong); }

.faq__q {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 1.2rem;
  padding: 1.05rem 0.2rem;
  cursor: pointer;
  list-style: none;
  font-size: clamp(0.98rem, 1.5vw, 1.1rem);
  font-weight: 600;
  line-height: 1.35;
  transition: color 0.2s ease;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:hover { color: var(--accent, #e0403a); }
.faq__chev {
  flex: 0 0 auto; margin-top: 0.3em; opacity: 0.45;
  transition: transform 0.28s cubic-bezier(0.19, 1, 0.22, 1);
}
.faq__item[open] > .faq__q .faq__chev { transform: rotate(180deg); }
.faq__item[open] > .faq__q { color: var(--accent, #e0403a); }

.faq__a { padding: 0 2.4rem 1.15rem 0.2rem; }
.faq__a p { margin: 0; line-height: 1.65; opacity: 0.82; max-width: 62ch; }

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

/* The collective claim sits between the two pillars and the smaller offers,
   because it applies to all of them and is the reason to use us over hiring
   a camera operator for the day. */
.collective {
  margin-top: clamp(1rem, 2.5vw, 1.6rem);
  padding: clamp(1.2rem, 3vw, 1.9rem);
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--accent, #e0403a);
  border-radius: 0 14px 14px 0;
  display: grid;
  gap: 0.5rem;
}
.collective__label {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--accent, #e0403a);
}
.collective__copy {
  margin: 0; max-width: 68ch; line-height: 1.65;
  font-size: clamp(0.98rem, 1.5vw, 1.08rem);
}

/* ============================================================
   SERVICES BRIEF
   A four-line summary near the top, before the longer two-pillar
   argument. Someone who lands cold needs to know what is on the menu
   before they are asked to follow a thesis about how it fits together.
   ============================================================ */
.briefs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  gap: clamp(0.8rem, 2vw, 1.2rem);
  margin: clamp(1.4rem, 3vw, 2.2rem) 0 0;
  padding: 0; list-style: none;
}
.brief-card {
  display: flex; flex-direction: column; gap: 0.5rem;
  padding: clamp(1.1rem, 2.4vw, 1.6rem);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  transition: border-color 0.3s ease, transform 0.4s cubic-bezier(0.19, 1, 0.22, 1);
}
.brief-card:hover { border-color: var(--accent, #e0403a); transform: translateY(-3px); }
.brief-card__n {
  margin: 0; font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6rem; letter-spacing: 0.2em; color: var(--accent, #e0403a);
}
.brief-card__h {
  margin: 0; font-size: clamp(1.05rem, 1.8vw, 1.25rem); font-weight: 800;
  line-height: 1.15; letter-spacing: -0.015em;
}
.brief-card__p { margin: 0; font-size: 0.92rem; line-height: 1.55; opacity: 0.75; }
.brief-card__a {
  margin-top: auto; padding-top: 0.7rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase;
  text-decoration: none; color: inherit;
  display: inline-flex; align-items: center; gap: 0.4rem;
}
.brief-card__a em { font-style: normal; transition: transform 0.3s cubic-bezier(0.19,1,0.22,1); }
.brief-card:hover .brief-card__a em { transform: translateX(4px); }

@media (prefers-reduced-motion: reduce) {
  .brief-card, .consult__btn { transition: none; }
}

/* ============================================================
   FREE CONSULT
   Form left, argument right. The ask comes first because someone
   already sold should not have to scroll past persuasion to reach it.
   ============================================================ */
.consult__inner {
  max-width: var(--shell-max, 1240px);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: clamp(1.6rem, 4vw, 3.4rem);
  align-items: start;
}

.consult__form {
  border: 1px solid var(--line-strong);
  border-radius: 18px;
  overflow: hidden;
  background: var(--card-bg);
}
.consult__formhead {
  padding: clamp(1.2rem, 2.6vw, 1.7rem);
  background: var(--accent, #e0403a);
  color: #fff;
  display: grid;
  gap: 0.3rem;
}
.consult__formkicker {
  margin: 0;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6rem; letter-spacing: 0.2em; text-transform: uppercase; opacity: 0.85;
}
.consult__formsub { margin: 0; font-size: 1.02rem; font-weight: 600; line-height: 1.35; }
.consult__fields { display: grid; gap: 0.75rem; padding: clamp(1.1rem, 2.6vw, 1.6rem); }

.consult__hp { position: absolute; left: -9999px; opacity: 0; pointer-events: none; }
.field { display: grid; gap: 0.3rem; }
.field label {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.56rem; letter-spacing: 0.14em; text-transform: uppercase; opacity: 0.6;
}
.field input, .field select, .field textarea {
  width: 100%; padding: 0.68rem 0.75rem;
  border: 1px solid var(--line-strong); border-radius: 10px;
  background: var(--paper); color: var(--ink);
  font-size: 0.95rem;
  transition: border-color 0.2s ease;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent, #e0403a);
}
.field input[aria-invalid="true"] { border-color: var(--accent, #e0403a); }

.consult__btn {
  margin-top: 0.25rem; padding: 0.9rem 1.4rem;
  border: 0; border-radius: 999px;
  background: var(--accent, #e0403a); color: #fff;
  font-weight: 700; font-size: 1rem; cursor: pointer;
  transition: transform 0.25s cubic-bezier(0.19, 1, 0.22, 1), opacity 0.2s ease;
}
.consult__btn:hover { transform: translateY(-2px); }
.consult__btn[disabled] { opacity: 0.55; cursor: default; transform: none; }
.consult__note { margin: 0; font-size: 0.76rem; opacity: 0.6; line-height: 1.45; }
.consult__note[data-state="ok"] { color: var(--accent, #e0403a); opacity: 1; font-weight: 600; }
.consult__note[data-state="err"] { color: var(--accent, #e0403a); opacity: 1; }

.consult__copy { display: grid; gap: 0.9rem; align-content: start; }
.consult__h {
  margin: 0;
  font-size: clamp(1.8rem, 4.2vw, 3.1rem);
  line-height: 1.02; letter-spacing: -0.03em; font-weight: 800;
}
.consult__h em { font-style: italic; color: var(--accent, #e0403a); }
.consult__lede { margin: 0; line-height: 1.6; opacity: 0.82; max-width: 52ch; }

.consult__boxes { margin: 0.3rem 0 0; padding: 0; list-style: none; display: grid; gap: 0.6rem; }
.cbox {
  display: flex; align-items: center; gap: 0.9rem;
  padding: 0.85rem 1rem;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  transition: border-color 0.25s ease;
}
.cbox:hover { border-color: var(--accent, #e0403a); }
.cbox__ico {
  flex: 0 0 auto; width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent, #e0403a) 16%, transparent);
  color: var(--accent, #e0403a);
}
.cbox__ico svg { width: 17px; height: 17px; }
.cbox__t { font-size: 0.93rem; line-height: 1.4; font-weight: 500; }

@media (max-width: 900px) {
  .consult__inner { grid-template-columns: minmax(0, 1fr); }
  /* Argument first on a phone: the form is a long scroll and nobody
     fills one in before they know what they are getting. */
  .consult__copy { order: -1; }
}
@media (prefers-reduced-motion: reduce) {
  .consult__btn, .cbox { transition: none; }
}

/* ============================================================
   INSIGHTS: blog teaser rail + /blog grid
   Cards carry a still, a byline, the headline and one line of the
   argument, which is the minimum needed to decide whether to read.
   ============================================================ */
.insights__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap;
}
.insights__title {
  margin: 0; font-size: clamp(1.7rem, 4vw, 3rem);
  line-height: 1.04; letter-spacing: -0.03em; font-weight: 800;
}
.insights__title em { font-style: italic; color: var(--accent, #e0403a); }
.insights__nav { display: flex; gap: 0.5rem; }
.insights__arrow {
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1px solid var(--line-strong); background: none; color: inherit;
  cursor: pointer; transition: background 0.25s ease, color 0.25s ease, opacity 0.2s ease;
}
.insights__arrow svg { width: 16px; height: 16px; }
.insights__arrow:hover { background: var(--accent, #e0403a); color: #fff; border-color: var(--accent, #e0403a); }
.insights__arrow[disabled] { opacity: 0.3; cursor: default; }
.insights__arrow[disabled]:hover { background: none; color: inherit; border-color: var(--line-strong); }

.prail {
  display: flex; gap: clamp(0.8rem, 2vw, 1.3rem);
  overflow-x: auto; scroll-snap-type: x proximity; scroll-behavior: smooth;
  padding: clamp(1.2rem, 3vw, 2rem) var(--gutter) 0.8rem;
  scrollbar-width: none;
}
.prail::-webkit-scrollbar { display: none; }
.prail .pcard { flex: 0 0 clamp(250px, 30vw, 330px); scroll-snap-align: start; }

.pgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: clamp(1rem, 2.4vw, 1.6rem);
  max-width: var(--shell-max, 1240px);
  margin-inline: auto;
  padding: clamp(1rem, 3vw, 2rem) clamp(1rem, 5vw, 2.6rem) 3rem;
}

.pcard__link { display: grid; gap: 0; text-decoration: none; color: inherit; height: 100%; }
.pcard__thumb {
  position: relative; display: block; aspect-ratio: 16 / 10;
  overflow: hidden; border-radius: 12px 12px 0 0; background: var(--ink);
}
.pcard__thumb img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 30%;
  transition: transform 0.8s cubic-bezier(0.19, 1, 0.22, 1);
}
.pcard__link:hover .pcard__thumb img { transform: scale(1.05); }
.pcard__kicker {
  position: absolute; left: 0.7rem; top: 0.7rem; z-index: 2;
  padding: 0.28rem 0.6rem; border-radius: 999px;
  background: var(--accent, #e0403a); color: #fff;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.54rem; letter-spacing: 0.14em; text-transform: uppercase;
}
.pcard__body {
  display: grid; gap: 0.4rem; align-content: start;
  padding: 1rem 1.05rem 1.15rem;
  border: 1px solid var(--line-strong); border-top: 0;
  border-radius: 0 0 12px 12px;
  background: var(--card-bg);
  height: 100%;
}
.pcard__by {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.54rem; letter-spacing: 0.13em; text-transform: uppercase; opacity: 0.5;
}
.pcard__title { font-size: 1.02rem; font-weight: 700; line-height: 1.25; }
.pcard__ex { font-size: 0.88rem; line-height: 1.5; opacity: 0.7; }
.pcard__more {
  margin-top: 0.35rem;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--accent, #e0403a);
}
.insights__all {
  display: inline-flex; align-items: center; gap: 0.5rem;
  margin-top: clamp(0.6rem, 2vw, 1.2rem);
  padding: 0.75rem 1.3rem; border-radius: 999px;
  border: 1px solid var(--line-strong); text-decoration: none; color: inherit;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.68rem; letter-spacing: 0.15em; text-transform: uppercase;
  transition: background 0.3s ease, color 0.3s ease;
}
.insights__all:hover { background: var(--ink); color: var(--paper); }
.insights__all em { font-style: normal; }

/* ---- article ---- */
.post { max-width: 44rem; margin-inline: auto; padding: clamp(4rem, 10vh, 6rem) clamp(1rem, 5vw, 2.6rem) 3rem; }
.post__head { display: grid; gap: 0.7rem; margin-bottom: clamp(1.4rem, 3vw, 2.2rem); }
.post__kicker {
  margin: 0; font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--accent, #e0403a);
}
.post__h1 {
  margin: 0; font-size: clamp(1.9rem, 5vw, 3.1rem);
  line-height: 1.05; letter-spacing: -0.03em; font-weight: 800; text-wrap: balance;
}
.post__meta {
  margin: 0; font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.62rem; letter-spacing: 0.12em; text-transform: uppercase; opacity: 0.5;
}
.post__body { display: grid; gap: 1.15rem; }
.post__body p { margin: 0; line-height: 1.75; font-size: 1.03rem; opacity: 0.88; }
.post__body h2 {
  margin: 1rem 0 -0.2rem; font-size: clamp(1.2rem, 2.4vw, 1.5rem);
  font-weight: 800; letter-spacing: -0.018em; line-height: 1.25;
}
.post__body strong { font-weight: 700; opacity: 1; }

.post__cta {
  margin-top: clamp(2rem, 5vw, 3rem);
  padding: clamp(1.3rem, 3vw, 2rem);
  border: 1px solid var(--accent, #e0403a); border-radius: 16px;
  display: grid; gap: 0.5rem; justify-items: start;
}
.post__ctah { margin: 0; font-size: 1.2rem; font-weight: 800; }
.post__ctap { margin: 0; opacity: 0.8; line-height: 1.55; }
.post__ctab {
  margin-top: 0.5rem; padding: 0.8rem 1.35rem; border-radius: 999px;
  background: var(--accent, #e0403a); color: #fff; text-decoration: none;
  font-weight: 700; font-size: 0.95rem;
  display: inline-flex; align-items: center; gap: 0.45rem;
}
.post__ctab em { font-style: normal; transition: transform 0.3s cubic-bezier(0.19,1,0.22,1); }
.post__ctab:hover em { transform: translateX(4px); }

.post__next { margin-top: clamp(1.6rem, 4vw, 2.4rem); }
.post__next a {
  display: grid; gap: 0.3rem; padding: 1.1rem 1.3rem;
  border: 1px solid var(--line-strong); border-radius: 14px;
  text-decoration: none; color: inherit;
  transition: border-color 0.25s ease;
}
.post__next a:hover { border-color: var(--accent, #e0403a); }
.post__nextl {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.58rem; letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.5;
}
.post__nextt { font-size: 1.05rem; font-weight: 700; line-height: 1.3; }

@media (prefers-reduced-motion: reduce) {
  .prail { scroll-behavior: auto; }
  .pcard__thumb img, .insights__arrow { transition: none; }
}

/* scroll-snap-align: start measures from the scrollport edge, not from the
   content box, so the container's inline padding pushed the first card's snap
   position 56px in and the rail rested at scrollLeft 56 instead of 0. Telling
   the scrollport about the padding makes zero a valid snap position again,
   which is what the prev arrow's disabled state depends on. */
.prail { scroll-padding-inline: var(--gutter); }
.proof__row { scroll-padding-inline: clamp(1rem, 5vw, 2.6rem); }

/* Post banner. Sits above the headline and is the page's largest paint, so
   it is eager and high priority rather than lazy: a hero image that fades in
   late is a layout shift the reader watches happen. */
.post__banner {
  margin: 0 0 clamp(1.4rem, 3vw, 2.2rem);
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  aspect-ratio: 1200 / 750;
  background: var(--ink);
}
.post__banner img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* The banner is full-bleed within the article column, so the article needs
   its top padding back to clear the fixed nav. */
.post { padding-top: clamp(5rem, 12vh, 7rem); }

/* The work grid sat inside .pbody, which is capped at 60rem for readable
   prose. That is right for paragraphs and wrong for a gallery: on a wide
   screen it fitted two columns and left a third of the page empty. */
.pbody:has(> .film-grid) {
  max-width: var(--shell-max, 1240px);
}
.film-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr));
}

/* ============================================================
   PLACES WE TRAVEL TO
   Five regions, each a column. Town names read as chips rather than
   a bulleted list: this is a coverage map, not prose, and forty
   bullets stacked vertically is a wall nobody reads.
   ============================================================ */
.towns {
  max-width: var(--shell-max, 1240px);
  margin-inline: auto;
  padding: clamp(1.4rem, 3.5vw, 2.4rem) clamp(1rem, 5vw, 2.6rem);
}
.towns__note {
  margin: -0.4rem 0 clamp(1.2rem, 3vw, 1.8rem);
  max-width: 62ch;
  font-size: 0.92rem;
  line-height: 1.55;
  opacity: 0.65;
}
/* Explicit column counts rather than auto-fit: there are five regions, and
   auto-fit produced four across with one orphaned underneath. Five on a wide
   screen reads as a legend; three then two also balances. */
.towns__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 215px), 1fr));
  gap: clamp(0.9rem, 2vw, 1.4rem);
}
@media (min-width: 1180px) {
  .towns__grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
@media (min-width: 720px) and (max-width: 1179px) {
  .towns__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.towns__group {
  display: grid;
  gap: 0.75rem;
  align-content: start;
  padding: clamp(1rem, 2.2vw, 1.35rem);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  background: var(--card-bg);
}
.towns__h {
  margin: 0;
  padding-bottom: 0.65rem;
  border-bottom: 1px solid var(--line-strong);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent, #e0403a);
  font-weight: 500;
}
.towns__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.towns__list li {
  padding: 0.28rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  font-size: 0.8rem;
  line-height: 1.3;
  opacity: 0.82;
  white-space: nowrap;
}

@media (max-width: 560px) {
  .towns__group { padding: 0.9rem 1rem; }
  .towns__list li { font-size: 0.76rem; padding: 0.25rem 0.55rem; }
}

/* ============================================================
   WORK LIST: natural scroll, parallax media
   No pinning and no scroll hijacking. The previous version stuck the
   stage and stepped frames from scroll position, which meant a scroll
   changed state, state changed layout, and layout changed scroll. On
   touch that surfaced as jumping to the next frame and snapping back.

   Here the only thing that moves is a transform inside an overflowing
   mask. Transforms never affect layout, so nothing can feed back into
   scroll position. The page scrolls exactly as the browser intends.
   ============================================================ */
.wlist { display: grid; gap: clamp(3rem, 8vw, 7rem); }

.wrow__link {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(1.4rem, 4vw, 3.5rem);
  align-items: center;
  text-decoration: none;
  color: inherit;
}
/* Alternate sides so a long list never marches. */
.wrow:nth-child(even) .wrow__link { direction: rtl; }
.wrow:nth-child(even) .wrow__link > * { direction: ltr; }

.wrow__media {
  position: relative;
  display: block;
  aspect-ratio: 16 / 11;
  overflow: hidden;
  border-radius: 18px;
  border: 1px solid var(--line-strong);
  background: var(--card-bg);
}
/* Oversized so the parallax travel never runs out of image at either end. */
.wrow__inner {
  position: absolute;
  inset: -12% 0;
  display: block;
  will-change: transform;
}
.wrow__inner video {
  width: 100%; height: 100%; object-fit: cover; display: block;
}

.wrow__info { display: grid; gap: 0.5rem; align-content: center; }
.wrow__cat {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.66rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--accent, #e0403a);
}
.wrow__client {
  font-size: clamp(1.9rem, 5vw, 4rem);
  line-height: 0.98; letter-spacing: -0.035em;
  text-transform: uppercase; font-weight: 800;
}
.wrow__sub { font-size: clamp(1rem, 1.6vw, 1.2rem); opacity: 0.7; max-width: 34ch; line-height: 1.4; }
.wrow__meta {
  display: flex; flex-wrap: wrap; gap: 1.6rem;
  margin-top: 0.6rem; padding-top: 0.9rem;
  border-top: 1px solid var(--line-strong);
}
.wrow__meta > span { display: grid; gap: 0.25rem; }
.wrow__meta i {
  font-style: normal;
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.56rem; letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.5;
}
.wrow__cta {
  margin-top: 0.9rem; justify-self: start;
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.75rem 1.3rem; border-radius: 999px;
  border: 1px solid var(--line-strong);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase;
  transition: background 0.3s ease, color 0.3s ease;
}
.wrow__link:hover .wrow__cta { background: var(--ink); color: var(--paper); }
.wrow__cta em { font-style: normal; transition: transform 0.3s cubic-bezier(0.19,1,0.22,1); }
.wrow__link:hover .wrow__cta em { transform: translateX(5px); }

@media (max-width: 860px) {
  .wrow__link { grid-template-columns: minmax(0, 1fr); gap: 1.1rem; }
  .wrow:nth-child(even) .wrow__link { direction: ltr; }
  .wrow__media { aspect-ratio: 4 / 5; }
  .wlist { gap: clamp(2.4rem, 9vw, 3.6rem); }
}
@media (prefers-reduced-motion: reduce) {
  .wrow__inner { transform: none !important; }
}

/* ============================================================
   WORK LIST: reveal motion
   Three techniques, all of them transform / opacity / clip-path only.
   None of them touch layout, so none can feed back into scroll position
   the way the old pinned reel did. Reveals fire once on enter and stay
   put, which also means scrolling back up never re-animates.
   ============================================================ */

/* --- 1. clip-path wipe on the media -------------------------
   Alternating origin per row so a long list never feels mechanical. */
.wrow__media {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1.05s cubic-bezier(0.19, 1, 0.22, 1);
}
.wrow__media[data-reveal]:not(.is-in) { clip-path: inset(0 0 100% 0); }
.wrow:nth-child(odd)  .wrow__media[data-reveal]:not(.is-in) { clip-path: inset(0 100% 0 0); }
.wrow:nth-child(even) .wrow__media[data-reveal]:not(.is-in) { clip-path: inset(0 0 0 100%); }

/* The media itself counter-scales slightly, so the wipe reads as the frame
   opening onto the footage rather than the footage sliding in. */
.wrow__media[data-reveal] .wrow__inner {
  transition: transform 1.2s cubic-bezier(0.19, 1, 0.22, 1);
}
.wrow__media[data-reveal]:not(.is-in) .wrow__inner { transform: scale(1.12); }

/* --- 2. line-mask rise on the text --------------------------
   The single highest-value polish move in the vault's own notes: each line
   sits below a clipped edge and lifts into place. */
.mask { display: block; overflow: hidden; padding-block: 0.06em; margin-block: -0.06em; }
.mask > i {
  display: block;
  font-style: inherit;
  transform: translate3d(0, 0, 0);
  transition: transform 0.9s cubic-bezier(0.19, 1, 0.22, 1);
}
.wrow__info:not(.is-in) .mask > i { transform: translate3d(0, 108%, 0); }
/* Staggered so the three lines arrive as a sequence, not a block. */
.wrow__info .wrow__cat    > i { transition-delay: 0.02s; }
.wrow__info .wrow__client > i { transition-delay: 0.10s; }
.wrow__info .wrow__sub    > i { transition-delay: 0.18s; }

.wrow__info .wrow__meta,
.wrow__info .wrow__cta {
  transition: opacity 0.7s ease 0.3s, transform 0.9s cubic-bezier(0.19,1,0.22,1) 0.3s;
}
.wrow__info:not(.is-in) .wrow__meta,
.wrow__info:not(.is-in) .wrow__cta {
  opacity: 0; transform: translate3d(0, 14px, 0);
}


@media (prefers-reduced-motion: reduce) {
  .wrow__media, .wrow__media .wrow__inner, .mask > i,
  .wrow__meta, .wrow__cta { transition: none !important; }
  .wrow__media[data-reveal]:not(.is-in) { clip-path: none; }
  .wrow__info:not(.is-in) .mask > i { transform: none; }
  .wrow__info:not(.is-in) .wrow__meta,
  .wrow__info:not(.is-in) .wrow__cta { opacity: 1; transform: none; }
}

/* hCaptcha sits above the send button; it is an iframe we do not control,
   so only spacing and overflow are set here. */
.consult__fields .h-captcha{margin:.25rem 0 .1rem;min-height:78px;overflow:hidden}
.consult__fields .h-captcha iframe{max-width:100%}

/* Email and phone share a line on anything wider than a phone. Both are
   wanted, so asking for them side by side reads as one ask, not two. */
.field-row{display:grid;gap:.75rem}
@media (min-width:520px){.field-row{grid-template-columns:1fr 1fr}}

/* Post-submit state. Replaces the fields entirely so there is nothing
   left to press. */
.consult__done{padding:.6rem 0 .2rem}
.consult__donet{font-size:1.05rem;font-weight:600;margin:0 0 .4rem}
.consult__donep{margin:0;opacity:.75;line-height:1.5}
form[data-sent] .consult__btn{display:none}

/* ---------- Worth reading: links from a service or industry page into the
   articles that belong to it. Added after Search Console showed 67 posts
   discovered but never crawled, because nothing except /blog linked to
   them. ---------- */
.reading {
  max-width: var(--measure-wide); margin: 0 auto;
  padding: clamp(1.6rem, 4vw, 2.4rem) 0 0;
  border-top: 1px solid var(--line);
}
.reading__h {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.05rem, 2.2vw, 1.3rem); letter-spacing: -0.01em;
  margin: 0 0 1rem;
}
.reading__list { list-style: none; margin: 0 0 1.1rem; padding: 0; display: grid; gap: 0.1rem; }
.reading__list li { border-top: 1px solid var(--line); }
.reading__list li:first-child { border-top: 0; }
.reading__list a {
  display: block; padding: 0.7rem 0; color: var(--ink); text-decoration: none;
  font-size: 1rem; line-height: 1.35; transition: color 0.16s, padding 0.16s;
}
.reading__list a:hover { color: var(--red); padding-left: 0.35rem; }
.reading__all {
  display: inline-block; font-size: 0.85rem; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft);
}
.reading__all:hover { color: var(--red); }

/* ---------- Related reading inside a post ---------- */
.post__more { margin: 2.4rem 0 0; padding-top: 1.6rem; border-top: 1px solid var(--line); }
.post__moreh { font-family: var(--font-display); font-weight: 800; font-size: 1.05rem; margin: 0 0 0.9rem; }
.post__morelist { list-style: none; margin: 0; padding: 0; }
.post__morelist li { border-top: 1px solid var(--line); }
.post__morelist li:first-child { border-top: 0; }
.post__morelist a {
  display: block; padding: 0.7rem 0 0.2rem; color: var(--ink);
  text-decoration: none; line-height: 1.35; transition: color 0.16s;
}
.post__morelist a:hover { color: var(--red); }
.post__morelist span {
  display: block; padding-bottom: 0.7rem; font-size: 0.74rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
}
