/* ---------- Reset & base ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --cream: #F5EEE3;
  --cream-alt: #EFE6D6;
  --panel: #FBF7EF;
  --ink: #1C1B18;
  --ink-soft: #55504A;
  --ink-faint: #837C72;
  --border: #E1D5BE;
  --green: #15332C;
  --green-dark: #0D211C;
  --orange: #D8632E;
  --yellow: #E5A63C;
  --blue: #2E4C86;
  --black-shape: #191919;
  --white: #FFFFFF;

  --container: 1160px;
  --radius-lg: 20px;
  --radius-md: 14px;
  --radius-sm: 8px;

  --font-serif: "Fraunces", Georgia, serif;
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

html { scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation: none !important; transition: none !important; }
}

body {
  font-family: var(--font-sans);
  background: var(--cream);
  color: var(--ink);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 111%; }

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

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

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--green);
  color: var(--cream);
  padding: 12px 20px;
  border-radius: 0 0 8px 0;
  z-index: 200;
}
.skip-link:focus { left: 0; }

.eyebrow {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.divider {
  border-top: 1px solid var(--border);
  width: 100%;
}

/* ---------- Buttons & links ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.95rem;
  padding: 13px 22px;
  border-radius: var(--radius-sm);
  border: 1.5px solid transparent;
  transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn-primary {
  background: var(--green);
  color: var(--cream);
}
.btn-primary:hover { background: var(--green-dark); }

.btn-outline {
  background: transparent;
  color: var(--ink);
  border-color: var(--ink);
}
.btn-outline:hover { background: var(--ink); color: var(--cream); }

.btn-outline-light {
  background: transparent;
  color: var(--cream);
  border-color: rgba(245,238,227,0.55);
  align-self: flex-start;
}
.btn-outline-light:hover { background: rgba(245,238,227,0.12); border-color: var(--cream); }

.btn-small { padding: 9px 16px; font-size: 0.88rem; }

.icon-arrow {
  width: 15px; height: 15px;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}
.btn:hover .icon-arrow,
.cta-email:hover .icon-arrow { transform: translateX(3px); }

.card-link, .view-all {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  font-size: 0.92rem;
}
.view-all { color: var(--ink); }
.card-link { color: var(--green); }

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(245, 238, 227, 0.92);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--border);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 76px;
  gap: 24px;
}

.logo { display: flex; align-items: center; flex-shrink: 0; }
.logo svg { display: block; }

.main-nav {
  position: relative;
  display: flex;
  align-items: center;
  gap: 32px;
  margin: 0 auto;
  font-size: 0.95rem;
  font-weight: 500;
}

.main-nav a {
  position: relative;
  padding-bottom: 6px;
  color: var(--ink-soft);
  transition: color 0.15s ease;
}
.main-nav a:hover { color: var(--ink); }
.main-nav a.active {
  color: var(--ink);
  font-weight: 600;
}
.main-nav a.active::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--green);
  border-radius: 2px;
}
/* Static fallback underline; suppressed once the JS sliding indicator takes over. */
.main-nav.nav-js-ready a.active::after { display: none; }

.nav-indicator {
  position: absolute;
  bottom: 0;
  left: 0;
  height: 2px;
  width: 0;
  background: var(--green);
  border-radius: 2px;
  opacity: 0;
  pointer-events: none;
}

.header-cta { flex-shrink: 0; margin-left: 8px; }
.main-nav a.header-cta,
.main-nav a.header-cta:hover { color: var(--cream); }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  flex-shrink: 0;
}
.nav-toggle span {
  display: block;
  width: 18px;
  height: 1.5px;
  margin: 0 auto;
  background: var(--ink);
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* ---------- Hero ---------- */
.hero { padding: 76px 0 84px; }

.hero-inner {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 64px;
  align-items: center;
}

.hero-content h1 {
  font-family: var(--font-serif);
  font-weight: 900;
  font-size: clamp(3.2rem, 6.2vw, 5.2rem);
  line-height: 0.95;
  letter-spacing: -0.02em;
  margin-bottom: 20px;
}

.hero-content h2 {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  line-height: 1.28;
  max-width: 620px;
  margin-bottom: 22px;
}

.hero-content p {
  color: var(--ink-soft);
  font-size: 1.05rem;
  line-height: 1.65;
  max-width: 540px;
  margin-bottom: 16px;
}

.hero-actions {
  display: flex;
  gap: 16px;
  margin-top: 30px;
  flex-wrap: wrap;
}

.hero-graphic {
  position: relative;
  aspect-ratio: 0.98;
  width: 100%;
  border-radius: var(--radius-lg);
  background: var(--panel);
  border: 1px solid var(--border);
  overflow: hidden;
}

.hero-graphic .shape { position: absolute; }

.shape-quarter {
  top: 0; right: 0;
  width: 40%; height: 40%;
  background: var(--green);
  border-bottom-left-radius: 100%;
  z-index: 3;
}
.shape-green {
  top: 0; left: 0;
  width: 26%; height: 40%;
  background: var(--green);
  z-index: 3;
}
.shape-yellow {
  left: 0; top: 40%;
  width: 26%; height: 28%;
  background: var(--yellow);
  z-index: 3;
}
.shape-blue {
  left: 0; bottom: 0;
  width: 40%; height: 32%;
  background: var(--blue);
  clip-path: polygon(0 0, 100% 100%, 0 100%);
  z-index: 3;
}
.shape-orange {
  right: 0; bottom: 0;
  width: 25%; height: 46%;
  background: var(--orange);
  z-index: 3;
}
.hero-photo {
  position: absolute;
  left: 54%;
  bottom: 0;
  transform: translateX(-50%);
  width: 112%;
  height: auto;
  z-index: 2;
  display: block;
  filter: grayscale(100%);
}

/* ---------- Section headings ---------- */
section h2 {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: clamp(1.9rem, 3vw, 2.3rem);
  letter-spacing: -0.01em;
}

.section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 40px;
  gap: 20px;
  flex-wrap: wrap;
}

/* ---------- Selected Work ---------- */
.selected-work { padding: 88px 0; }

.work-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 28px;
}

.work-card {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  -webkit-tap-highlight-color: transparent;
}

.card-media {
  aspect-ratio: 16/12;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--white);
  border-bottom: 1px solid var(--border);
}

.card-media-photo { padding: 0; }
.card-media-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left center;
  display: block;
}

.card-link .icon-arrow {
  transition: transform 0.2s ease;
}

.card-body { padding: 22px 22px 26px; display: flex; flex-direction: column; gap: 8px; }

.card-top-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.card-kicker {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--orange);
}

.card-index {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 0.8rem;
  color: var(--ink-faint);
  opacity: 0.55;
  flex-shrink: 0;
}

.card-body h3 {
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.3;
}

.card-desc {
  color: var(--ink-soft);
  font-size: 0.92rem;
  line-height: 1.55;
}

.card-tags {
  color: var(--ink-faint);
  font-size: 0.82rem;
  font-weight: 500;
}

.card-note {
  color: var(--ink-faint);
  font-size: 0.78rem;
  font-style: italic;
}

.card-link {
  margin-top: 6px;
  -webkit-tap-highlight-color: transparent;
}
.card-link::after { content: ""; position: absolute; inset: 0; }
.card-link:active,
.card-link:focus { outline: none; }

/* mock: storefront */
.mock-topbar { display: flex; align-items: center; gap: 5px; }
.mock-topbar .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--border); }
.mock-topbar.dark .dot { background: rgba(255,255,255,0.25); }
.mock-storename { margin-left: auto; font-size: 0.6rem; font-weight: 700; letter-spacing: 0.08em; color: var(--ink-faint); }
.mock-storename.light { color: rgba(255,255,255,0.6); }

.mock-nav { display: flex; gap: 12px; font-size: 0.62rem; color: var(--ink-faint); font-weight: 500; }

.mock-product { display: flex; gap: 10px; flex: 1; }
.mock-product-image {
  flex: 1;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--orange), var(--yellow));
  position: relative;
  min-height: 60px;
}
.mock-price-tag {
  position: absolute;
  bottom: 8px; left: 8px;
  background: var(--cream);
  color: var(--ink);
  font-size: 0.62rem;
  font-weight: 700;
  padding: 3px 7px;
  border-radius: 5px;
}
.mock-product-info { flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 8px; }
.mock-line { height: 7px; border-radius: 4px; background: var(--border); }
.mock-line-title { width: 80%; }
.mock-line-sub { width: 55%; background: #ECE1CB; }
.mock-btn {
  margin-top: 4px;
  align-self: flex-start;
  background: var(--green);
  color: var(--cream);
  font-size: 0.62rem;
  font-weight: 700;
  padding: 6px 12px;
  border-radius: 6px;
}
.mock-thumbs { display: flex; gap: 6px; }
.mock-thumbs span { width: 22%; aspect-ratio: 1; border-radius: 6px; background: var(--border); }

/* mock: custom dev (dark) */
.media-custom { background: var(--green); border-bottom-color: var(--green-dark); }
.mock-stats { display: flex; gap: 18px; margin-top: 4px; }
.mock-stat { display: flex; flex-direction: column; gap: 2px; }
.mock-stat-num { font-family: var(--font-serif); font-weight: 700; font-size: 1.3rem; color: var(--cream); }
.mock-stat-label { font-size: 0.6rem; color: rgba(245,238,227,0.55); }
.mock-toggles { display: flex; flex-direction: column; gap: 8px; margin-top: auto; }
.mock-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mock-line-sm { flex: 1; height: 6px; border-radius: 4px; background: rgba(245,238,227,0.18); }
.mock-switch { width: 24px; height: 13px; border-radius: 999px; background: rgba(245,238,227,0.18); position: relative; flex-shrink: 0; }
.mock-switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 9px; height: 9px; border-radius: 50%; background: rgba(245,238,227,0.5); transition: left 0.15s ease; }
.mock-switch.on { background: var(--yellow); }
.mock-switch.on::after { left: 13px; background: var(--green-dark); }

/* mock: automation pipeline */
.mock-pipeline { display: flex; flex-direction: column; gap: 4px; flex: 1; justify-content: center; }
.mock-node {
  display: flex; align-items: center; gap: 8px;
  font-size: 0.68rem; font-weight: 600; color: var(--ink-soft);
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 7px 10px;
}
.mock-node-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.mock-node-dot.green { background: var(--green); }
.mock-node-dot.yellow { background: var(--yellow); }
.mock-node-dot.blue { background: var(--blue); }
.mock-node-dot.orange { background: var(--orange); }
.mock-connector { width: 1.5px; height: 8px; background: var(--border); margin-left: 14px; }

/* mock: concept storefront composition (wireframe-style, not a screenshot) */
.concept-grid {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 1fr;
  gap: 8px;
}
.concept-tile { border-radius: var(--radius-sm); }
.concept-tile.wide { grid-column: 1 / -1; }
.concept-tile.tile-green { background: var(--green); }
.concept-tile.tile-yellow { background: var(--yellow); }
.concept-tile.tile-blue { background: var(--blue); }
.concept-tile.tile-orange { background: var(--orange); }

/* ---------- What I Do ---------- */
.what-i-do { padding: 88px 0; }
.what-i-do h2 { margin-bottom: 44px; }

.services-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 36px 28px;
}

.service-icon {
  width: 52px; height: 52px;
  border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  color: var(--cream);
  margin-bottom: 18px;
}
.service-icon svg { width: 24px; height: 24px; }

.icon-green { background: var(--green); }
.icon-orange { background: var(--orange); }
.icon-blue { background: var(--blue); }
.icon-yellow { background: var(--yellow); }

.service-item h3 { font-size: 1.05rem; font-weight: 700; margin-bottom: 10px; }
.service-item p { color: var(--ink-soft); font-size: 0.92rem; line-height: 1.6; }

/* --- What I Do: staged entrance ---------------------------------------
   The whole section plays as one choreography the first time it scrolls
   into view (the observer in js/main.js puts .in-view on the section):

     1. the copy wipes open left-to-right, column after column;
     2. the icons follow in the same order — each one rolls in from the
        left, tipping edge over edge like a die and bouncing on every
        landing before it settles upright in its slot.

   The section carries plain `.reveal` purely as the trigger: that is the
   hook js/main.js already watches, so the sequence arms itself with any
   version of the script. `.anim-stage` down in the reveal block cancels
   the section's own fade/slide — only the children move.

   Nothing here animates until .in-view lands, so the section holds its
   final layout (the icons keep their space) while the text plays. */
.what-i-do.anim-stage { overflow-x: clip; }

.what-i-do.anim-stage .wid-title,
.what-i-do.anim-stage .service-item h3,
.what-i-do.anim-stage .service-item p,
.what-i-do.anim-stage .service-icon { opacity: 0; }

/* Column index drives every delay below, so the two waves sweep across
   the grid in the same left-to-right order. */
.services-grid .service-item { --i: 0; }
.services-grid .service-item:nth-child(2) { --i: 1; }
.services-grid .service-item:nth-child(3) { --i: 2; }
.services-grid .service-item:nth-child(4) { --i: 3; }

/* Wave 1 — text uncovers from its left edge. */
@keyframes wid-wipe {
  from { opacity: 0; clip-path: inset(0 100% 0 0); transform: translate3d(-18px, 0, 0); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); transform: translate3d(0, 0, 0); }
}

.what-i-do.anim-stage.in-view .wid-title {
  animation: wid-wipe 0.72s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.what-i-do.anim-stage.in-view .service-item h3 {
  animation: wid-wipe 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(0.26s + var(--i) * 0.1s);
}
.what-i-do.anim-stage.in-view .service-item p {
  animation: wid-wipe 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(0.34s + var(--i) * 0.1s);
}

/* Wave 2 — the tumble. --roll is exactly four tile widths, so each of
   the four quarter-turns covers one edge of the icon and the roll reads
   as real contact with the ground instead of a spin-and-slide. Arcs get
   lower as it goes, the way a real die loses height on every bounce.
   Every keyframe repeats the same transform function list on purpose:
   mixing lists would force matrix interpolation and the browser would
   take the short way round instead of turning the full 360deg. */
@keyframes wid-tumble {
  0% {
    opacity: 0;
    transform: translate3d(var(--roll), 0, 0) rotate(-360deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.2, 0.55, 0.4, 1);
  }
  6% { opacity: 1; }
  11% {
    transform: translate3d(calc(var(--roll) * 0.875), -38px, 0) rotate(-315deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.6, 0, 0.9, 0.5);
  }
  20% {
    transform: translate3d(calc(var(--roll) * 0.75), 0, 0) rotate(-270deg) scale(1.08, 0.9);
    animation-timing-function: cubic-bezier(0.2, 0.55, 0.4, 1);
  }
  24% {
    transform: translate3d(calc(var(--roll) * 0.7), -14px, 0) rotate(-252deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.25, 0.6, 0.45, 1);
  }
  31% {
    transform: translate3d(calc(var(--roll) * 0.625), -34px, 0) rotate(-225deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.6, 0, 0.9, 0.5);
  }
  40% {
    transform: translate3d(calc(var(--roll) * 0.5), 0, 0) rotate(-180deg) scale(1.08, 0.9);
    animation-timing-function: cubic-bezier(0.2, 0.55, 0.4, 1);
  }
  44% {
    transform: translate3d(calc(var(--roll) * 0.45), -13px, 0) rotate(-162deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.25, 0.6, 0.45, 1);
  }
  51% {
    transform: translate3d(calc(var(--roll) * 0.375), -29px, 0) rotate(-135deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.6, 0, 0.9, 0.5);
  }
  60% {
    transform: translate3d(calc(var(--roll) * 0.25), 0, 0) rotate(-90deg) scale(1.08, 0.9);
    animation-timing-function: cubic-bezier(0.2, 0.55, 0.4, 1);
  }
  64% {
    transform: translate3d(calc(var(--roll) * 0.2), -11px, 0) rotate(-72deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.25, 0.6, 0.45, 1);
  }
  71% {
    transform: translate3d(calc(var(--roll) * 0.125), -24px, 0) rotate(-45deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.6, 0, 0.9, 0.5);
  }
  80% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1.1, 0.88);
    animation-timing-function: cubic-bezier(0.2, 0.55, 0.4, 1);
  }
  87% {
    transform: translate3d(0, -12px, 0) rotate(0deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.6, 0, 0.9, 0.5);
  }
  94% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1.05, 0.95);
    animation-timing-function: cubic-bezier(0.3, 0, 0.5, 1);
  }
  100% {
    opacity: 1;
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1, 1);
  }
}

.what-i-do.anim-stage.in-view .service-icon {
  --roll: -208px;
  transform-origin: 50% 100%;
  animation: wid-tumble 1.15s linear both;
  animation-delay: calc(0.95s + var(--i) * 0.13s);
}

/* Reduced motion: the global rule at the top of this file drops the
   animations, so the staged elements need their finished state back. */
@media (prefers-reduced-motion: reduce) {
  .what-i-do.anim-stage .wid-title,
  .what-i-do.anim-stage .service-item h3,
  .what-i-do.anim-stage .service-item p,
  .what-i-do.anim-stage .service-icon {
    opacity: 1;
    clip-path: none;
    transform: none;
  }
}

/* ---------- Technical Capabilities ---------- */
.tech-capabilities { padding: 80px 0; border-top: 1px solid var(--border); }
.tech-capabilities h2 { margin-bottom: 44px; }

.tech-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}

.tech-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 28px 32px;
}

.tech-card h3 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 1rem;
  font-weight: 700;
  margin-bottom: 14px;
}

.tech-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }

.tech-skills { color: var(--ink-soft); font-size: 0.98rem; line-height: 1.6; }

/* --- Technical Toolkit: one card, then the rest out of it -------------
   The first card drops into place and settles with a bounce, the same
   language as the tumbling icons above. Once it is down, the other three
   slide out from underneath it — right, then down, then diagonally —
   growing to full size as they travel, so they read as being pulled out
   of the first card rather than flying in from off-screen.

   --dx/--dy is the offset from a card's own slot back to card 1's slot.
   Grid items here are stretched to identical sizes at every breakpoint,
   so "one card plus the 24px gap" is exactly one step of the grid and
   the three of them start perfectly hidden behind card 1. */
.tech-capabilities.anim-stage .tech-card { position: relative; opacity: 0; }
/* Stacked in dealing order: every card slides out from under the ones
   already placed, never across them. Only visible while they travel —
   in the settled grid nothing overlaps. */
.tech-capabilities.anim-stage .tech-card:nth-child(1) { z-index: 4; }
.tech-capabilities.anim-stage .tech-card:nth-child(2) { z-index: 3; }
.tech-capabilities.anim-stage .tech-card:nth-child(3) { z-index: 2; }
.tech-capabilities.anim-stage .tech-card:nth-child(4) { z-index: 1; }

.tech-grid .tech-card:nth-child(2) { --dx: calc(-100% - 24px); --dy: 0px; --d: 0.02s; }
.tech-grid .tech-card:nth-child(3) { --dx: 0px; --dy: calc(-100% - 24px); --d: 0.14s; }
.tech-grid .tech-card:nth-child(4) { --dx: calc(-100% - 24px); --dy: calc(-100% - 24px); --d: 0.26s; }

/* The fall is deliberately unhurried — it carries the whole opening beat
   of the section, so it comes from higher up and accelerates gently
   rather than dropping in a blink. The bounce after it stays quick. */
@keyframes tk-drop {
  0% {
    opacity: 0;
    transform: translate3d(0, -72px, 0) rotate(-1.6deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.4, 0, 0.75, 0.5);
  }
  26% { opacity: 1; }
  60% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1.015, 0.955);
    animation-timing-function: cubic-bezier(0.2, 0.55, 0.4, 1);
  }
  75% {
    transform: translate3d(0, -11px, 0) rotate(0deg) scale(1, 1);
    animation-timing-function: cubic-bezier(0.6, 0, 0.9, 0.5);
  }
  89% {
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1.01, 0.975);
    animation-timing-function: cubic-bezier(0.3, 0, 0.4, 1);
  }
  100% {
    opacity: 1;
    transform: translate3d(0, 0, 0) rotate(0deg) scale(1, 1);
  }
}

@keyframes tk-emerge {
  0% { opacity: 0; transform: translate3d(var(--dx), var(--dy), 0) scale(0.9); }
  18% { opacity: 1; }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}

.tech-capabilities.anim-stage.in-view .tech-card:first-child {
  animation: tk-drop 1.25s linear both;
  animation-delay: 0.15s;
}
/* They leave as card 1 hits the ground, so the landing is what shakes
   them loose instead of the sequence pausing between the two beats. */
.tech-capabilities.anim-stage.in-view .tech-card:nth-child(n+2) {
  animation: tk-emerge 0.9s cubic-bezier(0.16, 1, 0.3, 1) both;
  animation-delay: calc(0.9s + var(--d));
}

@media (prefers-reduced-motion: reduce) {
  .tech-capabilities.anim-stage .tech-card { opacity: 1; transform: none; }
}

.tags { display: flex; flex-wrap: wrap; gap: 8px; }
.tag {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--ink-soft);
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 6px 12px;
}

/* ---------- CTA ---------- */
.cta { padding: 20px 0 64px; }

.cta-box {
  background: var(--green);
  color: var(--cream);
  border-radius: var(--radius-lg);
  padding: 36px 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
}

.cta-text {
  font-family: var(--font-serif);
  font-size: clamp(1.15rem, 1.8vw, 1.4rem);
  line-height: 1.35;
  max-width: 480px;
}

.cta-actions { display: flex; align-items: center; gap: 28px; flex-shrink: 0; }

.cta-email {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 700;
  color: var(--yellow);
  font-size: 1.02rem;
  border-bottom: 1.5px solid rgba(229,166,60,0.4);
  padding-bottom: 3px;
}
.cta-email svg { width: 18px; height: 18px; }

/* ---------- Footer ---------- */
.site-footer { border-top: 1px solid var(--border); padding: 28px 0; }
.footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}
.copyright { color: var(--ink-faint); font-size: 0.88rem; }
.footer-links { display: flex; gap: 26px; font-size: 0.88rem; font-weight: 500; color: var(--ink-soft); }
.footer-links a:hover { color: var(--ink); }

/* ---------- Case study page ---------- */
.case-hero {
  background: var(--green);
  color: var(--cream);
  padding: 64px 0 52px;
}

.case-hero-inner {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 56px;
  align-items: center;
}

.case-hero-media { position: relative; }
.case-hero-media::before {
  content: "";
  position: absolute;
  inset: 20px -16px -16px 20px;
  background: var(--yellow);
  border-radius: var(--radius-lg);
  z-index: 0;
}

.case-shot {
  position: relative;
  z-index: 1;
  background: var(--white);
  border-radius: var(--radius-lg);
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  aspect-ratio: 4/3.1;
  box-shadow: 0 26px 54px rgba(9, 20, 17, 0.35);
}
.case-shot.case-shot-dark { background: var(--green-dark); }
.case-shot.case-shot-photo { padding: 0; overflow: hidden; }
.case-shot.case-shot-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left center;
  display: block;
}

.case-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: rgba(245,238,227,0.7);
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 32px;
  transition: color 0.15s ease;
}
.case-back:hover { color: var(--cream); }

.case-hero .card-kicker { color: var(--yellow); margin-bottom: 14px; }

.case-hero h1 {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: clamp(2.2rem, 4.4vw, 3.4rem);
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--cream);
  margin-bottom: 18px;
  max-width: 820px;
}

.case-lead {
  color: rgba(245,238,227,0.8);
  font-size: 1.08rem;
  line-height: 1.65;
  max-width: 640px;
  margin-bottom: 40px;
}

.case-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 28px 56px;
  border-top: 1px solid rgba(245,238,227,0.16);
  padding-top: 28px;
}
.case-meta-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.case-meta-label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(245,238,227,0.5);
}
.case-meta-value { font-size: 0.95rem; font-weight: 600; color: var(--cream); }

.case-role { padding: 64px 0; }
.case-role-inner { max-width: 760px; }
.case-role .eyebrow { margin-bottom: 12px; }
.case-role h2 { margin-bottom: 18px; }
.case-role p { color: var(--ink-soft); font-size: 1.02rem; line-height: 1.7; }
.case-role p + p { margin-top: 14px; }
.case-role .tags { margin-top: 22px; }

.case-work { padding: 20px 0 88px; }
.case-work h2 { margin-bottom: 16px; }

.case-media-disclaimer {
  font-size: 0.84rem;
  font-style: italic;
  color: var(--ink-faint);
  max-width: 560px;
  margin-bottom: 52px;
}

.case-block {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 56px;
  align-items: center;
}
.case-block + .case-block { margin-top: 72px; }
.case-block.reverse .case-block-media { order: 2; }
.case-block.reverse .case-block-text { order: 1; }

.case-block-heading { display: flex; flex-direction: column; }

.case-num {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--orange);
  letter-spacing: 0.02em;
  display: block;
  margin-bottom: 10px;
}
.case-block-text h3 { font-size: 1.4rem; font-weight: 700; margin-bottom: 12px; line-height: 1.25; }
.case-block-text p { color: var(--ink-soft); font-size: 0.98rem; line-height: 1.65; }

/* ---------- Case page: full-width visual sections + image placeholders ---------- */
/* Generic vertical rhythm for a case page built from a mix of split
   (.case-block) and full-width (.case-feature) sections. */
.case-section + .case-section { margin-top: 72px; }

.case-feature-heading { max-width: 640px; margin-bottom: 24px; }
.case-feature-heading h3 { font-size: 1.4rem; font-weight: 700; margin-bottom: 10px; line-height: 1.25; }
.case-feature-heading p { color: var(--ink-soft); font-size: 0.98rem; line-height: 1.65; }

/* Intentional stand-in for a screenshot that hasn't been produced yet —
   styled as a deliberate content slot (dashed frame, icon, label) rather
   than a bare gray box. */
.case-placeholder {
  position: relative;
  background: var(--panel);
  border: 1.5px dashed var(--border);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  padding: 32px;
  overflow: hidden;
}
.case-placeholder::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(135deg, rgba(28,27,24,0.035) 0 2px, transparent 2px 14px);
  pointer-events: none;
}
.ph-icon-wrap {
  position: relative;
  z-index: 1;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--cream);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-faint);
}
.ph-icon-wrap svg { width: 22px; height: 22px; }
.ph-label { position: relative; z-index: 1; font-weight: 700; color: var(--ink-soft); font-size: 0.92rem; }
.ph-sublabel {
  position: relative;
  z-index: 1;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.ph-16x9 { aspect-ratio: 16/9; }
.ph-4x3 { aspect-ratio: 4/3; }
.ph-21x9 { aspect-ratio: 21/9; }

.ph-responsive-row { display: flex; align-items: stretch; gap: 20px; }
.ph-desktop-frame { flex: 1 1 62%; aspect-ratio: 16/10; }
.ph-mobile-frame { flex: 0 1 30%; max-width: 220px; aspect-ratio: 9/16; }

.case-micro .case-feature-heading { margin-bottom: 20px; }
.ph-icon-wrap.ph-play svg { margin-left: 2px; }

/* wp-frame: browser-style chrome wrapping real screenshots */
.wp-frame {
  position: relative;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 4/3;
  display: flex;
  flex-direction: column;
  box-shadow: 0 14px 30px rgba(28, 27, 24, 0.06);
  transition: transform 0.7s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
@media (hover: hover) and (pointer: fine) and (min-width: 1200px) {
  .wp-frame:hover {
    position: relative;
    z-index: 5;
    transform: scale(1.08);
    box-shadow: 0 34px 70px rgba(28, 27, 24, 0.24);
  }
}
.wp-topbar {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.wp-topbar .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--border); }
.wp-url {
  margin-left: 8px;
  font-size: 0.66rem;
  font-weight: 500;
  color: var(--ink-faint);
  background: var(--cream);
  padding: 3px 10px;
  border-radius: 999px;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.case-shot-image {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background: var(--cream);
}
.case-shot-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  cursor: zoom-in;
}

/* Each screenshot is zoomed in on its most relevant detail (table headers,
   the code modal) so the crop stays legible at case-block-media size. */
.shot-storefront { object-position: top center; transform: scale(1.15); transform-origin: top center; }
.shot-orders { object-position: top left; transform: scale(1.3); transform-origin: top left; }
.shot-snippet { object-position: center center; transform: scale(1.15); transform-origin: center 46%; }
.shot-products { object-position: top left; transform: scale(1.3); transform-origin: top left; }
.shot-workflow { object-position: left center; transform: scale(1.1); transform-origin: left center; }
.shot-ai-node { object-position: left top; transform: scale(1.15); transform-origin: left top; }

.shot-zoom-hint {
  position: absolute;
  bottom: 10px;
  right: 10px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(21, 51, 44, 0.8);
  color: var(--cream);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
  pointer-events: none;
}
.shot-zoom-hint svg { width: 15px; height: 15px; }
.wp-frame:hover .shot-zoom-hint,
.case-shot-image img:focus-visible ~ .shot-zoom-hint {
  opacity: 1;
  transform: translateY(0);
}

/* ---------- Screenshot lightbox ---------- */
.shot-lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px;
  background: rgba(13, 17, 15, 0.92);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease;
}
.shot-lightbox.open { opacity: 1; visibility: visible; }
.shot-lightbox-img {
  max-width: 100%;
  max-height: 100%;
  border-radius: var(--radius-sm);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
}
.shot-lightbox-close {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(245, 238, 227, 0.12);
  border: 1px solid rgba(245, 238, 227, 0.3);
  color: var(--cream);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s ease;
}
.shot-lightbox-close:hover { background: rgba(245, 238, 227, 0.22); }
.shot-lightbox-close svg { width: 18px; height: 18px; }

body.lightbox-open { overflow: hidden; }

/* ---------- Flow diagrams (automation / integration case study) ---------- */
.flow-diagram {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  padding: 22px 22px;
  background: var(--cream);
}
.flow-step {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink);
  text-align: center;
  line-height: 1.3;
}
.flow-step-accent {
  border-color: transparent;
  color: var(--cream);
}
.flow-step-accent.accent-green { background: var(--green); }
.flow-step-accent.accent-blue { background: var(--blue); }
.flow-step-accent.accent-orange { background: var(--orange); }
.flow-step-accent.accent-yellow { background: var(--yellow); color: var(--ink); }

.flow-arrow {
  align-self: center;
  color: var(--ink-faint);
  font-size: 1rem;
  line-height: 1;
}

@media (max-width: 1024px) {
  .case-hero-inner { grid-template-columns: 1fr; gap: 36px; }
  .case-hero-media { max-width: 380px; margin: 0 auto; }
  .case-meta { gap: 22px 40px; }
  .case-block, .case-block.reverse { grid-template-columns: 1fr; }
  .case-block.reverse .case-block-media, .case-block.reverse .case-block-text { order: 0; }
}

@media (max-width: 768px) {
  .case-hero { padding: 36px 0 40px; }
  .case-hero-inner { gap: 40px; }
  .case-hero-media { max-width: 280px; margin: 0 auto; }
  .case-hero-media::before { inset: 14px -10px -10px 14px; border-radius: var(--radius-md); }
  .case-shot { border-radius: var(--radius-md); }
  .case-role, .case-work { padding-top: 44px; padding-bottom: 44px; }
  .case-work h2 { margin-bottom: 12px; }
  .case-media-disclaimer { margin-bottom: 36px; }
  .case-block { gap: 18px; }
  .case-block + .case-block { margin-top: 48px; }
  .case-section + .case-section { margin-top: 48px; }
  .ph-responsive-row { flex-direction: column; align-items: center; }
  .ph-desktop-frame { width: 100%; max-width: none; }
  .ph-mobile-frame { width: 100%; max-width: 260px; aspect-ratio: 9/14; }
  .case-back { margin-bottom: 24px; }
  .case-hero .card-kicker { margin-bottom: 12px; }
  .case-hero h1 { margin-bottom: 16px; }
  .case-lead { margin-bottom: 32px; }
  .case-meta {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 22px 16px;
    padding-top: 24px;
  }
}

@media (max-width: 480px) {
  .case-hero { padding: 28px 0 36px; }
  .case-hero h1 { font-size: 1.85rem; line-height: 1.15; margin-bottom: 14px; }
  .case-lead { font-size: 1rem; margin-bottom: 28px; }
  .case-back { margin-bottom: 20px; }
  .case-hero-inner { gap: 32px; }
  .case-hero-media { max-width: 210px; }
  .case-shot { padding: 14px; gap: 8px; }
  .case-shot .mock-nav { gap: 8px; }
  .case-shot .mock-price-tag { font-size: 0.56rem; padding: 2px 6px; }
  .case-shot .mock-btn { font-size: 0.56rem; padding: 5px 9px; }
}

/* ---------- Reveal on scroll ---------- */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1), transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.in-view { opacity: 1; transform: translateY(0); }

/* A section that runs its own choreography wears `.reveal` only to get
   picked up by the observer — it must not fade or slide itself. Sits
   after `.reveal` on purpose: same specificity, later wins. */
.anim-stage { opacity: 1; transform: none; transition: none; }

/* Light stagger so cards in the same row settle in one after another
   instead of popping in all at once. */
.work-grid .work-card:nth-child(2) { transition-delay: 0.1s; }

/* ---------- Motion entrance (animated in js/motion.js) ---------- */
/* Elements stay visible by default (no CDN/JS dependency for content to
   appear); motion.js supplies its own "from" keyframe when it animates in,
   so there's nothing to hide here and nothing to fall back from. */
.hero-content h1 .line-mask { display: inline-block; overflow: hidden; padding-bottom: 0.14em; margin-bottom: -0.14em; }
.hero-content h1 .line-inner { display: inline-block; }

/* ---------- Responsive ---------- */
@media (max-width: 1024px) {
  .hero-inner { grid-template-columns: 1fr; gap: 40px; }
  .hero-graphic { max-width: 420px; margin: 0 auto; }
  .work-grid { grid-template-columns: repeat(2, 1fr); }
  .services-grid { grid-template-columns: repeat(2, 1fr); }
  .tech-grid { grid-template-columns: repeat(2, 1fr); }
  .cta-box { flex-direction: column; align-items: flex-start; gap: 24px; }
  .cta-text { max-width: none; }
}

@media (max-width: 768px) {
  .container { padding: 0 22px; }
  .main-nav { display: none; }
  .nav-toggle { display: flex; }

  .site-header.menu-open .main-nav {
    display: flex;
    position: absolute;
    top: 76px; left: 0; right: 0;
    background: var(--cream);
    border-bottom: 1px solid var(--border);
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 16px 22px 24px;
  }
  .site-header.menu-open .main-nav a {
    width: 100%;
    padding: 10px 0;
  }
  .site-header.menu-open .header-cta {
    width: auto;
    margin: 10px 0 0;
    justify-content: center;
  }

  .hero { padding: 44px 0 56px; }
  .hero-graphic { order: -1; }
  .selected-work, .what-i-do, .tech-capabilities { padding: 56px 0; }
  .cta { padding: 12px 0 64px; }

  .work-grid { grid-template-columns: 1fr; }
  .services-grid { grid-template-columns: 1fr 1fr; gap: 30px 20px; }

  /* One column: the toolkit cards stack, so each one comes out of the
     card above rather than out of the one beside it. */
  .tech-grid { grid-template-columns: 1fr; }
  .tech-grid .tech-card:nth-child(2) { --dx: 0px; --dy: calc(-100% - 24px); }
  .tech-grid .tech-card:nth-child(3) { --dx: 0px; --dy: calc(-200% - 48px); }
  .tech-grid .tech-card:nth-child(4) { --dx: 0px; --dy: calc(-300% - 72px); }
  .cta-box { padding: 36px 26px; }
  .section-header { margin-bottom: 28px; }
}

@media (max-width: 480px) {
  .hero-content h1 { font-size: 3rem; }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { justify-content: center; }
  .services-grid { grid-template-columns: 1fr; }
  .cta-actions { flex-direction: column; align-items: flex-start; gap: 18px; }
  .footer-inner { flex-direction: column; align-items: flex-start; }
}
