/* ==========================================================================
   Ryan Mardiono — portfolio stylesheet.

   One file per concern, bundled in this order. Tokens first, then the base
   (reset, type, button, motion), then the clip frames every section
   shares, then a file per section, then the colour washes, last so they win. Each section file holds its own desktop,
   tablet (≤899px) and phone (≤639px) rules, so a section reads top to bottom.

   Minification is off (astro.config.mjs): the minifier folds
   `animation-timeline` into the `animation` shorthand, which browsers reject.
   ========================================================================== *//* ==========================================================================
   Design tokens. Every colour, face, measure and easing the site uses lives
   here; components read tokens and never hard-code a value. Desktop measures
   come from the reference at 1440px (an 824px column, 40px card radius).
   ========================================================================== */

/* Registered so they can animate: the fruit's turn on scroll and the sticker's peeled corner. */
@property --turn {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
@property --fold {
  syntax: '<length>';
  inherits: true;
  initial-value: 0px;
}

:root {
  /* Surfaces */
  --cream: #f6f5f1;
  --card: #e4e3dd;
  --white: #fff;
  --ice: #ddf4ff;
  --turf: #e6f1e4;
  --navy: #131f24;
  --pine: #1d3637;
  --bezel: #14171a; /* device frames around recordings */
  --bezel-dot: #3d434a; /* the browser window's three dots */
  --grid: #e7e7e1; /* the recipe card's grid paper */

  /* Ink */
  --ink: #000;
  --ink-soft: #292929;
  --ink-2: rgba(0, 0, 0, 0.7); /* body copy on light surfaces (8:1 on cream) */
  --ink-3: rgba(0, 0, 0, 0.6); /* captions and asides (5.6:1 on cream) */
  --line: rgba(0, 0, 0, 0.22);

  /* Fruit */
  --red: #fd1e1f;
  --blue: #0015d4;
  --sky: #a8ddf6;
  --pink: #ff8fca;
  --yellow: #ffcb41;
  --orange: #ff8c1a;
  --mango: #ffb230;
  --mango-light: #ffd27a;
  --lime: #a9d33a;
  --green: #3fae49;

  /* The accent is the fruit red for marks and fills; text takes a deeper cut of it that clears 4.5:1 on cream. */
  --accent: var(--red);
  --accent-text: #d61314;

  /* Text on the current surface. Washes (see base.css) override these so copy stays readable on every colour. */
  --text: var(--ink);
  --text-2: var(--ink-2);

  /* Type */
  --serif: 'Libre Baskerville', Georgia, 'Times New Roman', serif;
  --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* Measure */
  --col: 824px;
  --gutter: 24px;
  --r-lg: 40px;
  --r-md: 24px;
  --r-sm: 16px;

  /* Motion */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --spring: linear(0, 0.006, 0.025 2.8%, 0.101 6.1%, 0.539 18.9%, 0.721 25.3%, 0.849 31.5%, 0.937 38.1%, 0.968 41.8%, 0.991 45.7%, 1.006 50.1%, 1.015 55%, 1.017 63.9%, 1.001);

  /* Shadow, for things pinned to a board (leaning left or right) */
  --shadow-l: rgba(0, 0, 0, 0.15) -7px 9px 15px 2px;
  --shadow-r: rgba(0, 0, 0, 0.15) 7px 9px 15px 2px;
}

/* ==========================================================================
   Base: reset, focus, type, layout primitives, the button and tab, colour
   washes, and the motion utilities every section shares.
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;
}
body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.4;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
img,
svg {
  display: block;
  max-width: 100%;
}
img {
  height: auto;
}
a {
  color: inherit;
  text-decoration: none;
}
p {
  margin: 0;
  text-wrap: pretty;
}
h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 400;
  text-wrap: balance;
}
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
figure {
  margin: 0;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
main:focus {
  outline: none;
} /* the skip link's target; the outline would ring the whole page */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 4px;
}
::selection {
  background: var(--yellow);
  color: var(--ink);
}

/* ---- Accessibility helpers ------------------------------------------- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.sprite {
  position: absolute;
}
/* Skip link: off screen until it has focus, then a pill at the top left. */
.skip {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: 12px;
  background: var(--ink);
  color: var(--white);
  font-weight: 500;
}
.skip:focus {
  top: 16px;
}

/* ---- Type (measured) ------------------------------------------------- */
.t-display {
  font-family: var(--serif);
  font-size: 40px;
  line-height: 52px;
  letter-spacing: -0.6px;
}
.t-lead {
  font-family: var(--serif);
  font-size: 20px;
  line-height: 30px;
  letter-spacing: -0.4px;
}
.t-serif-md {
  font-family: var(--serif);
  font-size: 24px;
  line-height: 36px;
  letter-spacing: -0.4px;
}

/* ---- Layout ---------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--col);
  margin: 0 auto;
}
.rule {
  width: 100%;
  border: 0;
  border-top: 1px dashed var(--line);
  margin: 0;
}

/* ---- Button ---------------------------------------------------------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 44.2px;
  padding: 0 20px;
  border-radius: 24px;
  background: var(--ink);
  color: var(--white);
  font-size: 18px;
  font-weight: 500;
  line-height: 25.2px;
  letter-spacing: -0.18px;
  white-space: nowrap;
  overflow: hidden;
  isolation: isolate;
  transition: transform 0.5s var(--spring);
}
/* juice: a fill with a rounded top rises from the bottom and settles with a bounce */
.btn::before {
  content: '';
  position: absolute;
  left: -12%;
  top: 100%;
  width: 124%;
  height: 130%;
  border-radius: 50% 50% 0 0 / 40% 40% 0 0;
  background: var(--accent);
  transform: rotate(-3deg);
  transform-origin: 50% 100%;
  transition: transform 0.42s var(--spring);
  z-index: -1;
}
.btn:hover::before,
.btn:focus-visible::before {
  transform: translateY(-88%) rotate(2deg);
}
.btn:active {
  transform: scale(0.97);
}
.btn--ghost {
  background: transparent;
  color: var(--ink);
}
.btn--ghost::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1.5px var(--ink);
  pointer-events: none;
}
.btn--ghost::before {
  background: var(--yellow);
} /* lemonade */
.btn > :not(.sr-only) {
  position: relative;
}

/* ---- Tab: hangs off the bottom of a block (the footer, a case study) --- */
.tab {
  display: inline-block;
  height: 57px;
  padding: 16px 32px 0;
  background: var(--card);
  color: var(--ink);
  font-size: 18px;
  line-height: 25.2px;
  letter-spacing: -0.6px;
  border-radius: 0 0 20px 20px;
  transition:
    height 0.5s var(--spring),
    background 0.3s var(--ease);
}
/* The extra height is taken back as negative margin, so the row (and everything under it) never moves. */
.tab:hover {
  height: 64px;
  margin-bottom: -7px;
  background: var(--yellow);
}

/* ---- Page fade: no preloader, the page simply fades up ------------- */
@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
body {
  animation: fade 0.7s var(--ease) both;
}

/* ---- Motion: `appear` on load, `reveal` on scroll ---------------------
   Stagger with `--delay`. Browsers with scroll-driven animations reveal in
   CSS alone; the rest get an IntersectionObserver (scripts/reveal.ts). */
@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.appear {
  animation: rise 0.9s var(--ease) both;
  animation-delay: var(--delay, 0s);
}
.js .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity 0.9s var(--ease),
    transform 0.9s var(--ease);
  transition-delay: var(--delay, 0s);
}
.js .reveal.is-in {
  opacity: 1;
  transform: none;
}
@supports (animation-timeline: view()) {
  .js .reveal,
  .js .reveal.is-in {
    opacity: 1;
    transform: none;
    transition: none;
    animation: rise linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 40%;
  }
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
  .js .reveal,
  .appear {
    opacity: 1;
    transform: none;
  }
}

/* ---- Tablet ----------------------------------------------------------- */
@media (max-width: 899px) {
  .wrap {
    max-width: none;
    padding: 0 var(--gutter);
  }
}

/* ---- Phone ------------------------------------------------------------ */
@media (max-width: 639px) {
  .t-display {
    font-size: 32px;
    line-height: 40px;
    letter-spacing: -0.5px;
  }
  .t-lead {
    font-size: 18px;
    line-height: 27px;
  }
  .t-serif-md {
    font-size: 22px;
    line-height: 32px;
  }
  .tab {
    padding: 14px 14px 0;
    height: 52px;
    font-size: 16px;
  }
  .tab:hover {
    height: 60px;
    margin-bottom: -8px;
  }
}
/* ==========================================================================
   Clips: a screen recording in a device. A phone (a dark bezel with rounded
   corners) or a desktop browser window (a dark chrome with three dots).
   Contexts size them: the carousel, the work cards and the case studies.
   ========================================================================== */
.clip--phone {
  flex: none;
  width: 232px;
  padding: 6px;
  background: var(--bezel);
  border-radius: 42px;
}
.clip--phone video {
  display: block;
  width: 100%;
  aspect-ratio: 1206 / 2622;
  border-radius: 36px;
  background: var(--white);
}
.clip--browser {
  width: 100%;
  padding: 0 5px 5px;
  background: var(--bezel);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.clip__bar {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 9px;
}
.clip__bar i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--bezel-dot);
}
.clip--browser video {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: 10px;
  background: var(--white);
}

@media (max-width: 639px) {
  .clip--phone {
    width: min(220px, 100%);
    border-radius: 38px;
    align-self: center;
  }
  .clip--phone video {
    border-radius: 32px;
  }
}

/* ---- Nav (97px) ------------------------------------------------------ */
.nav {
  height: 97px;
  padding: 0 var(--gutter);
}
.nav__inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 40px;
}
.nav__link {
  color: var(--accent-text);
  font-size: 16px;
  line-height: 22.4px;
  letter-spacing: -0.48px;
  transition: color 0.25s var(--ease);
}
.nav__link:hover {
  color: var(--ink);
}
.logo {
  color: var(--accent);
  display: block;
}
.logo svg {
  width: 104px;
  height: 52px;
}
.logo:hover svg {
  animation: wiggle 0.6s var(--ease);
}
@keyframes wiggle {
  0% {
    transform: rotate(0);
  }
  30% {
    transform: rotate(-5deg);
  }
  60% {
    transform: rotate(4deg);
  }
  100% {
    transform: rotate(0);
  }
}

@media (max-width: 639px) {
  .nav {
    height: 84px;
  }
  .nav__inner {
    gap: 32px;
  }
  .logo svg {
    width: 84px;
    height: 42px;
  }
}

/* ---- Hero (601px under the nav) -------------------------------------- */
.hero {
  position: relative;
  height: 601px;
  text-align: center;
}
.hero__inner {
  position: relative;
  z-index: 1;
  width: 600px;
  margin: 0 auto;
  padding-top: 78px;
}
.hero__doodle {
  margin: 0 auto 28px;
  width: 64px;
  height: 28px;
  color: var(--accent);
}
.hero__eyebrow {
  font-size: 18px;
  line-height: 25.2px;
  letter-spacing: -0.6px;
}
.hero__title {
  margin: 16px -70px 20px;
  font-family: var(--serif);
  font-size: 60px;
  line-height: 70px;
  letter-spacing: -0.8px;
}
.hero__text {
  width: 522px;
  margin: 0 auto;
  font-size: 18px;
  line-height: 25.2px;
  letter-spacing: -0.6px;
}
.hero .btn {
  margin-top: 61px;
} /* where the dashed rule used to sit: 28 + 1 + 32 */
.hero__art {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.fruit {
  position: absolute;
  top: 0;
  width: 600px;
  height: 600px;
}
.fruit--left {
  left: calc(50% - 870px);
  --px: 22px;
} /* -150px at 1440 */
.fruit--right {
  right: max(calc(50% - 924px), -450px);
  --px: -18px;
} /* -204px at 1440; never fully off screen */
.fruit__mouse {
  transform: translate(calc(var(--mx, 0) * var(--px, 24px)), calc(var(--my, 0) * var(--px, 24px)));
  transition: transform 0.7s var(--ease);
  will-change: transform;
}
.fruit svg {
  width: 600px;
  height: 600px;
}
.fruit--left svg {
  animation: float-a 9s ease-in-out infinite;
}
.fruit--right svg {
  animation: float-b 11s ease-in-out infinite;
}
@keyframes float-a {
  0%,
  100% {
    transform: rotate(-3deg) translateY(0);
  }
  50% {
    transform: rotate(3deg) translateY(-12px);
  }
}
@keyframes float-b {
  0%,
  100% {
    transform: rotate(4deg) translateY(0);
  }
  50% {
    transform: rotate(-2deg) translateY(-16px);
  }
}
/* The fruit drift up and away as the page scrolls. */
@supports (animation-timeline: view()) {
  @keyframes drift-away-l {
    to {
      transform: translateY(-160px) rotate(-14deg);
    }
  }
  @keyframes drift-away-r {
    to {
      transform: translateY(-120px) rotate(16deg);
    }
  }
  .fruit--left {
    animation: drift-away-l linear both;
    animation-timeline: scroll(root);
    animation-range: 0 700px;
  }
  .fruit--right {
    animation: drift-away-r linear both;
    animation-timeline: scroll(root);
    animation-range: 0 700px;
  }
}

/* Tablet: the fruit hug the edges, clipped like the reference's flowers, and never sit under the text. */
@media (max-width: 899px) {
  .hero {
    height: auto;
    padding-bottom: 24px;
  }
  .hero__inner {
    width: auto;
    max-width: 600px;
  }
  .hero__title {
    margin-left: 0;
    margin-right: 0;
    font-size: 44px;
    line-height: 52px;
  }
  .hero__text {
    width: auto;
    max-width: 460px;
  }
  .fruit,
  .fruit svg {
    width: 460px;
    height: 460px;
  }
  .fruit--left {
    left: calc(17vw - 460px);
  }
  .fruit--right {
    right: calc(14vw - 460px);
  }
}

/* Phone: text only, no fruit. The hero fills the first screen so the works heading only just peeks in at
   the bottom: nav 84 + works padding 96 + a 48px peek. */
@media (max-width: 639px) {
  .hero {
    padding: 0 var(--gutter) 32px;
    min-height: calc(100vh - 228px);
    min-height: calc(100svh - 228px);
  }
  .hero__inner {
    padding-top: 56px;
  } /* the reference leaves about this much between its nav and the doodle */
  .hero__title {
    font-size: 32px;
    line-height: 40px;
    letter-spacing: -0.5px;
  }
  .hero__text {
    font-size: 17px;
  }
  .hero__art {
    display: none;
  }
}
/* ---- Ticker (598px section) ------------------------------------------ */
.ticker {
  position: relative;
  padding-top: 48px;
  height: 598px;
}
.ticker__sign {
  width: 68px;
  height: 47px;
  margin: 0 auto;
  color: var(--accent);
}
.ticker__title {
  text-align: center;
  margin-top: 18px;
}
/* The pause control sits on the title's line at the right edge; touch screens scroll the strip by hand instead. */
.ticker__pause {
  position: absolute;
  right: var(--gutter);
  top: 113px;
  height: 36px;
  padding: 0 14px;
  font-size: 14px;
}
.ticker__viewport {
  margin-top: 41px;
  overflow: hidden;
}
.ticker__track {
  display: flex;
  gap: 10px;
  width: max-content;
  animation: marquee 130s linear infinite;
}
.ticker__viewport:hover .ticker__track,
.ticker__track.is-paused {
  animation-play-state: paused;
}
@keyframes marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(calc(-50% - 5px));
  }
}
.ticker__item {
  height: 400px;
  flex: none;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--card);
}
/* Phones: the whole device by default, sitting in the middle of a narrow tile... */
.ticker__item--clip {
  width: 256px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ticker__item--clip .clip--phone {
  width: 160px;
  padding: 4px;
  border-radius: 27px;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.14),
    0 0 0 1px rgba(0, 0, 0, 0.18);
}
.ticker__item--clip video {
  border-radius: 23px;
}
/* ...or zoomed right in: a bigger phone that runs off the top or bottom edge of a wider tile. */
.ticker__item--zoom-top,
.ticker__item--zoom-bottom {
  width: 340px;
}
.ticker__item--zoom-top {
  align-items: flex-start;
  padding-top: 36px;
}
.ticker__item--zoom-bottom {
  align-items: flex-end;
  padding-bottom: 36px;
}
.ticker__item--zoom-top .clip--phone,
.ticker__item--zoom-bottom .clip--phone {
  width: 272px;
  padding: 7px;
  border-radius: 46px;
}
.ticker__item--zoom-top video,
.ticker__item--zoom-bottom video {
  border-radius: 39px;
}
.ticker__item--browser {
  width: 560px;
  padding: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ticker__item--browser .clip--browser {
  width: 512px;
  border-radius: 12px;
}
.ticker__item--browser .clip--browser video {
  border-radius: 7px;
}
.ticker__card {
  width: 331px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px;
  color: var(--text);
  font-family: var(--serif);
  font-size: 30px;
  line-height: 1.3;
  letter-spacing: -0.4px;
}
.ticker__card small {
  display: block;
  font-family: var(--sans);
  font-size: 14px;
  letter-spacing: 0;
  margin-top: 14px;
  color: var(--text-2);
}
.ticker__card svg {
  width: 96px;
  height: 96px;
  margin-bottom: 20px;
}
/* Without a hover (touch) or without motion, the strip stands still and scrolls by hand. */
@media (hover: none), (prefers-reduced-motion: reduce) {
  .ticker__viewport {
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    padding: 0 var(--gutter);
  }
  .ticker__viewport::-webkit-scrollbar {
    display: none;
  }
  .ticker__track {
    animation: none;
  }
  .ticker__item {
    scroll-snap-align: center;
  }
  .ticker__pause {
    display: none;
  }
}

@media (max-width: 899px) {
  .ticker {
    height: auto;
    padding-bottom: 8px;
  }
}
/* Phone: the workshop ticker is skipped altogether, like the reference. */
@media (max-width: 639px) {
  .ticker {
    display: none;
  }
}
/* ---- Works: rows of a card beside two tiles -------------------------- */
.works {
  padding: 120px 0 32px;
}
.works--page {
  padding-top: 24px;
}
.rows {
  display: grid;
  gap: 16px;
  margin-top: 64px;
}
.row {
  display: grid;
  grid-template-columns: 616px 192px;
  gap: 16px;
  align-items: start;
}
.row--flip {
  grid-template-columns: 192px 616px;
}
.row--flip .card {
  order: 2;
}
.row--flip .tiles {
  order: 1;
}
.tiles {
  display: grid;
  gap: 16px;
}
.tile {
  width: 192px;
  height: 192px;
  border-radius: var(--r-lg);
  background: var(--white);
  display: grid;
  place-items: center;
}
.tile--tall {
  height: 207px;
}
.tile--blue {
  background: var(--blue);
}
.tile--pink {
  background: var(--pink);
}
.tile--yellow {
  background: var(--yellow);
}
.tile svg {
  width: 80px;
  height: 80px;
  transition: transform 0.8s var(--spring);
}
.tile:hover svg {
  transform: rotate(40deg) scale(1.08);
}
/* A project logo in the white tile: an app-icon square. It stays put on hover; only the fruit spins. */
.tile__logo {
  width: 120px;
  height: 120px;
  border-radius: 27px;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.tile__logo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---- Card ------------------------------------------------------------ */
.card {
  position: relative;
  display: block;
  width: 616px;
  height: 415px;
  background: var(--card);
  border-radius: var(--r-lg);
  overflow: hidden;
  color: var(--ink);
  isolation: isolate;
  container-type: inline-size;
}
.card__pics {
  position: absolute;
  left: 32px;
  top: 28px;
  width: 552px;
  height: 313px;
  z-index: 0;
}
/* Hidden once the colour has covered them. */
.card:hover .card__pics,
.card:hover .card__shots,
.card:focus-visible .card__pics,
.card:focus-visible .card__shots {
  opacity: 0;
  transition: opacity 0s linear 0.24s;
}
/* Shots in the carousel's style: a wide and a narrow tile, sized in card widths so they scale with the card. */
.card__shots {
  position: absolute;
  left: 5.2cqw;
  top: 4.55cqw;
  width: 89.6cqw;
  height: 50.8cqw;
  z-index: 0;
  display: grid;
  grid-template-columns: 330fr 206fr;
  gap: 2.6cqw;
}
.shot {
  border-radius: 3.9cqw;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4cqw;
}
.shot .clip--phone {
  width: 19.5cqw;
  padding: 0.65cqw;
  border-radius: 4.4cqw;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.14),
    0 0 0 1px rgba(0, 0, 0, 0.18);
}
.shot .clip--phone video {
  border-radius: 3.7cqw;
}
.shot .clip--browser {
  width: 90%;
  border-radius: 12px;
}
.shot .clip--browser video {
  border-radius: 7px;
}
.shot--zoom-top {
  align-items: flex-start;
  padding-top: 4cqw;
}
.shot--zoom-bottom {
  align-items: flex-end;
  padding-bottom: 4cqw;
}
.shot--zoom-top .clip--phone,
.shot--zoom-bottom .clip--phone {
  width: 29.5cqw;
  padding: 1cqw;
  border-radius: 7cqw;
}
.shot--zoom-top .clip--phone video,
.shot--zoom-bottom .clip--phone video {
  border-radius: 6cqw;
}
/* Springs from the top-left on hover and fills the card; shrinks into the bottom-left on leave. */
.card__bubble {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* A plain div, not an SVG: Safari composites transformed SVGs unreliably. */
  background: var(--bubble, var(--yellow));
  border-radius: var(--r-lg);
  transform: scale(0);
  transform-origin: 6% 94%;
  transition: transform 0.28s cubic-bezier(0.3, 0.9, 0.3, 1);
  pointer-events: none;
}
.card__text {
  position: absolute;
  left: 32px;
  top: 28px;
  width: 552px;
  z-index: 2;
  font-family: var(--serif);
  font-size: 26px;
  line-height: 36px;
  letter-spacing: -0.4px;
  color: var(--ink);
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 0.12s linear,
    transform 0.25s var(--ease);
  pointer-events: none;
}
.card__line {
  position: absolute;
  left: 32px;
  top: 351px;
  width: 552px;
  height: 36px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 10px;
}
.card__line h2,
.card__line h3 {
  font-size: 24px;
  line-height: 36px;
  letter-spacing: -0.96px;
}
.card__tag {
  font-size: 24px;
  line-height: 36px;
  letter-spacing: -0.96px;
  opacity: 0.5;
}
.card__chevron {
  position: absolute;
  right: 0;
  top: 2px;
  width: 32px;
  height: 32px;
  color: var(--ink);
  opacity: 0;
  transform: translateX(-8px);
  transition:
    opacity 0.15s linear,
    transform 0.35s var(--spring);
}
.card:hover .card__bubble,
.card:focus-visible .card__bubble {
  transform: scale(1);
  transform-origin: 8% 8%;
  transition-duration: 0.22s;
}
.card:hover .card__text,
.card:focus-visible .card__text {
  opacity: 1;
  transform: none;
  transition-delay: 0.06s;
}
.card:hover .card__chevron,
.card:focus-visible .card__chevron {
  opacity: 1;
  transform: none;
}
.card--blue:hover .card__text,
.card--blue:hover .card__line {
  color: var(--white);
}
.frame {
  position: absolute;
  background: var(--white);
  border-radius: var(--r-md);
  padding: 9px;
  transform: rotate(var(--r, 0deg)) translateY(var(--py, 0px));
  transition: transform 0.7s var(--ease);
  will-change: transform;
}
.frame img,
.frame video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--r-sm);
}
/* A tinted square frame shows the whole picture on its colour. */
.frame--tinted {
  background: var(--tint);
}
.frame--tinted img,
.frame--tinted video {
  object-fit: contain;
}
/* Arrangement A: wide top-left, square bottom-right. B: square top-left, wide bottom-right. */
/* Measured from the four reference cards. */
.card--a .frame--wide {
  left: 0;
  top: 0;
  width: 419px;
  height: 279px;
  --r: -6deg;
}
.card--a .frame--square {
  left: 299px;
  top: 92px;
  width: 258px;
  height: 258px;
  --r: 5deg;
}
.card--a2 .frame--wide {
  left: 8px;
  top: 2px;
  width: 416px;
  height: 277px;
  --r: -5deg;
}
.card--a2 .frame--square {
  left: 283px;
  top: 72px;
  width: 269px;
  height: 269px;
  --r: 8deg;
}
.card--b .frame--square {
  left: 1px;
  top: -1px;
  width: 265px;
  height: 265px;
  --r: -7deg;
}
.card--b .frame--wide {
  left: 128px;
  top: 44px;
  width: 422px;
  height: 285px;
  --r: 7deg;
}

.callout {
  height: 98.4px;
  background: var(--card);
  border-radius: 120px;
  padding: 24px 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.callout p {
  font-size: 18px;
  line-height: 25.2px;
  letter-spacing: -0.18px;
  font-weight: 500;
  width: 456px;
}
.callout .btn {
  flex: none;
} /* overflow: hidden would otherwise let it shrink and clip its label */
.more {
  margin-top: 48px;
  color: var(--ink-3);
  font-size: 18px;
  letter-spacing: -0.6px;
}

/* ---- Work cards without hover: the description sits under the title ------
   The reference does this below 1440 and on touch; here it is tablet, phone
   and any touch screen, so the blurb is never locked behind a hover. */
@media (max-width: 899px), (hover: none) {
  .card {
    display: flex;
    flex-direction: column;
    height: auto;
  }
  .card__pics {
    position: relative;
    left: auto;
    top: auto;
    width: auto;
    height: 313px;
    margin: 28px 32px 0;
    order: 1;
  }
  .card__shots {
    position: relative;
    left: auto;
    top: auto;
    width: auto;
    margin: 4.55cqw 5.2cqw 0;
    order: 1;
  }
  .card__line {
    position: relative;
    left: auto;
    top: auto;
    width: auto;
    height: auto;
    margin: 10px 32px 0;
    order: 2;
  }
  .card__text {
    position: relative;
    left: auto;
    top: auto;
    width: auto;
    margin: 4px 32px 28px;
    order: 3;
    opacity: 1;
    transform: none;
    transition: none;
    font-family: var(--sans);
    font-size: 16px;
    line-height: 23px;
    letter-spacing: -0.16px;
    color: rgba(0, 0, 0, 0.72);
  }
  .card__bubble,
  .card__chevron {
    display: none;
  }
  .card:hover .card__pics,
  .card:hover .card__shots,
  .card:focus-visible .card__pics,
  .card:focus-visible .card__shots {
    opacity: 1;
    transition: none;
  }
  .card--blue:hover .card__text {
    color: rgba(0, 0, 0, 0.72);
  }
  .card--blue:hover .card__line {
    color: var(--ink);
  }
}

/* ---- Tablet: rows keep the card beside its tile column; the card's geometry is in container units. */
@media (max-width: 899px) {
  .rows {
    margin-top: 48px;
  }
  .row {
    grid-template-columns: minmax(0, 1fr) clamp(120px, 22%, 192px);
  }
  .row--flip {
    grid-template-columns: clamp(120px, 22%, 192px) minmax(0, 1fr);
  }
  .tile,
  .tile--tall {
    width: auto;
    height: auto;
    aspect-ratio: 1;
    border-radius: min(40px, 21%);
  }
  .tile--tall {
    aspect-ratio: 192 / 207;
  }
  .tile svg {
    width: 42%;
    height: auto;
    aspect-ratio: 1;
  }
  .tile__logo {
    width: 62%;
    height: auto;
    aspect-ratio: 1;
    border-radius: 23%;
  }
  .card {
    width: auto;
    max-width: none;
    border-radius: clamp(24px, 6.5cqw, 40px);
    container-type: inline-size;
  }
  /* Tall enough for the rotated square, which hangs below the wide picture, so it never sits on the title. */
  .card__pics {
    margin: 4.5cqw 5.2cqw 0;
    height: 57cqw;
  }
  .card__line {
    margin: 2cqw 5.2cqw 0;
  }
  .card__text {
    margin: 0.8cqw 5.2cqw 4.5cqw;
  }
  .card__line h2,
  .card__line h3,
  .card__tag {
    font-size: clamp(19px, 3.9cqw, 24px);
    line-height: 1.5;
    letter-spacing: -0.04em;
  }
  .frame {
    padding: max(5px, 1.46cqw);
    border-radius: max(14px, 3.9cqw);
  }
  .frame img,
  .frame video {
    border-radius: max(9px, 2.6cqw);
  }
  .card--a .frame--wide {
    width: 68cqw;
    height: 45.3cqw;
  }
  .card--a .frame--square {
    left: 48.5cqw;
    top: 14.9cqw;
    width: 41.9cqw;
    height: 41.9cqw;
  }
  .card--a2 .frame--wide {
    left: 1.3cqw;
    top: 0.3cqw;
    width: 67.5cqw;
    height: 45cqw;
  }
  .card--a2 .frame--square {
    left: 45.9cqw;
    top: 11.7cqw;
    width: 43.7cqw;
    height: 43.7cqw;
  }
  .card--b .frame--square {
    left: 0.2cqw;
    top: -0.2cqw;
    width: 43cqw;
    height: 43cqw;
  }
  .card--b .frame--wide {
    left: 20.8cqw;
    top: 7.1cqw;
    width: 68.5cqw;
    height: 46.3cqw;
  }
  .callout p {
    width: auto;
    flex: 1 1 auto;
  }
}

/* ---- Phone, matched to the reference at 390: a centred heading, 12px margins, 32px radius, 32px between
   cards, big tilted pictures that run off the sides, a 24/36 title line and a 16/22.4 blurb. */
@media (max-width: 639px) {
  .works {
    padding: 96px 0 24px;
  }
  .works--page {
    padding-top: 24px;
  }
  .works .wrap {
    padding: 0 12px;
  }
  .works .section__head {
    text-align: center;
  }
  .rows {
    margin-top: 40px;
    gap: 32px;
  }
  .row,
  .row--flip {
    grid-template-columns: 1fr;
  }
  .tiles {
    display: none;
  }
  .card {
    border-radius: 32px;
  }
  .card__shots {
    display: block;
    margin: 0;
    height: 76cqw;
  }
  .shot {
    position: absolute;
  }
  /* Explicit heights, not aspect-ratio: WebKit lets an aspect-ratio box grow to its content, and the zoomed phone is taller than the tile. */
  .shot--wide {
    left: -8cqw;
    top: 3cqw;
    width: 76cqw;
    height: 57cqw;
    rotate: -6deg;
  }
  .shot--narrow {
    right: -8cqw;
    top: 12cqw;
    width: 51cqw;
    height: 51cqw;
    rotate: 5deg;
    z-index: 1;
  }
  .shot {
    box-shadow: 0 0 0 8px var(--white);
  }
  .card__pics {
    margin: 0;
    height: 76cqw;
  }
  .card__line {
    margin: 0 24px;
  }
  .card__line h2,
  .card__line h3,
  .card__tag {
    font-size: 24px;
    line-height: 36px;
    letter-spacing: -0.96px;
  }
  .card__text {
    margin: 6px 24px 20px;
    font-size: 16px;
    line-height: 22.4px;
    letter-spacing: -0.16px;
    color: var(--ink);
  }
  .callout {
    height: auto;
    border-radius: 32px;
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
    padding: 24px;
  }
  .callout p {
    font-size: 16px;
    line-height: 22.4px;
    letter-spacing: -0.16px;
    font-weight: 400;
  }
  .more {
    margin-top: 32px;
  }
}
/* ---- Services: a recipe card pinned to the board ---------------------
   The About photos' white mat and red pegs, grid paper inside, and four
   stickers over the right side. Sticker positions and sizes are cqw of the paper. */
.services {
  padding: 100px 0 120px;
}
.recipe {
  position: relative;
  padding: 4px;
  container-type: inline-size;
  background: var(--white);
  box-shadow: var(--shadow-r);
  rotate: -1deg;
  transform-origin: 50% 0;
}
.recipe__peg {
  position: absolute;
  width: 14px;
  height: 14px;
  background: var(--accent);
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.18);
  z-index: 3;
}
.recipe__wrap {
  margin-top: 64px;
}
.recipe__paper {
  position: relative;
  min-height: 48.5cqw;
  padding: 44px 48px;
  container-type: inline-size;
  background:
    linear-gradient(var(--grid) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, var(--grid) 1px, transparent 1px) 0 0 / 24px 24px,
    var(--white);
}
.recipe__title {
  font-family: var(--serif);
  font-size: 30px;
  line-height: 38px;
  letter-spacing: -0.5px;
}
.recipe__serves {
  margin-top: 8px;
  font-size: 14px;
  line-height: 20px;
  letter-spacing: -0.1px;
  color: var(--ink-soft);
}
.recipe__list {
  width: 300px;
  margin-top: 28px;
  padding-top: 28px;
  border-top: 1.5px dashed var(--line);
}
.recipe__label {
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.recipe__items {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 18px;
}
.recipe__item {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  column-gap: 14px;
  align-items: center;
  font-family: var(--serif);
  font-size: 20px;
  line-height: 26px;
  letter-spacing: -0.4px;
}
.recipe__fruit {
  width: 28px;
  height: 28px;
  transition: transform 0.7s var(--spring);
}
.recipe__item:hover .recipe__fruit {
  transform: rotate(-12deg) scale(1.15);
}
.decals {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.decal {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--w);
  pointer-events: auto;
  z-index: 2;
  --fold: 0px;
  rotate: var(--r);
  transition:
    rotate 0.6s var(--spring),
    scale 0.6s var(--spring),
    --fold 0.5s var(--ease);
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.28)) drop-shadow(0 6px 12px rgba(0, 0, 0, 0.12));
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
.decal svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  pointer-events: none;
}
/* The peel: the face is clipped along a fold across the bottom-right corner, and the paper back is the
   same shape mirrored across that fold (x + y = 2S - fold) and clipped to the flap. --fold is the peel depth. */
.decal__face {
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--fold)), calc(100% - var(--fold)) 100%, 0 100%);
}
.decal__back {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform-origin: 0 0;
  transform: translate(calc(200% - var(--fold)), calc(200% - var(--fold))) matrix(0, -1, -1, 0, 0, 0);
  clip-path: polygon(100% 100%, 100% calc(100% - var(--fold)), calc(100% - var(--fold)) 100%);
}
@media (hover: hover) {
  .decal:hover {
    --fold: var(--peel);
  }
  .decal:hover .decal__gloss {
    transition: transform 0.9s var(--ease);
    transform: translateX(220px) skewX(-22deg);
  }
}
/* Grabbing lifts it (and lays the corner back down); the gloss band rests off the shape and jumps back hidden. */
.decal.is-dragging {
  --fold: 0px;
  rotate: 0deg;
  scale: 1.08;
  cursor: grabbing;
  z-index: 5;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.3)) drop-shadow(0 16px 24px rgba(0, 0, 0, 0.16));
}
.decal__gloss {
  transition: none;
}

/* Tablet: the card scales with the column; the sticker cluster scales with it. */
@media (max-width: 899px) {
  .recipe__wrap {
    margin-top: 40px;
  }
  .recipe__paper {
    padding: 32px 32px;
  }
}
/* Phone: stickers drop into a row under the list. */
@media (max-width: 639px) {
  .services {
    padding: 72px 0 88px;
  }
  .recipe__paper {
    min-height: 0;
    padding: 28px 24px 32px;
  }
  .recipe__list {
    width: auto;
  }
  .decals {
    position: static;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px 18px;
    margin-top: 32px;
  }
  .decal {
    position: static;
    width: calc(var(--px) * 0.72);
    touch-action: pan-y;
  }
}
/* ---- About: two boards of pinned photos beside the copy -------------- */
.about {
  padding: 16px 0 112px;
}
.about__row {
  display: grid;
  grid-template-columns: 396px 396px;
  column-gap: 32px;
  align-items: start;
  margin-top: 40px;
}
.about__row--flip {
  grid-template-columns: 396px 396px;
  align-items: center;
  margin-top: 24px;
}
.about__text {
  display: grid;
  gap: 20px;
  padding-top: 4.7px;
}
.about__row--flip .about__text {
  padding-top: 0;
}
.about__text p {
  font-size: 18px;
  line-height: 25.2px;
  letter-spacing: -0.6px;
}
.about .rule {
  margin-top: 24px;
}
.board {
  position: relative;
  width: 408px;
  aspect-ratio: 408 / 230;
  margin-left: -6px;
  container-type: inline-size;
}
/* Positions are reference pixels on a 408-wide board; --u is one of them, so the board scales as one piece. */
.board > * {
  --u: calc(100cqw / 408);
}
.board__art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.photo {
  --r: 0deg;
  --x: 0;
  --y: 0;
  position: absolute;
  left: calc(var(--x) * var(--u));
  top: calc(var(--y) * var(--u));
  width: calc(106 * var(--u));
  height: calc(124 * var(--u));
  background: var(--white);
  border-radius: calc(12 * var(--u));
  padding: calc(4 * var(--u));
  box-shadow: var(--shadow-l);
  transform: rotate(var(--r));
}
.photo--r {
  box-shadow: var(--shadow-r);
}
.photo__img {
  width: 100%;
  height: 100%;
  border-radius: calc(8 * var(--u));
  overflow: hidden;
}
.photo__img svg,
.photo__img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.peg {
  position: absolute;
  left: calc(var(--x) * var(--u));
  top: calc(var(--y) * var(--u));
  width: calc(7 * var(--u));
  height: calc(12 * var(--u));
  background: var(--red);
  border-radius: 1px;
  z-index: 1;
}

@media (max-width: 899px) {
  .about__row,
  .about__row--flip {
    grid-template-columns: minmax(0, 1fr);
  }
  .board {
    margin-left: 0;
    max-width: 100%;
  }
}
/* Phone: each board follows its paragraphs. */
@media (max-width: 639px) {
  .about {
    padding-bottom: 88px;
  }
  .about__row {
    margin-top: 32px;
    row-gap: 24px;
  }
  .about__text {
    display: contents;
  }
  .about__row:not(.about__row--flip) .board {
    order: 1;
  }
}
/* ---- Contact (824 × 481, radius 40) ---------------------------------- */
.contact {
  padding-top: 0;
}
.contact__block {
  position: relative;
  width: 824px;
  height: 481px;
  margin: 0 auto;
  background: var(--accent);
  color: var(--white);
  border-radius: var(--r-lg);
  overflow: hidden;
  text-align: center;
}
.contact :focus-visible {
  outline-color: var(--white);
} /* the accent outline would vanish on the accent block */
.contact__mark {
  position: absolute;
  left: 50%;
  top: 122px;
  width: 64px;
  height: 50px;
  margin-left: -32px;
  transform-origin: 50% 50%;
}
.contact__block:hover .contact__mark {
  animation: wobble 1s var(--ease);
}
@keyframes wobble {
  0%,
  100% {
    transform: rotate(0);
  }
  25% {
    transform: rotate(-10deg) translateY(-4px);
  }
  50% {
    transform: rotate(8deg) translateY(-6px);
  }
  75% {
    transform: rotate(-4deg) translateY(-2px);
  }
}
.contact__kicker {
  position: absolute;
  left: 0;
  right: 0;
  top: 216px;
  color: var(--white);
}
.contact__big {
  position: absolute;
  left: 24px;
  right: 24px;
  bottom: 0;
  height: 141px;
  font-size: 144.24px;
  line-height: 140px;
  letter-spacing: -5px;
  color: var(--white);
  white-space: nowrap;
  transition: transform 0.7s var(--spring);
}
.contact__big:hover {
  transform: translateY(-6px);
}
@supports (animation-timeline: view()) {
  .contact__big {
    animation: rise linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 60%;
  }
}

/* Tablet: 32px in from the edges, the block grows to its content (704 × 459 at 768), and the big line
   scales to the block's inner width: 144px type is 771px wide, so 0.1868 of the width. */
@media (max-width: 899px) {
  .contact {
    padding: 0 32px;
  }
  .contact__block {
    width: 100%;
    height: auto;
    padding: 100px 24px 0;
  }
  .contact__mark {
    position: static;
    margin: 22px auto 0;
  }
  .contact__kicker {
    position: static;
    margin: 44px auto 0;
  }
  .contact__big {
    position: static;
    display: block;
    height: auto;
    margin-top: 88px;
    font-size: calc((100vw - 112px) * 0.1868);
    line-height: 0.975;
    letter-spacing: -0.0347em;
  }
}
/* Phone: 12px in from the edges, 351 × 344 at 375 (near square), the line scaled to the inner width.
   The kicker stays at 24px: white on the red is 3.9:1, which passes only as large text. */
@media (max-width: 639px) {
  .contact {
    padding: 0 12px;
  }
  .contact__block {
    padding: 64px 16px 12px;
    border-radius: 32px;
  }
  .contact__kicker {
    font-size: 24px;
    line-height: 32px;
  }
  .contact__big {
    margin-top: 64px;
    font-size: calc((100vw - 56px) * 0.1868);
  }
}
/* ---- Footer: tabs + fruit field -------------------------------------- */
.footer {
  text-align: center;
}
.footer__tabs {
  display: flex;
  justify-content: center;
  gap: 16px;
  height: 64px;
}
/* Each row is wider than the page and centred, so it spills evenly on both sides at any width (like the reference). */
.field {
  margin-top: 88px;
  height: 900px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.field__row {
  display: flex;
  justify-content: center;
  height: 180px;
  flex: none;
}
.field__row--text {
  align-items: center;
}
.field__row--extra {
  display: none;
} /* two more rows, phone only */
.cell {
  width: 180px;
  height: 180px;
  flex: none;
  display: grid;
  place-items: center;
}
.cell--text {
  width: 316.8px;
}
.field__line {
  width: 80%;
  margin: 0 auto;
  text-align: center;
}
.bloom {
  width: 150px;
  height: 150px;
}
.bloom svg {
  width: 100%;
  height: 100%;
  rotate: var(--turn);
  transition:
    rotate 0.8s var(--spring),
    scale 0.8s var(--spring);
}
.cell:hover .bloom svg {
  rotate: calc(var(--turn) + 36deg);
  scale: 1.12;
}
@supports (animation-timeline: view()) {
  @keyframes turn {
    from {
      --turn: -20deg;
    }
    to {
      --turn: 24deg;
    }
  }
  .bloom svg {
    animation: turn linear both;
    animation-timeline: view();
  }
}

/* Tablet: 150px cells, 120px fruit, five rows (750px), the caption cell 384 wide. */
@media (max-width: 899px) {
  .footer__tabs {
    flex-wrap: wrap;
    height: auto;
    padding: 0 12px;
  }
  .field {
    height: 750px;
  }
  .field__row {
    height: 150px;
  }
  .cell {
    width: 150px;
    height: 150px;
  }
  .cell--text {
    width: 384px;
  }
  .bloom {
    width: 120px;
    height: 120px;
  }
}
/* Phone: 80px cells, 50px fruit, seven rows (560px), the caption fourth with fruit either side of it. */
@media (max-width: 639px) {
  .footer__tabs {
    gap: 8px;
  }
  .tab--works {
    display: none;
  } /* five tabs wrap onto a second line; the nav has the link anyway */
  .field {
    margin-top: 56px;
    height: 560px;
  }
  .field__row {
    height: 80px;
  }
  .field__row--extra {
    display: flex;
  }
  .field__row--extra-top {
    order: -1;
  }
  .cell {
    width: 80px;
    height: 80px;
  }
  .cell--text {
    width: 219px;
  }
  .bloom {
    width: 50px;
    height: 50px;
  }
  .field__line {
    width: 100%;
    font-size: 16px;
    line-height: 24px;
  }
}
/* ==========================================================================
   Case study (measured: 720px text column, 40px page gutter, 668px outline
   blocks, 1360×750 frames, 666px squares).
   ========================================================================== */
.cs {
  position: relative;
  display: flex;
  flex-direction: column;
}
.cs__text {
  width: 720px;
  padding: 80px 40px 64px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.cs__text--body {
  padding: 80px 40px;
  gap: 16px;
}
.cs__title {
  font-family: var(--serif);
  font-size: 40px;
  line-height: 52px;
  letter-spacing: -0.6px;
  width: 640px;
}
.cs__sub {
  width: 448px;
  font-size: 18px;
  line-height: 25.2px;
  letter-spacing: -0.18px;
  font-weight: 500;
}
.cs__blocks {
  display: flex;
  gap: 24px;
  padding: 24px 40px;
}
.cs__blocks--pics {
  flex-direction: column;
  gap: 0;
}
.cs__block {
  flex: 1 1 0;
  min-width: 0;
  border-radius: var(--r-md);
  padding: 32px 40px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.cs__block--outline {
  border: 1px solid var(--card);
}
.cs__block--white {
  background: var(--white);
}
.cs__block--full {
  flex-basis: 100%;
}
.cs__block--tall {
  min-height: 374.8px;
}
.cs__block--centre {
  align-items: center;
  justify-content: center;
}
.cs__block--closing {
  align-items: center;
  justify-content: center;
  gap: 32px;
  padding: 96px 40px;
  min-height: 330px;
}
.cs__block-title {
  font-size: 24px;
  line-height: 33.6px;
  letter-spacing: -0.96px;
  font-weight: 500;
}
.cs__list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.cs__list p,
.cs__intro,
.cs__paras p,
.cs__item-text,
.cs__item-title,
.cs__nda {
  font-size: 18px;
  line-height: 25.2px;
  letter-spacing: -0.18px;
  font-weight: 500;
}
.cs__list p,
.cs__intro,
.cs__nda {
  color: var(--ink-2);
}
.cs__list a {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cs__intro {
  width: 533px;
  max-width: 100%;
}
.cs__block--tall .cs__intro {
  margin-bottom: auto;
}
.cs__kicker {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-top: 62px;
}
.cs__fruit {
  width: 48px;
  height: 48px;
}
.cs__h1 {
  font-family: var(--serif);
  font-size: 40px;
  line-height: 52px;
  letter-spacing: -0.6px;
}
.cs__logo {
  width: 190px;
  height: auto;
  border-radius: 22px;
}
.cs__mark {
  width: 190px;
  height: 190px;
  border-radius: 42px;
  overflow: hidden;
  display: block;
}
.cs__mark img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cs__wide {
  padding: 24px 40px 0;
}
.cs__frame {
  width: 100%;
  height: 750px;
  border-radius: var(--r-md);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.cs__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cs__frame--white {
  background: var(--white);
}
.cs__frame--pad {
  padding: 64px 64px 0;
}
.cs__frame--pad img {
  height: auto;
  max-height: 100%;
  border-radius: 16px 16px 0 0;
  object-fit: cover;
  object-position: top;
}
.cs__frame--centre {
  align-items: center;
  padding: 0 64px;
}
.cs__frame--centre .cs__inset {
  width: 844px;
  height: auto;
  border-radius: var(--r-sm);
}
.cs__frame--tall {
  height: auto;
  display: block;
}
.cs__frame--tall img {
  height: auto;
}
.cs__squares {
  display: flex;
  gap: 24px;
}
.cs__square {
  flex: 1 1 0;
  aspect-ratio: 1;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--card);
}
.cs__square img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cs__caption {
  padding: 14px 8px 0;
  font-size: 15px;
  line-height: 21px;
  letter-spacing: -0.15px;
  font-weight: 500;
  color: var(--ink-3);
}
.cs__label {
  font-size: 24px;
  line-height: 33.6px;
  letter-spacing: -0.96px;
  font-weight: 500;
}
.cs__label--spaced {
  margin-top: 56px;
}
.cs__paras {
  width: 500px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.cs__paras p {
  color: var(--ink-2);
}
.cs__text--approach {
  width: 100%;
}
.cs__approach {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 28px 48px;
  margin-top: 8px;
}
.cs__item {
  display: flex;
  gap: 12px;
}
.cs__bullet {
  width: 18px;
  height: 25px;
  flex: none;
}
.cs__item-title {
  color: var(--ink);
}
.cs__item-text {
  color: var(--ink-2);
}
.cs__nav {
  display: flex;
  justify-content: space-between;
  padding: 0 88px 40px;
  margin-top: 0;
} /* The tabs hang straight off the last frame, like the footer tabs hang off the footer. */

/* Clips in a frame: up to three phones (or one browser window) centred on a tint. */
.cs__frame--clips {
  align-items: center;
  justify-content: center;
  gap: 56px;
}
.cs__frame--clips .clip--phone {
  width: min(264px, 28%);
}
.cs__frame--clips:has(.clip--phone:nth-child(4)) .clip--phone {
  width: min(250px, 21%);
}
.cs__frame--clips:has(.clip--phone:nth-child(4)) {
  gap: 36px;
}
.cs__frame--clips .clip--browser {
  width: min(1080px, 84%);
}

/* Feature cards: a wide card and a narrow one per row, swapping sides each row. Wide: text beside the whole
   phone. Narrow: text on top, a bigger phone running off the bottom edge. Nothing tilts. */
.cs__features {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  padding: 24px 40px;
}
.cs__feature {
  display: flex;
  align-items: center;
  gap: 28px;
  border-radius: var(--r-md);
  padding: 40px 36px 40px 40px;
  min-height: 520px;
  overflow: hidden;
}
.cs__feature--wide {
  grid-column: span 2;
}
.cs__feature--narrow {
  grid-column: span 1;
  flex-direction: column;
  align-items: center;
  gap: 0;
  padding: 40px 36px 0;
}
.cs__feature--narrow .cs__feature-text {
  flex: none;
  align-self: stretch;
}
.cs__feature--narrow .clip--phone {
  width: 296px;
  margin-top: 32px;
  margin-bottom: -420px;
  border-radius: 52px;
}
.cs__feature--narrow .clip--phone video {
  border-radius: 46px;
}
.cs__feature--browser {
  flex-direction: column;
  align-items: stretch;
  gap: 24px;
  padding: 36px 36px 30px 40px;
}
.cs__feature--browser .cs__feature-text {
  flex: none;
}
.cs__feature-text {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* The number takes the card's secondary text colour so it reads on every wash; outline cards on cream use the accent. */
.cs__feature-num {
  font-size: 14px;
  line-height: 20px;
  letter-spacing: 0.4px;
  color: var(--text-2);
  font-weight: 500;
}
.cs__block--outline .cs__feature-num {
  color: var(--accent-text);
  opacity: 1;
}
.cs__feature-title {
  font-family: var(--serif);
  font-size: 28px;
  line-height: 36px;
  letter-spacing: -0.5px;
}
.cs__feature-body {
  font-size: 17px;
  line-height: 24px;
  letter-spacing: -0.17px;
  font-weight: 500;
  color: var(--text-2);
}

/* Engineering notes: a grid of short outline blocks. */
.cs__tech {
  padding: 56px 40px 24px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.cs__tech-label {
  padding: 0 0 8px;
}
.cs__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}
.cs__cell {
  padding: 28px 32px;
  gap: 10px;
}
.cs__cell-title {
  font-size: 20px;
  line-height: 28px;
  letter-spacing: -0.4px;
  font-weight: 500;
  color: var(--ink);
}
.cs__cell-text {
  font-size: 16px;
  line-height: 22.4px;
  letter-spacing: -0.16px;
  font-weight: 500;
  color: var(--ink-2);
}

/* Built with: a paper tag hangs off the top of the page at the right. Pull it and the clotheslines unfurl
   under the title, one per group, with the tools pegged to them, dropping in one by one and swaying. */
.kit__btn {
  position: absolute;
  top: 84px;
  right: 40px;
  z-index: 5;
  height: 40px;
  padding: 0 16px 0 14px;
  font-size: 16px;
}
.kit__icon {
  width: 18px;
  height: 18px;
}
/* the lines: a strip in the page flow that opens to its height */
.kit__lines {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.7s var(--spring);
}
.kit__lines.is-open {
  grid-template-rows: 1fr;
}
.kit__inner {
  overflow: hidden;
  min-height: 0;
  padding: 0 40px;
  display: flex;
  flex-direction: column;
}
.kit__lines.is-open .kit__inner {
  padding-bottom: 8px;
}
.line {
  position: relative;
  padding: 12px 0 0 92px;
  min-height: 96px;
  color: var(--ink);
}
.line__string {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 24px;
  overflow: visible;
  clip-path: inset(-4px 100% -4px 0);
  transition: clip-path 0.9s var(--ease);
  transition-delay: calc(var(--g) * 120ms);
}
.kit__lines.is-open .line__string {
  clip-path: inset(-4px 0 -4px 0);
}
.line__label {
  position: absolute;
  left: 0;
  top: 4px;
  padding: 3px 10px;
  border-radius: 8px;
  background: var(--white);
  border: 1.5px solid var(--ink);
  font-size: 12px;
  line-height: 16px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  font-weight: 500;
  opacity: 0;
  transform: translateY(-10px);
  transition:
    opacity 0.4s var(--ease),
    transform 0.7s var(--spring);
  transition-delay: calc(var(--g) * 120ms + 150ms);
}
.kit__lines.is-open .line__label {
  opacity: 1;
  transform: none;
}
.line__pins {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0 18px;
}
.pin {
  position: relative;
  flex: none;
  margin-top: var(--t);
  opacity: 0;
  transform: translateY(-28px);
  transition:
    opacity 0.4s var(--ease),
    transform 0.9s var(--spring);
  transition-delay: calc(var(--g) * 120ms + 200ms + var(--i) * 55ms);
}
.kit__lines.is-open .pin {
  opacity: 1;
  transform: none;
}
/* the thread up to the string, the peg on the string, and the paper swinging from the peg */
.pin__peg {
  position: absolute;
  left: 50%;
  top: calc(-1 * var(--t) - 6px);
  width: 7px;
  height: 13px;
  margin-left: -3.5px;
  border-radius: 3px;
  background: var(--mango-light);
  border: 1.5px solid var(--ink);
  z-index: 1;
}
.pin__paper {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 34px;
  padding: 0 14px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--paper) 42%, var(--white));
  border: 1.5px solid rgba(0, 0, 0, 0.16);
  font-size: 15px;
  letter-spacing: -0.15px;
  font-weight: 500;
  white-space: nowrap;
  transform-origin: 50% calc(-1 * var(--t));
  animation: sway calc(3.2s + var(--i) * 0.23s) ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -0.7s);
  transition: transform 0.6s var(--spring);
}
/* The string is part of the pill, so it swings and tilts with it and never comes away from the peg. */
.pin__paper::before {
  content: '';
  position: absolute;
  left: 50%;
  top: calc(-1 * var(--t) - 2px);
  width: 1.5px;
  height: calc(var(--t) + 2px);
  margin-left: -0.75px;
  background: var(--ink);
}
.pin:hover .pin__paper {
  animation: none;
  transform: rotate(5deg);
}
@keyframes sway {
  from {
    rotate: -2.5deg;
  }
  to {
    rotate: 2.5deg;
  }
}

/* ---- Tablet ----------------------------------------------------------- */
@media (max-width: 899px) {
  .cs__text {
    width: 100%;
    padding: 48px 24px 32px;
  }
  .cs__text--body {
    padding: 48px 24px;
  }
  .cs__title,
  .cs__sub,
  .cs__paras,
  .cs__item,
  .cs__intro {
    width: 100%;
  }
  .cs__blocks {
    flex-direction: column;
    padding: 16px 24px;
  }
  .cs__block,
  .cs__square {
    flex: none;
    width: 100%;
  }
  .cs__wide {
    padding: 16px 24px 0;
  }
  .cs__frame--centre {
    padding: 0 24px;
  }
  .cs__frame--centre .cs__inset {
    width: 100%;
  }
  .cs__nav {
    padding: 0 24px 40px;
  }
  .cs__squares {
    flex-direction: column;
    gap: 16px;
  }
  .cs__features {
    grid-template-columns: 1fr;
    padding: 16px 24px;
    gap: 16px;
  }
  .cs__feature {
    min-height: 0;
    padding: 32px 24px;
  }
  .cs__feature--wide,
  .cs__feature--narrow {
    grid-column: auto;
  }
  .cs__feature--narrow {
    padding-bottom: 0;
  }
  .cs__feature--browser {
    padding: 32px 24px;
  }
  .cs__tech {
    padding: 40px 24px 16px;
  }
  .cs__grid {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  /* The Built-with tag sits under the title instead of over it. */
  .kit__btn {
    position: relative;
    top: auto;
    right: auto;
    margin: 0 24px 8px;
  }
  .cs__frame--clips {
    gap: 24px;
  }
  .cs__frame--clips .clip--phone,
  .cs__frame--clips:has(.clip--phone:nth-child(4)) .clip--phone {
    width: 28%;
  }
  .cs__frame--clips:has(.clip--phone:nth-child(4)) .clip--phone {
    width: 21%;
  }
  .cs__frame--clips .clip--browser {
    width: 92%;
  }
}

/* ---- Phone ------------------------------------------------------------ */
@media (max-width: 639px) {
  .cs__text {
    padding: 32px 24px 24px;
  }
  .cs__text--body {
    padding: 40px 24px;
  }
  .cs__title {
    font-size: 30px;
    line-height: 40px;
  }
  .cs__h1 {
    font-size: 28px;
    line-height: 38px;
  }
  .cs__frame {
    height: auto;
    aspect-ratio: 1360 / 750;
  }
  .cs__frame--pad {
    padding: 24px 24px 0;
  }
  .cs__frame--centre {
    height: auto;
    aspect-ratio: auto;
    padding: 24px;
  }
  .cs__frame--tall {
    aspect-ratio: auto;
  }
  .cs__block {
    padding: 24px;
  }
  .cs__block--tall {
    min-height: 0;
  }
  .cs__block--closing {
    padding: 56px 24px;
    min-height: 0;
  }
  .cs__nav {
    justify-content: center;
    gap: 16px;
    padding: 0 16px 32px;
  }
  .cs__nav .tab {
    height: 64px;
    padding: 20px 28px 0;
    font-size: 18px;
    border-radius: 0 0 20px 20px;
  }
  .cs__nav .tab:hover {
    height: 72px;
    margin-bottom: -8px;
  }
  .cs__feature {
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
  }
  .cs__feature-title {
    font-size: 26px;
    line-height: 34px;
  }
  .cs__approach {
    grid-template-columns: 1fr;
  }
  /* Built with: the button opens a white block like the page's white cards, holding a caption per group
     and a wrap of grey pills. No string, pegs or colour. The block's vertical padding only exists while
     open, so the collapsed row is truly zero height. */
  .kit__btn {
    margin-bottom: 16px;
  }
  .kit__inner {
    margin: 0 24px;
    padding: 0 24px;
    background: var(--white);
    border-radius: var(--r-md);
    transition: padding 0.7s var(--spring);
  }
  .kit__lines.is-open .kit__inner {
    padding: 24px;
  }
  .line {
    padding: 0;
    min-height: 0;
    margin-top: 18px;
  }
  .line:first-child {
    margin-top: 0;
  }
  .line__string,
  .pin__peg,
  .pin__paper::before {
    display: none;
  }
  .line__label {
    position: static;
    display: inline-block;
    margin-bottom: 10px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ink-2);
    opacity: 1;
    transform: none;
  }
  .pin {
    margin-top: 0;
    transform: translateY(8px);
  }
  .line__pins {
    gap: 8px;
  }
  .pin__paper {
    animation: none;
    height: 32px;
    padding: 0 12px;
    font-size: 14px;
    background: var(--card);
    border: 0;
  }
  /* Clip trios become a swipeable strip: one phone in view, the next peeking in. */
  .cs__frame--clips,
  .cs__frame--clips:has(.clip--phone:nth-child(4)) {
    height: auto;
    aspect-ratio: auto;
    justify-content: flex-start;
    gap: 16px;
    padding: 24px;
    overflow: auto hidden;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .cs__frame--clips::-webkit-scrollbar {
    display: none;
  }
  .cs__frame--clips::after {
    content: '';
    flex: none;
    width: 8px;
  }
  .cs__frame--clips .clip--phone,
  .cs__frame--clips:has(.clip--phone:nth-child(4)) .clip--phone {
    width: 200px;
    flex: none;
    scroll-snap-align: center;
  }
  .cs__frame--clips .clip--browser {
    width: 100%;
    flex: none;
  }
  .cs__frame--clips:has(.clip--browser) {
    padding: 16px;
  }
}
/* ---- Garden: the 404 page ------------------------------------------- */
.garden {
  min-height: 56vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 48px var(--gutter) 96px;
}
.garden__sprout {
  width: 64px;
  height: 64px;
  margin-bottom: 24px;
}
.garden p {
  margin-top: 12px;
  color: var(--ink-soft);
  max-width: 420px;
  font-size: 18px;
}
.garden .btn {
  margin-top: 32px;
}
/* ==========================================================================
   Washes. Imported last so a wash always wins over a section's own fallback background.
   ========================================================================== */
/* Full-strength colour behind clips and cards.
   Each wash sets the text tokens for its surface, in opaque colours so the
   contrast is what it says: ink on the light and mid colours (green is the
   tightest at 7.4:1; white on it would be 2.9:1), white on blue (10:1). */
.wash--pink,
.wash--yellow,
.wash--orange,
.wash--lime,
.wash--green,
.wash--red {
  --text: var(--ink);
  --text-2: var(--ink);
  color: var(--text);
}
.wash--pink {
  background: var(--pink);
}
.wash--yellow {
  background: var(--yellow);
}
.wash--orange {
  background: var(--orange);
}
.wash--lime {
  background: var(--lime);
}
.wash--green {
  background: var(--green);
}
.wash--red {
  background: var(--red);
}
.wash--blue {
  background: var(--blue);
  --text: var(--white);
  --text-2: var(--white);
  color: var(--text);
}
