/* ============================================
   Sharon Austin — Portfolio
   Design tokens
   ============================================ */
:root {
  --bg: #fcfcfa;
  --ink: #111111;
  --pink: #f866d8;
  --pink-deep: #d43dbc;
  --pink-light: #ffa6e8;
  --pink-wash: #fbe7f6;
  --muted: #2c2c2c;
  --line: #e3e0d6;
  --footer-bg: #0c0c0c;

  --font-display: "Fraunces", "Georgia", serif;
  --font-body: "Source Serif 4", Georgia, serif;
  --font-mono: "Space Mono", "Courier New", monospace;

  --container: 1240px;
  --gutter: clamp(20px, 5vw, 64px);
}

/* ============================================
   Reset
   ============================================ */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p, ul { margin: 0; }
h3 { line-height: 1.3; }
ul { padding: 0; list-style: none; }
button { font: inherit; background: none; border: none; cursor: pointer; color: inherit; }

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

/* Visible keyboard focus everywhere */
a:focus-visible,
button:focus-visible,
video:focus-visible {
  outline: 2.5px solid var(--pink);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}

/* ============================================
   Header / Nav
   ============================================ */
.site-header {
  border-bottom: 2px solid var(--ink);
  background: var(--bg);
  position: relative;
  z-index: 20;
}
.nav-wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 26px;
  padding-bottom: 26px;
  gap: 24px;
}
.logo {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 30px;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.logo .logo-accent { color: var(--pink); }
.nav-links {
  display: flex;
  gap: 34px;
  font-family: var(--font-body);
  font-size: 17px;
}
.nav-links a {
  position: relative;
  transition: color 0.15s ease;
}
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -3px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.2s ease;
}
.nav-links a:hover::after,
.nav-links a:focus-visible::after { transform: scaleX(1); }

.btn-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--pink);
  border: 1.5px solid var(--ink);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 16px;
  padding: 10px 22px;
  border-radius: 999px;
  /* Squircle pill: flatter, superellipse ends where supported (Chrome/Edge
     for now); other browsers just keep the round pill. Same on the
     .kicker-link eyebrow tags, .work-link-row cards, About tags and the
     contact form button. */
  corner-shape: squircle;
  white-space: nowrap;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  box-shadow: 3px 3px 0 var(--ink);
}
.btn-pill:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--ink);
}
.btn-pill:active {
  transform: translate(0, 0);
  box-shadow: 1px 1px 0 var(--ink);
}

/* ============================================
   Mobile nav — hamburger + full-screen overlay.
   Hidden until the .nav-links bar collapses at
   640px (see the Responsive section at the end).
   ============================================ */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 11px 10px;
  margin: -11px -10px -11px 0; /* keep a 44px tap target without padding out the bar */
}
.nav-toggle span {
  display: block;
  width: 100%;
  height: 2px;
  background: var(--ink);
  border-radius: 2px;
}

.mobile-menu {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 100;
  background: var(--bg);
  overflow-y: auto;
  overscroll-behavior: contain;
  opacity: 0;
  visibility: hidden;
  /* Fade opacity, but flip visibility instantly on open (0s / no delay)
     and hold it until the fade-out finishes on close (0s after 0.22s),
     so the closed overlay is fully removed from the a11y tree and its
     links can't be tabbed to, yet focus can move in the moment it opens. */
  transition: opacity 0.22s ease, visibility 0s linear 0.22s;
}
.mobile-menu.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.22s ease, visibility 0s linear 0s;
}
.mobile-menu-inner {
  min-height: 100%;
  padding: 22px var(--gutter) 56px;
  display: flex;
  flex-direction: column;
}
.mobile-menu-close {
  align-self: flex-end;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin-right: -12px;
  color: var(--ink);
  transition: transform 0.15s ease, color 0.15s ease;
}
.mobile-menu-close svg { width: 30px; height: 30px; }
.mobile-menu-close:hover { transform: rotate(90deg); color: var(--pink-deep); }

.mobile-nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  margin-top: 7vh;
}
.mobile-nav-top {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2rem, 11vw, 2.9rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
}
.mobile-nav-sub {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0 0 2px;
  border-left: 2px solid var(--line);
}
.mobile-nav-sub li { padding-left: 18px; }
.mobile-nav-sub a {
  font-family: var(--font-body);
  font-size: 1.1rem;
  color: var(--muted);
}
.mobile-nav-cta {
  margin-top: 22px;
  font-size: 18px;
  padding: 14px 32px;
}

/* ============================================
   Hero
   ============================================ */
.hero {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: var(--gutter);
  padding-top: 72px;
  padding-bottom: 56px;
  align-items: center;
}
.hero-left { position: relative; }

.eyebrow-wrap {
  position: relative;
  height: 90px;
  margin-bottom: -10px;
}
.doodle-arrow {
  /* Hangs from the header rule and corkscrews down to point at "(me)". The
     SVG has a 300-unit straight lead-in above the drawing (300/190 * 96px ≈
     152px) that tucks up under the site header, so it stays attached even when
     the taller icon grid pushes this column down. The -72px is .hero
     padding-top; the pivot sits where the drawing proper starts (300/576). */
  position: absolute;
  top: calc(-72px - 152px);
  left: 52px;
  width: 96px;
  transform-origin: 70% 52.08%;
  animation: wiggle 5s ease-in-out infinite;
}
.eyebrow {
  position: absolute;
  left: 0;
  bottom: 8px;
  font-family: var(--font-mono);
  color: var(--pink);
  font-size: 15px;
  letter-spacing: 0.02em;
  transform: rotate(-16deg);
}

.hero-headline {
  position: relative;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(38px, 4.6vw, 60px);
  line-height: 1.06;
  letter-spacing: -0.01em;
}
.hero-headline strong { font-weight: 700; }
.line-solver { position: relative; display: inline-block; }
.doodle-scribble {
  position: absolute;
  width: 92px;
  height: auto;                  /* also sizes the inline SVG that replaces the img */
  left: 100%;
  bottom: -2px;
  margin-left: 0;
}

.hero-copy {
  margin-top: 26px;
  max-width: 46ch;
  color: var(--muted);
  font-size: 18px;
}

.hero-right {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: clamp(10px, 2vw, 30px);
  padding-top: 8px;
  --icon-size: clamp(46px, 6vw, 74px);   /* base icon width; wider icons scale off it */
}
.hero-right .doodle-slot {
  justify-self: center;
  align-self: center;
  display: inline-flex;
  position: relative;
}
/* Static per-icon offset + tilt so the 3x3 grid reads as a loose,
   scattered cluster instead of a rigid grid. Each icon still floats/
   spins on its own via the animation on .doodle-icon underneath. */
.hero-right .doodle-slot:nth-child(1) { transform: translate(6px, -16px) rotate(-6deg); }
.hero-right .doodle-slot:nth-child(2) { transform: translate(-12px, -24px) rotate(-10deg); }
.hero-right .doodle-slot:nth-child(3) { transform: translate(14px, 4px) rotate(-9deg); }
.hero-right .doodle-slot:nth-child(4) { transform: translate(-16px, -10px) rotate(7deg); }
.hero-right .doodle-slot:nth-child(5) { transform: translate(4px, 14px) rotate(10deg); }
.hero-right .doodle-slot:nth-child(6) { transform: translate(-6px, -18px) rotate(5deg); }
.hero-right .doodle-slot:nth-child(7) { transform: translate(16px, -6px) rotate(-7deg); }
.hero-right .doodle-slot:nth-child(8) { transform: translate(-14px, 30px) rotate(4deg); }
.hero-right .doodle-slot:nth-child(9) { transform: translate(10px, -10px) rotate(-11deg); }

.hero-right .doodle-icon {
  width: var(--icon-size);
  aspect-ratio: 1 / 1;
  background-color: var(--ink);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  transition: background-color 0.2s ease;
}
.hero-right .icon-code     { -webkit-mask-image: url('../assets/svg/icon-code.svg'); mask-image: url('../assets/svg/icon-code.svg'); animation: float-a 6s ease-in-out infinite; }
.hero-right .icon-chair    { -webkit-mask-image: url('../assets/svg/icon-chair.svg'); mask-image: url('../assets/svg/icon-chair.svg'); animation: float-b 7s ease-in-out infinite; }
.hero-right .icon-scissors { -webkit-mask-image: url('../assets/svg/icon-scissors.svg'); mask-image: url('../assets/svg/icon-scissors.svg'); animation: rock 5.5s ease-in-out infinite; }
.hero-right .icon-clapper  { -webkit-mask-image: url('../assets/svg/icon-clapperboard.svg'); mask-image: url('../assets/svg/icon-clapperboard.svg'); animation: float-a 6.5s ease-in-out infinite 0.4s; }
.hero-right .icon-monitor  { animation: float-b 6s ease-in-out infinite 0.2s; }
.hero-right .icon-cat      { -webkit-mask-image: url('../assets/svg/cat1.svg'); mask-image: url('../assets/svg/cat1.svg'); animation: rock 6.2s ease-in-out infinite 0.3s; }
.hero-right .icon-cursor   { animation: float-a 5.8s ease-in-out infinite 0.6s; }
.hero-right .icon-donuts   { -webkit-mask-image: url('../assets/svg/icon-donuts.svg'); mask-image: url('../assets/svg/icon-donuts.svg'); animation: spin-slow 18s linear infinite; }
.hero-right .icon-camera1  { -webkit-mask-image: url('../assets/svg/camera1.svg'); mask-image: url('../assets/svg/camera1.svg'); animation: float-b 6.4s ease-in-out infinite 0.1s; }

/* Chair + clapperboard sit a bit small against the others — bump them 20%
   (hero cluster only; interior pages don't use .hero-right). */
.hero-right .icon-chair,
.hero-right .icon-clapper { width: calc(var(--icon-size) * 1.2); }
/* camera1 + cat have extra padding in their viewBox — bump them up to match */
.hero-right .icon-camera1 { width: calc(var(--icon-size) * 1.3); }
.hero-right .icon-cat { width: calc(var(--icon-size) * 1.56); }
.hero-right .icon-monitor { width: calc(var(--icon-size) * 2); }

/* icon-code and icon-cursor are inline SVGs (not masks) so their parts can
   move independently and follow currentColor. */
.hero-right .icon-code,
.hero-right .icon-cursor {
  -webkit-mask-image: none;
  mask-image: none;
  background: none;
  color: var(--ink);
  transition: color 0.2s ease;
}
.hero-right .icon-code svg,
.hero-right .icon-cursor svg { width: 100%; height: 100%; display: block; }
.hero-right .icon-cursor .cursor-burst { opacity: 0; }

/* Hover: hot pink, plus a per-icon action replacing the idle float/rock while hovered */
.hero-right .doodle-icon:hover { background-color: var(--pink); }
/* icon-code is an inline SVG, not a mask — colour it, don't fill its box */
.hero-right .icon-code:hover { color: var(--pink); background: none; }

.hero-right .icon-code:hover .bracket-l { animation: hv-bracket-l 0.5s ease-in-out infinite; }
.hero-right .icon-code:hover .bracket-r { animation: hv-bracket-r 0.5s ease-in-out infinite; }
/* director's chair: pops, and a big pink star springs up behind it. The star
   is an inline-SVG sibling (.chair-stars) since the chair itself is a mask;
   the chair stays ink on hover so it reads against the pink. */
.hero-right .icon-chair { position: relative; z-index: 1; }
.hero-right .icon-chair:hover    { animation: hv-flash 0.4s ease-out forwards; background-color: var(--ink); }
.hero-right .chair-stars {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 180%;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  color: var(--pink);
  pointer-events: none;
  z-index: 0;
}
.hero-right .chair-stars svg { width: 100%; height: 100%; display: block; overflow: visible; }
.hero-right .chair-stars .star { opacity: 0; transform-box: fill-box; transform-origin: center; }
/* pops in, then keeps slowly turning for as long as the chair is hovered */
.hero-right .icon-chair:hover + .chair-stars .star { animation: hv-star-pop 0.45s ease-out both, hv-star-spin 6s linear 0.45s infinite; }
.hero-right .icon-scissors:hover { animation: hv-snip 0.28s ease-in-out infinite; }
/* clapperboard just snaps to its closed frame (same viewBox, only the arm moves) */
.hero-right .icon-clapper {
  transition: background-color 0.2s ease, transform 0.15s ease;
}
.hero-right .icon-clapper:hover {
  animation: none;
  transform: scale(1.12);
  -webkit-mask-image: url('../assets/svg/icon-clapperboard-closed.svg');
  mask-image: url('../assets/svg/icon-clapperboard-closed.svg');
}
/* monitor: a wrapper (not a mask) holding the line art plus an inline-SVG
   screen layer underneath, so the two float together. On hover the frame stays
   ink, gives a little wiggle, sparkles stream out from behind it, and the screen
   turns pink while "Hi!" types out behind a blinking caret. The screen SVG shares
   icon-monitor.svg's viewBox, so its rect lines up behind the bezel. */
.hero-right .icon-monitor { position: relative; -webkit-mask-image: none; mask-image: none; background: none; }
/* hover: the float freezes in place and a short wiggle plays on the separate
   `rotate` property, so the two don't fight over transform */
.hero-right .icon-monitor:hover {
  animation: float-b 6s ease-in-out infinite 0.2s, hv-monitor-wiggle 0.5s ease-in-out;
  animation-play-state: paused, running;
  background: none;
}
.hero-right .monitor-art,
.hero-right .monitor-screen { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.hero-right .monitor-art {
  background-color: var(--ink);
  -webkit-mask: url('../assets/svg/icon-monitor.svg') center / contain no-repeat;
  mask: url('../assets/svg/icon-monitor.svg') center / contain no-repeat;
}
/* celebratory dust: pink dots + 4-point sparkles that stream out from
   behind the monitor while hovered. First child, so the screen + art paint over
   it; each spark is laid out at its end point and flies out from near centre. */
.hero-right .monitor-sparkles {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 220%;
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  color: var(--pink);
  pointer-events: none;
  overflow: visible;
}
.hero-right .monitor-sparkles .spark { opacity: 0; transform-box: fill-box; transform-origin: center; }
.hero-right .icon-monitor:hover .monitor-sparkles .spark { animation: hv-spark 1.3s ease-out infinite backwards; }
.hero-right .monitor-screen .screen-glow { fill: var(--pink); opacity: 0; }
.hero-right .monitor-screen .screen-type,
.hero-right .monitor-screen .screen-caret {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 90px;
  fill: var(--ink);
  opacity: 0;
}
.hero-right .icon-monitor:hover .screen-glow { opacity: 1; }
/* each letter has its own delay inline (0.15s apart); the caret hops one
   character width (55.1 units) per letter, then blinks */
.hero-right .icon-monitor:hover .screen-type { animation: hv-type-in 0.01s both; }
.hero-right .icon-monitor:hover .screen-caret { animation: hv-caret-move 0.45s steps(1, end) both, hv-caret-blink 0.9s steps(1, end) infinite; }
/* cat: swaps to the stretching pose (cat2, same viewBox) */
.hero-right .icon-cat {
  transition: background-color 0.2s ease, transform 0.15s ease;
}
.hero-right .icon-cat:hover {
  animation: none;
  transform: scale(1.08);
  -webkit-mask-image: url('../assets/svg/cat2.svg');
  mask-image: url('../assets/svg/cat2.svg');
}
/* cursor: presses down small, inverts to an outline, and throws off a few click marks */
.hero-right .icon-cursor:hover { color: var(--pink); background: none; animation: hv-cursor-press 0.35s ease-out forwards; }
.hero-right .icon-cursor:hover .cursor-arrow { fill: none; stroke: currentColor; stroke-width: 5; }
.hero-right .icon-cursor:hover .cursor-burst { transform-box: fill-box; transform-origin: center; animation: hv-cursor-burst 0.4s ease-out forwards; }
.hero-right .icon-donuts:hover   { animation: hv-spin 0.7s ease-in-out infinite; }
/* camera1: presses the shutter and swaps to a frame with flash rays around it (same viewBox).
   It also turns level: rotate: 10deg cancels its slot's -10deg tilt (slot 2 — keep in sync). */
.hero-right .icon-camera1 { transition: background-color 0.2s ease, rotate 0.25s ease-out; }
.hero-right .icon-camera1:hover  {
  rotate: 10deg;
  animation: hv-flash 0.4s ease-out forwards;
  -webkit-mask-image: url('../assets/svg/camera1-flash.svg');
  mask-image: url('../assets/svg/camera1-flash.svg');
}

@keyframes hv-bracket-l { 0%, 100% { transform: translateX(0); } 45% { transform: translateX(-14px); } }
@keyframes hv-bracket-r { 0%, 100% { transform: translateX(0); } 45% { transform: translateX(14px); } }
@keyframes hv-snip {
  0%, 100% { transform: rotate(-9deg) scale(1.1); }
  50%      { transform: rotate(9deg) scale(1.1); }
}
@keyframes hv-paint {
  0%, 100% { transform: rotate(0) scale(1.08); }
  50%      { transform: rotate(-20deg) translateX(-3px) scale(1.08); }
}
@keyframes hv-cursor-press {
  0%   { transform: translate(0, 0) scale(1); }
  35%  { transform: translate(-4px, -4px) scale(0.72); }
  60%  { transform: translate(-7px, -7px) scale(0.86); }
  100% { transform: translate(-7px, -7px) scale(0.86); }
}
@keyframes hv-cursor-burst {
  0%   { opacity: 0; transform: scale(0.35); }
  35%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1.5); }
}
@keyframes hv-spin {
  from { transform: rotate(0deg) scale(1.15); }
  to   { transform: rotate(360deg) scale(1.15); }
}
@keyframes hv-monitor-wiggle {
  0%, 100% { rotate: 0deg; }
  20%      { rotate: -4deg; }
  45%      { rotate: 3deg; }
  70%      { rotate: -1.5deg; }
}
@keyframes hv-spark {
  0%   { opacity: 0; transform: translate(calc(var(--dx) * -0.7px), calc(var(--dy) * -0.7px)) scale(0.3); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translate(0, 0) scale(1) rotate(90deg); }
}
@keyframes hv-type-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes hv-caret-move {
  0%      { transform: translateX(0); }
  33.33%  { transform: translateX(55.1px); }
  66.67%  { transform: translateX(110.2px); }
  100%    { transform: translateX(165.3px); }
}
@keyframes hv-caret-blink {
  0%  { opacity: 1; }
  50% { opacity: 0; }
}
@keyframes hv-star-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes hv-star-pop {
  0%   { opacity: 0; transform: scale(0.2) rotate(-72deg); }
  40%  { opacity: 0.7; }
  70%  { transform: scale(1.1) rotate(6deg); }
  100% { opacity: 0.7; transform: scale(1) rotate(0); }
}
@keyframes hv-flash {
  0%   { transform: scale(0.9); }
  45%  { transform: scale(1.14); }
  100% { transform: scale(1.08); }
}
@keyframes hv-hop {
  0%, 100% { transform: translateY(0) rotate(0) scale(1.08); }
  30%      { transform: translateY(-9px) rotate(-9deg) scale(1.08); }
  62%      { transform: translateY(0) rotate(7deg) scale(1.08); }
}

@keyframes wiggle {
  0%, 100% { transform: rotate(0deg); }
  50% { transform: rotate(-6deg); }
}
@keyframes spin-slow {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
@keyframes float-a {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}
@keyframes float-b {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(8px); }
}
@keyframes rock {
  0%, 100% { transform: rotate(-4deg); }
  50% { transform: rotate(4deg); }
}
/* drift plus a side-to-side sway: a slow loop rather than a straight bob */
@keyframes drift-sway {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(10px, -6px); }
  50% { transform: translate(0, -10px); }
  75% { transform: translate(-10px, -4px); }
}
@keyframes drift {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(-6px, -10px); }
}

/* ============================================
   Ticker / Marquee
   ============================================ */
.ticker {
  background: var(--ink);
  color: #fff;
  overflow: hidden;
  border-top: 1px solid #000;
  border-bottom: 1px solid #000;
}
.ticker-track {
  display: flex;
  width: max-content;
  animation: marquee 26s linear infinite;
}
.ticker-track:hover { animation-play-state: paused; }
.ticker-seq {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  padding: 18px 0;
}
.ticker-item {
  font-family: var(--font-mono);
  font-size: 16px;
  letter-spacing: 0.02em;
  white-space: nowrap;
  padding: 0 20px;
}
.ticker-sep {
  width: 16px;
  height: 16px;
  color: var(--pink);
  flex-shrink: 0;
}
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(var(--ticker-distance, -50%)); }
}

/* ============================================
   Work sections (shared)
   ============================================ */
.work-section { padding: 84px 0 88px; }
.divider { border: none; border-top: 2px solid var(--ink); margin: 0; width: 100%; }

.vertical-label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.03em;
  color: var(--ink);
  white-space: nowrap;
}
.vertical-label {                /* hosts the highlighter swipe below */
  position: relative;
  isolation: isolate;
}
.vertical-label::before {        /* scribbly pink highlighter behind the caption */
  content: "";
  position: absolute;
  inset: -8px -4px;              /* vertical captions: bleed past the ends, a little each side */
  background: url('../assets/svg/highlight-v.svg') center / 100% 100% no-repeat;
  z-index: -1;
  opacity: 0.68;
  pointer-events: none;
}
.label-h {                       /* horizontal caption variant */
  writing-mode: horizontal-tb;
  transform: none;
  width: fit-content;
}
.label-h::before {
  inset: -4px -8px;
  background-image: url('../assets/svg/highlight-h.svg');
}
.video-label {                   /* 01: sits above the video's top-right corner */
  position: absolute;
  right: 0;
  bottom: calc(100% + 12px);
}

.see-work {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 22px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 23px;
  color: var(--pink-deep);
  text-decoration: none;
  transition: gap 0.15s ease;
}
.see-work:hover { gap: 12px; }
/* The label leans forward on hover (a faux-italic skew) so it reads as
   moving with the arrow rather than standing still while the arrow slides. */
.see-work-label {
  display: inline-block;
  transition: transform 0.18s ease;
  transform-origin: left center;
}
.see-work:hover .see-work-label {
  transform: skewX(-9deg) translateX(2px);
}

/* --- Section 01: Video --- */
.media-wrap {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 18px;
  margin-bottom: 44px;
}
.video-wrap {
  position: relative;
  flex: 1;
}
.video-frame {
  position: relative;
  border-radius: 4px;
  overflow: hidden;
  background: var(--ink);
  aspect-ratio: 21 / 9;
}
.video-frame.ratio-16x9 { aspect-ratio: 16 / 9; }
.video-frame.ratio-9x16 { aspect-ratio: 9 / 16; }
.video-frame.ratio-3x2 { aspect-ratio: 3 / 2; }
.video-frame video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.play-btn {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 74px; height: 74px;
  border-radius: 50%;
  background: rgba(255,255,255,0.92);
  display: flex; align-items: center; justify-content: center;
  transition: transform 0.2s ease, background 0.2s ease;
}
.play-btn:hover { transform: translate(-50%, -50%) scale(1.08); background: #fff; }
.play-btn svg { width: 22px; height: 22px; margin-left: 4px; }
.play-btn.is-hidden { opacity: 0; pointer-events: none; }

/* Popcorn doodles: a pair spilling off the top-left corner of the video,
   and a single kernel floating above a pair beside the section copy. */
.popcorn-tl {
  position: absolute;
  z-index: 2;
  pointer-events: none;
  width: 92px;
  left: -44px;
  top: -40px;
  animation: drift 9s ease-in-out infinite 0.5s;
}
.popcorn-cluster {
  position: absolute;
  right: 6%;
  top: 0;
  width: 106px;
  pointer-events: none;
}
.popcorn-cluster img { display: block; }
.popcorn-single {
  width: 48px;
  margin-left: 52px;             /* sits up and to the right of the pair */
  animation: drift-sway 9s ease-in-out infinite 1s;
}
.popcorn-pair {
  width: 106px;
  margin-top: 6px;
  margin-left: -100px;
  animation: drift 8s ease-in-out infinite;
}

.work-row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--gutter);
  align-items: start;
}
.work-title {                  /* same treatment as the Image & Design / Brand & Comms titles */
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(52px, 6.4vw, 84px);
  line-height: 0.95;
  letter-spacing: -0.02em;
}
.work-copy { position: relative; }
.work-copy .sub {
  font-family: var(--font-display);   /* matches .project-copy-heading on the work pages */
  font-weight: 700;
  font-size: 22px;
  margin-bottom: 12px;
}
.work-copy p {
  max-width: 44ch;
  color: var(--muted);
  font-size: 17px;
}

/* --- Section 02: Custom Imagery (media left / text right) --- */
.imagery-section .split {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;   /* media left / text right */
  gap: var(--gutter);
  align-items: stretch;                   /* copy column runs the media's full height... */
}
.imagery-copy .eyebrow-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(26px, 2.6vw, 34px);
  margin-bottom: -6px;
}
.imagery-copy .big-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(52px, 6.4vw, 84px);
  line-height: 0.95;
  letter-spacing: -0.02em;
}
.imagery-copy .sub {
  font-family: var(--font-display);   /* matches .project-copy-heading on the work pages */
  font-weight: 700;
  font-size: 22px;
  margin-top: 16px;
}
.imagery-copy p.desc {
  margin-top: 14px;
  max-width: 42ch;
  color: var(--muted);
}
.imagery-copy .desc strong { color: var(--ink); font-weight: 700; }

.imagery-media { position: relative; }
.imagery-grid-top {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}
.imagery-grid-top img { border-radius: 3px; width: 100%; aspect-ratio: 2 / 3; object-fit: cover; }
.imagery-wide { margin-top: 18px; position: relative; overflow: hidden; border-radius: 3px; }
/* trims 30px off the bottom of the wide image (the wrapper clips it), keeping the headroom above the bull */
.imagery-wide img { display: block; width: 100%; margin-bottom: -30px; }
/* ...so the sanitizers shot can sit at its foot, top and bottom edges level
   with the turf image. It fills the height left under the copy, up to the
   turf's own visible height (max-height, from
   this column's width in cqw: turf width = 1.15/0.85 of it per the .split
   columns, at the turf's 1472x800 ratio, less the 30px .imagery-wide trims). */
.imagery-copy { display: flex; flex-direction: column; align-items: flex-start; container-type: inline-size; }
.imagery-copy .see-work { margin-bottom: 12px; }
.imagery-side {
  flex: 1 1 0;
  min-height: 0;
  max-height: calc(100cqw * 1.15 / 0.85 * 800 / 1472 - 30px);
  margin-top: auto;
  /* reaches back across the column gap so it sits the same 18px from the
     turf image as the turf does from the shots above it */
  margin-left: calc(18px - var(--gutter));
  width: calc(100% + var(--gutter) - 18px);
  overflow: hidden;
  border-radius: 3px;
}
.imagery-side img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 45% 50%;            /* the tubs sit a touch left of centre */
}
.imagery-label {                 /* 02: vertical, just off the first shot's left edge */
  position: absolute;
  top: 0;
  right: calc(100% + 14px);
}

/* --- Section 03: Brand & Comms (text left / media right) ---
   Media stays first in the HTML so it leads on phones, like section 02. */
/* The cake + confetti are allowed to trail off past the right edge;
   clip them there instead of letting the page scroll sideways. */
.brand-section { overflow-x: clip; }
.brand-section .split {
  display: grid;
  grid-template-columns: 35fr 65fr;
  gap: var(--gutter);
  align-items: start;
}
.brand-media { position: relative; order: 2; }
/* Collage box = the media column, at the mockup's proportions. Every piece
   is absolutely placed in % of it (left/width of the box width, top of its
   height), so the whole arrangement scales as one. The cake and mousepad
   spill left under the copy; the phone's transparent margin runs off right. */
.brand-collage {
  /* Below the 1240px container width the copy column wraps taller, so the
     lower group (mousepad, cake, tumbler, confetti) steps down to clear it */
  --drop: clamp(0px, (1240px - 100vw) * 0.45, 110px);
  position: relative;
  aspect-ratio: 1075 / 1250;
  margin-bottom: var(--drop);
}
.brand-collage > *,
.brand-swag > * {
  position: absolute;
  max-width: none;
}
/* On desktop the swag wrapper generates no box, so its pieces are placed
   against .brand-collage like everything else */
.brand-swag { display: contents; }
.brand-wall     { left: -1.9%;  top: 0;      width: 70.7%; z-index: 1; }
.brand-mousepad { left: -17.7%; top: calc(54% + var(--drop));    width: 38.6%; z-index: 2;
                  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.18)); }
.brand-cake     { left: -60%;   top: calc(65.2% + var(--drop)); width: 60.5%; z-index: 3; }
.brand-tumbler  { left: 10.1%;  top: calc(63.5% + var(--drop)); width: 27.8%; z-index: 4; }
.brand-phone    { left: 42%;    top: -1.7%;  width: 77.6%; z-index: 5; pointer-events: none; }
.brand-phone img { display: block; width: 100%; }
/* The LinkedIn post image inside phone-LI-infra.png (1098 x 1603) spans
   x 255-801, y 464-1010. infra-ornament(-600).mp4 matches it when scaled to 563px
   square and shifted 10px left, so the clip is clipped to that window. */
.brand-phone-screen.autoplay-clip {
  position: absolute;
  left: 23.224%;
  top: 28.946%;
  width: 49.727%;
  height: 34.061%;
  pointer-events: auto;
}
.brand-phone-screen video {
  position: absolute;
  left: -1.832%;
  top: 0;
  width: 103.114%;
  max-width: none;
}
/* Navy confetti (build/make_confetti.py) scattered under the cake + tumbler */
.brand-confetti {
  left: -4%;
  top: calc(84% + var(--drop));
  width: 76%;
  z-index: 0;
  pointer-events: none;
}
.brand-label {                   /* 03: above the phone, clear of the wall */
  position: absolute;
  top: 34px;                     /* tucked into the corner between the wall and the phone */
  left: calc(68.8% + 18px);      /* 18px off the wall's right edge (-1.9% + 70.7%) */
  z-index: 6;                    /* over the collage pieces */
}

.brand-copy .big-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(50px, 6vw, 76px);
  line-height: 0.98;
  letter-spacing: -0.02em;
}
.brand-copy .sub {
  font-family: var(--font-display);   /* matches .project-copy-heading on the work pages */
  font-weight: 700;
  font-size: 22px;
  margin-top: 26px;
}
.brand-copy p.desc {
  margin-top: 14px;
  max-width: 42ch;
  color: var(--muted);
}

/* ============================================
   Footer
   ============================================ */
.site-footer {
  background: var(--footer-bg);
  color: #fff;
  padding: 64px 0 40px;
}
.footer-inner {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 48px;
}
.footer-brand {
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}
.footer-mark {
  width: 64px;
  height: 64px;
  animation: float-a 5s ease-in-out infinite, spin-slow 22s linear infinite;
}
.footer-wordmark {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 30px;
}
.footer-social {
  display: flex;
  gap: 18px;
  margin-top: 22px;
}
.footer-social a,
.footer-social button {
  width: 38px; height: 38px;
  border: 1px solid #444;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.footer-social a:hover,
.footer-social button:hover { border-color: var(--pink); background: rgba(248,102,216,0.1); }
.footer-social svg { width: 17px; height: 17px; }

.discord-copy-wrap { position: relative; display: inline-flex; }
.copy-toast {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  background: #fff;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  padding: 6px 12px;
  border-radius: 999px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.copy-toast.is-visible { opacity: 1; transform: translateX(-50%) translateY(0); }

.inline-link { color: var(--pink-deep); text-decoration: underline; }
button.inline-link {
  font: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

/* ============================================
   404 page — Lottie illustration + message,
   centred, no page-hero above it.
   ============================================ */
.not-found-content {
  text-align: center;
  padding: 72px 0 120px;
  overflow: hidden; /* contain the dust layer's spill past the art on narrow screens */
}
.not-found-art {
  position: relative;
  width: min(440px, 78vw);
  margin: 0 auto 4px;
}
.lottie-404 { width: 100%; }
.lottie-404 svg { display: block; }

/* Ambient dust — decoration only, spills a little past the illustration
   and is clipped to that expanded box. */
.nf-dust-layer {
  position: absolute;
  inset: -14% -18%;
  overflow: hidden;
  pointer-events: none;
}
.nf-dust {
  position: absolute;
  border-radius: 50%;
  background: #1c1c1c;
  animation-name: nf-drift;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}
@keyframes nf-drift {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(var(--dx), var(--dy)); }
}
@media (prefers-reduced-motion: reduce) {
  .nf-dust-layer { display: none; }
}
.not-found-heading {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.4rem, 1rem + 1.6vw, 2rem);
  margin: 0 0 14px;
}
.not-found-back {
  font-size: 1.05rem;
  margin: 0;
}

.footer-cols {
  display: flex;
  gap: 64px;
  font-family: var(--font-mono);
}
.footer-col h3 {
  font-size: 13px;
  letter-spacing: 0.06em;
  color: #8a8a8a;
  margin-bottom: 16px;
  font-weight: 400;
}
.footer-col ul { display: flex; flex-direction: column; gap: 12px; }
.footer-col a { font-size: 14px; transition: color 0.15s ease; white-space: nowrap; }
.footer-col a:hover { color: var(--pink); }

.footer-bottom {
  margin-top: 56px;
  padding-top: 20px;
  border-top: 1px solid #262626;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: #7a7a7a;
}

/* ============================================
   Simple sub-pages (Work, Play, Freebies, About,
   Contact, and the 3 work category pages) —
   header + page-hero + footer, basic on purpose.
   ============================================ */
.page-hero {
  position: relative;
  padding-top: 80px;
  padding-bottom: 60px;
}
/* Pink twinkling sparkles scattered around the page title (Play).
   Positioned per-sparkle inline; coloured via the mask technique. */
.hero-sparkles { position: absolute; inset: 50px 0 0; pointer-events: none; }
.hero-sparkle {
  position: absolute;
  aspect-ratio: 1 / 1;
  background-color: var(--pink);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  animation: twinkle 2.8s ease-in-out infinite;
}
.hero-sparkle--asterisk {
  -webkit-mask-image: url('../assets/svg/sparkle-asterisk.svg');
  mask-image: url('../assets/svg/sparkle-asterisk.svg');
}
.hero-sparkle--star {
  -webkit-mask-image: url('../assets/svg/star-twinkle-1.svg');
  mask-image: url('../assets/svg/star-twinkle-1.svg');
}
/* About: bubbles are plain CSS circles (hollow rings + a few solid dots)
   that bob slowly upward instead of twinkling. */
.hero-sparkle--ring,
.hero-sparkle--dot {
  border-radius: 50%;
  animation: bubble-float 5s ease-in-out infinite;
}
.hero-sparkle--ring {
  background-color: transparent;
  border: 2px solid var(--pink);
}
/* Work: play and play-pause buttons pulse, cursors give a little "click" nudge,
   registration marks turn slowly. */
.hero-sparkle--play {
  -webkit-mask-image: url('../assets/svg/play-triangle.svg');
  mask-image: url('../assets/svg/play-triangle.svg');
  animation: play-pulse 2.8s ease-in-out infinite;
}
.hero-sparkle--play-pause {
  -webkit-mask-image: url('../assets/svg/play-pause.svg');
  mask-image: url('../assets/svg/play-pause.svg');
  animation: play-pulse 2.8s ease-in-out infinite;
}
.hero-sparkle--cursor {
  -webkit-mask-image: url('../assets/svg/icon-cursor.svg');
  mask-image: url('../assets/svg/icon-cursor.svg');
  animation: cursor-nudge 3.2s ease-in-out infinite;
}
.hero-sparkle--reg {
  -webkit-mask-image: url('../assets/svg/reg-mark.svg');
  mask-image: url('../assets/svg/reg-mark.svg');
  animation: reg-turn 9s linear infinite;
}
.page-hero.has-decoration {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
}
.page-hero-doodle { flex-shrink: 0; }
.page-hero-doodle img {
  width: clamp(90px, 12vw, 160px);
  animation: rock 6s ease-in-out infinite;
}
/* Video + Campaigns hero: 2-frame clapperboard. Both SVGs share one viewBox
   (0 0 568.36 508.12) so the slate stays put and only the arm moves; that box
   is ~1.18x the drawing, so the container is scaled up to match. The open
   frame holds for 2s, then the closed frame (arm down + snap lines) shows for
   0.5s — a hard cut each way, looping every 2.5s. */
.page-hero-doodle.clapperboard {
  position: relative;
  width: clamp(106px, 14.2vw, 189px);
  margin-right: 100px;           /* pulled in toward the heading */
}
.page-hero-doodle.clapperboard .clap-frame {
  display: block;
  width: 100%;
}
.page-hero-doodle.clapperboard .clap-open {
  animation: rock 6s ease-in-out infinite,
             clapperboard-open 2.5s step-end infinite;
}
.page-hero-doodle.clapperboard .clap-closed {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: rock 6s ease-in-out infinite,
             clapperboard-snap 2.5s step-end infinite;
}
@keyframes clapperboard-open {   /* open slate: visible 0-2s, hidden 2-2.5s */
  0%  { opacity: 1; }
  80% { opacity: 0; }
}
@keyframes clapperboard-snap {   /* closed slate: hidden 0-2s, visible 2-2.5s */
  0%  { opacity: 0; }
  80% { opacity: 1; }
}
/* Custom Imagery hero (placeholder): framed picture swinging from its nail.
   The nail sits at (100, 14) in the 200 x 210 viewBox, so that's the pivot. */
/* Contact hero: coffee cup up top, ginger cat stepped down and to its
   right (south-east), each on its own float so they drift out of step */
.page-hero-doodle.contact-doodles {
  display: flex;
  align-items: flex-start;
  margin-right: clamp(60px, 26vw - 110px, 265px);   /* full nudge on wide screens, less as the intro text closes in */
}
.page-hero-doodle.contact-doodles img { width: clamp(108px, 12.6vw, 171px); }
.page-hero-doodle .contact-coffee { animation: float-a 5s ease-in-out infinite; }
.page-hero-doodle .contact-ginger {
  margin: clamp(56px, 7vw, 100px) 0 0 -24px;
  animation: float-b 6s ease-in-out infinite;
}
/* About (Find Me): a paw reaching up out of the footer at the bottom right.
   The arm runs to the bottom edge of the SVG, so bottom: 0 sits it flush
   on the footer; it waves from the wrist end. */
#find-me { position: relative; }
.footer-paw {
  position: absolute;
  right: 0;
  bottom: 0;
  width: clamp(138px, 15vw, 212px);
  pointer-events: none;
}
.footer-paw img {
  display: block;
  width: 100%;
  transform-origin: 50% 100%;
  animation: wiggle 4s ease-in-out infinite;
}
/* the pink twinkles around it reuse .hero-sparkle (shapes + twinkle) */
.page-hero-doodle.picture-frame {
  position: relative;
  width: clamp(106px, 14vw, 180px);
  margin-right: 90px;
}
.page-hero-doodle.picture-frame .frame-art {
  display: block;
  width: 100%;
  transform-origin: 50% 6.67%;
  animation: frame-swing 3.6s ease-in-out infinite;
}
@keyframes frame-swing {
  0%, 100% { transform: rotate(-5deg); }
  50% { transform: rotate(5deg); }
}
/* Camera flashes: each burst pops for ~0.3s then hides for the rest of its
   loop. Uneven loop lengths + delays keep them from falling into a pattern.
   (Reduced motion: the global rule ends them on their hidden frame.) */
.page-hero-doodle.picture-frame .flash {
  position: absolute;
  width: 42%;
  opacity: 0;
  pointer-events: none;
  animation: flash-pop 6.2s ease-out infinite;
}
.page-hero-doodle.picture-frame .flash-1 { left: -36%; top: 14%;  animation-delay: 1.2s; }
.page-hero-doodle.picture-frame .flash-2 { right: -36%; top: 42%; width: 34%; animation-duration: 7.7s; animation-delay: 3.4s; }
.page-hero-doodle.picture-frame .flash-3 { left: -16%; bottom: -18%; width: 31%; animation-duration: 9.1s; animation-delay: 5.6s; }
@keyframes flash-pop {
  0%   { opacity: 0; transform: scale(0.3) rotate(0); }
  2%   { opacity: 1; transform: scale(1) rotate(8deg); }
  5%   { opacity: 0; transform: scale(1.25) rotate(14deg); }
  100% { opacity: 0; transform: scale(1.25) rotate(14deg); }
}
/* Design & Comms hero: notebook low + left, laptop up + to its right, ruler
   left of the laptop,
   placed inside one fixed-ratio box. Both SVGs have generous viewBox padding,
   so they run larger than the default doodle. */
.page-hero-doodle.brand-doodles {
  position: relative;
  width: clamp(220px, 28vw, 360px);
  aspect-ratio: 1 / 1;
  margin-right: 40px;
}
.page-hero-doodle.brand-doodles .brand-notebook { position: absolute; width: 56%; left: 0; bottom: -8%; }
.page-hero-doodle.brand-doodles .brand-ruler { position: absolute; width: 42%; left: -6%; top: 6%; animation-delay: -4s; }
/* laptop: the wrapper rocks; inside, the open frame shows for 1s, then the
   closed frame for 1s — a hard cut each way, looping every 2s */
.page-hero-doodle.brand-doodles .brand-laptop {
  position: absolute;
  width: 52%;
  right: 0;
  top: 0;
  animation: rock 6s ease-in-out infinite -2s;
}
.page-hero-doodle.brand-doodles .brand-laptop img { display: block; width: 100%; animation: laptop-open 2s step-end infinite; }
.page-hero-doodle.brand-doodles .brand-laptop .laptop-closed { position: absolute; inset: 0; opacity: 0; animation-name: laptop-closed; }
@keyframes laptop-open {   /* visible 0-1s, hidden 1-2s */
  0%  { opacity: 1; }
  50% { opacity: 0; }
}
@keyframes laptop-closed { /* hidden 0-1s, visible 1-2s */
  0%  { opacity: 0; }
  50% { opacity: 1; }
}
/* Larger hero-side visual (e.g. the laptop screenshots GIF on Shopify + Web) —
   sits opposite the heading/lede in the same .has-decoration flex row. */
.page-hero-media {
  flex-shrink: 0;
  width: min(42%, 440px);
}
.page-hero-media img,
.page-hero-media video {
  width: 100%;
  height: auto;
  display: block;
}
.page-hero .kicker {
  display: inline-block;
  font-family: var(--font-mono);
  color: var(--pink-deep);
  font-size: 15px;
  letter-spacing: 0.02em;
  margin-bottom: 20px;
}
.page-hero .kicker-tilt {         /* About: tossed-on-the-page angle */
  transform: translateY(25px) rotate(-20deg);
  transform-origin: left bottom;
}
.page-hero .kicker-tilt-work {    /* Work: gentle clockwise tilt (a touch less than Play), pivoting on its centre */
  transform: rotate(6deg);
  transform-origin: center;
}
.page-hero .kicker-tilt-play {    /* Play: counter-clockwise tilt, pivoting on its centre */
  transform: rotate(-10deg);
  transform-origin: center;
}
.page-hero .kicker-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--pink);
  border: 1.5px solid var(--ink);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.02em;
  padding: 5px 16px;
  margin-bottom: 24px;
  border-radius: 999px;
  corner-shape: squircle;
  white-space: nowrap;
  text-decoration: none;
  transform: rotate(-3deg);
  box-shadow: 2px 2px 0 var(--ink);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.page-hero .kicker-link:hover {
  transform: rotate(-3deg) translate(-2px, -2px);
  box-shadow: 4px 4px 0 var(--ink);
}
.page-hero .kicker-link:active {
  transform: rotate(-3deg) translate(0, 0);
  box-shadow: 1px 1px 0 var(--ink);
}
.page-hero h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(48px, 8vw, 100px);
  line-height: 0.95;
  letter-spacing: -0.02em;
}
/* A heading with one very long word (Design & Communications): never
   wider than the space between the gutters (~8.6em for that word in
   Fraunces 800), so on phones it shrinks instead of overflowing. */
.page-hero h1 .h1-fit { font-size: min(1em, calc((100vw - 2 * var(--gutter)) / 8.6)); }
.page-hero p.lede {
  margin-top: 24px;
  max-width: 58ch;
  color: var(--muted);
  font-size: 19px;
}
/* Custom Imagery's longer intro gets a slightly wider column */
.page-hero:has(+ .imagery-gallery) p.lede { max-width: calc(58ch + 50px); }

/* --- Web Design & Shopify (work-web.html): ruled intro (lede + laptop GIF),
   then a 3-across gallery --- */
.web-intro {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 40px;
  border-top: 2px solid var(--ink);
  padding-top: 60px;
  padding-bottom: 70px;
}
.web-intro .lede {
  max-width: 58ch;
  color: var(--muted);
  font-size: 19px;
}
.gallery-grid.web-gallery-grid { grid-template-columns: repeat(3, 1fr); }

/* --- Work hub (work.html) — simple linked list down to the 3 categories --- */
/* Work index: the four category links are chunky pink cards (same outline +
   offset shadow as .btn-pill) so they read as doors, distinct from the flat
   accordion rows on the category pages. */
.work-links { display: grid; gap: 16px; margin-bottom: 90px; }
.work-link-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  padding: 26px 48px;
  background: var(--pink-wash);
  border: 2px solid var(--ink);
  border-radius: 999px;          /* squircle pill, like .btn-pill and the eyebrow tags */
  corner-shape: squircle;
  box-shadow: 4px 4px 0 var(--ink);
  text-decoration: none;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}
.work-link-row:hover,
.work-link-row:focus-visible {
  background: var(--pink);
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 var(--ink);
}
.work-link-row .num {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--ink);
  font-size: 19px;
  min-width: 36px;
  flex-shrink: 0;
}
.work-link-row .name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(26px, 4vw, 44px);
  flex: 1;
  color: var(--ink);
}
.work-link-row .arrow {
  font-family: var(--font-body);
  color: var(--ink);
  font-size: 29px;
  margin-right: 80px;            /* runway to slide into on hover */
  transition: transform 0.2s ease;
  flex-shrink: 0;
}
.work-link-row:hover .arrow,
.work-link-row:focus-visible .arrow { transform: translateX(40px); }

/* --- About page anchor sections --- */
.about-block {
  padding-top: 50px;
  padding-bottom: 50px;
  border-top: 1px solid var(--line);
}
.about-block:last-of-type { padding-bottom: 90px; }
.about-block h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(28px, 3.4vw, 38px);
  margin-bottom: 18px;
}
.about-block p {
  max-width: 60ch;
  color: var(--muted);
  font-size: 17px;
}
.about-block .tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 12px;
  list-style: none;
  padding: 0;
  margin: 6px 0 0;
}
.about-block .tag-list li {
  font-family: var(--font-mono);
  font-size: 14px;
  background: #f1efe8;
  border: 1px solid var(--line);
  padding: 7px 15px;
  border-radius: 999px;
  corner-shape: squircle;
  color: var(--ink);
}

/* --- Contact form --- */
.contact-form-wrap { padding-bottom: 90px; }
.contact-form {
  display: grid;
  gap: 22px;
}
/* fields + status stay 640 wide; the small notes may run wider */
.form-row { display: grid; gap: 8px; max-width: 640px; }
.form-row label {
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--ink);
}
/* pink asterisk on required fields (screen readers already announce "required") */
.form-row:has(:required) label::after {
  content: "*";
  content: "*" / "";
  margin-left: 3px;
  color: var(--pink-deep);
}
.form-row input,
.form-row textarea {
  font-family: var(--font-body);
  font-size: 17px;
  padding: 14px 16px;
  border: 1.5px solid var(--ink);
  border-radius: 3px;
  background: #fff;
  color: var(--ink);
  resize: vertical;
}
.form-row input:focus-visible,
.form-row textarea:focus-visible {
  outline: 2.5px solid var(--pink);
  outline-offset: 1px;
}
.form-honeypot { position: absolute; left: -9999px; top: -9999px; }
.contact-form button[type="submit"] {
  justify-self: start;
  background: var(--pink);
  border: 1.5px solid var(--ink);
  color: var(--ink);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 17px;
  padding: 13px 30px;
  border-radius: 999px;
  corner-shape: squircle;
  box-shadow: 3px 3px 0 var(--ink);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.contact-form button[type="submit"]:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 var(--ink);
}
.contact-form button[type="submit"]:active {
  transform: translate(0, 0);
  box-shadow: 1px 1px 0 var(--ink);
}
.form-note {
  margin-top: 18px;
  font-size: 14px;
  color: var(--muted);
}
.form-note + .form-note { margin-top: -12px; }   /* stacked notes: a small gap, not the full form gap */
.form-note a { color: var(--pink-deep); text-decoration: underline; }
.form-required-note { margin: 0 0 -8px; }   /* sits just above the first field */
.req-star { color: var(--pink-deep); }   /* matches the asterisk on required labels */
.form-status a { color: inherit; text-decoration: underline; }
.form-status {
  max-width: 640px;
  font-family: var(--font-mono);
  font-size: 14px;
  padding: 12px 16px;
  border-radius: 3px;
  display: none;
}
.form-status.is-success { display: block; background: #eafaf0; border: 1px solid #b7e6c6; color: #1f7a3f; }
.form-status.is-error { display: block; background: #fdecec; border: 1px solid #f3b9b9; color: #a32323; }

/* ============================================
   Custom Imagery gallery
   ============================================ */
.gallery-section { padding-bottom: 90px; }
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 34px 22px;
}
.gallery-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  text-align: left;
  padding: 0;
}
.gallery-thumb { width: 100%; }
.gallery-thumb {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: 3px;
  border: 1px solid var(--line);
}
.gallery-thumb img,
.gallery-thumb video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.3s ease;
}
.gallery-thumb::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.25);
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.gallery-item:hover .gallery-thumb::after,
.gallery-item:focus-visible .gallery-thumb::after {
  opacity: 0;
}
/* Custom Image & Design: thumbs show at full strength, no wash */
.imagery-gallery .gallery-thumb::after,
.project-squares-grid--clean .gallery-thumb::after,
.square-grid .gallery-thumb::after { display: none; }
/* ...and 3 across (bigger thumbs) instead of the default 4 */
.imagery-gallery .gallery-grid { grid-template-columns: repeat(3, 1fr); }
.gallery-item:hover .gallery-thumb img,
.gallery-item:hover .gallery-thumb video,
.gallery-item:focus-visible .gallery-thumb img,
.gallery-item:focus-visible .gallery-thumb video {
  transform: scale(1.045) rotate(-1.4deg);
}
.gallery-item:nth-child(even):hover .gallery-thumb img,
.gallery-item:nth-child(even):hover .gallery-thumb video,
.gallery-item:nth-child(even):focus-visible .gallery-thumb img,
.gallery-item:nth-child(even):focus-visible .gallery-thumb video {
  transform: scale(1.045) rotate(1.4deg);
}
.gallery-caption {
  display: block;
  width: 100%;
  margin-top: 12px;
}
.gallery-title {
  display: block;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 16px;
  color: var(--ink);
}
.gallery-desc {
  display: block;
  margin-top: 3px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--muted);
}
/* --- Lightbox --- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  align-items: center;
  justify-content: center;
}
.lightbox.is-open { display: flex; }
.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(12, 12, 12, 0.92);
}
.lightbox-content {
  position: relative;
  z-index: 1;
  margin: 0;
  max-width: min(880px, 86vw);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* The sitewide "img { display: block }" reset (an author rule) beats
   the browser's default [hidden] -> display:none, so without this the
   lightbox img stays visibly on screen (showing its last src) even
   when JS sets img.hidden = true to swap in a video. */
.lightbox-img[hidden] { display: none; }
.lightbox-img {
  max-width: 100%;
  max-height: 68vh;
  width: auto;
  border-radius: 3px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.lightbox-video {
  max-width: 100%;
  max-height: 68vh;
  width: auto;
  border-radius: 3px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  background: var(--ink);
}
.lightbox-close,
.lightbox-arrow {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.25);
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.lightbox-close svg,
.lightbox-arrow svg { width: 20px; height: 20px; }
.lightbox-close:hover,
.lightbox-arrow:hover { background: var(--pink); border-color: var(--pink); color: var(--ink); }
.lightbox-close { top: 26px; right: 26px; }
.lightbox-prev { left: 26px; top: 50%; transform: translateY(-50%); }
.lightbox-next { right: 26px; top: 50%; transform: translateY(-50%); }
.lightbox-prev:hover { transform: translateY(-50%) translateX(-3px); }
.lightbox-next:hover { transform: translateY(-50%) translateX(3px); }

/* ============================================
   Before / After compare slider
   ============================================ */
.compare-section { padding-bottom: 90px; }
.compare-section .kicker-label {
  font-family: var(--font-mono);
  color: var(--pink-deep);
  font-size: 15px;
  letter-spacing: 0.02em;
  margin-bottom: 6px;
}
.compare-heading {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(28px, 3.4vw, 38px);
  margin-bottom: 10px;
}
.compare-intro {
  max-width: 52ch;
  color: var(--muted);
  font-size: 17px;
  margin-bottom: 32px;
}

.compare-slider { position: relative; max-width: 1200px; margin: 0 auto; }
.compare-slider-second { margin-top: 40px; }

/* Compare slider embedded in a project panel (Pristiva) */
.project-compare { margin-top: 60px; }
.project-compare-label {
  font-family: var(--font-mono);
  color: var(--pink-deep);
  font-size: 15px;
  letter-spacing: 0.02em;
  margin-bottom: 14px;
}
.compare-frame {
  position: relative;
  aspect-ratio: 1200 / 955;
  border-radius: 4px;
  overflow: hidden;
  background: var(--ink);
  border: 1px solid var(--line);
}
.compare-frame--wide { aspect-ratio: 3 / 2; }
.compare-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.compare-before-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
  clip-path: inset(0 calc(100% - var(--pos, 50%)) 0 0);
}
.compare-label {
  position: absolute;
  top: 16px;
  z-index: 2;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: #fff;
  background: rgba(12, 12, 12, 0.6);
  padding: 6px 13px;
  border-radius: 999px;
  pointer-events: none;
}
.compare-label-before { left: 16px; }
.compare-label-after { right: 16px; }

.compare-divider {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos, 50%);
  transform: translateX(-50%);
  width: 3px;
  background: #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18);
  z-index: 2;
  pointer-events: none;
}
.compare-handle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--pink);
  border: 1.5px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
}
.compare-handle svg { width: 11px; height: 11px; }

.compare-slider:focus-within .compare-handle {
  outline: 2.5px solid var(--ink);
  outline-offset: 2px;
}

.compare-range {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}
.compare-range::-webkit-slider-runnable-track { -webkit-appearance: none; height: 100%; background: transparent; }
.compare-range::-moz-range-track { height: 100%; background: transparent; border: none; }
.compare-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 44px;
  height: 100%;
  background: transparent;
  cursor: ew-resize;
}
.compare-range::-moz-range-thumb {
  width: 44px;
  height: 100%;
  background: transparent;
  border: none;
  cursor: ew-resize;
}
.compare-range:focus-visible { outline: none; }

/* ============================================
   Project accordion (work-video.html)
   ============================================ */
.accordion-section {
  border-top: 2px solid var(--ink);
  padding-bottom: 90px;
}
.accordion-item { border-bottom: 1.5px solid var(--ink); }
.accordion-item:last-child { border-bottom: none; }

.accordion-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 28px 24px;
  text-align: left;
  cursor: pointer;
  background: transparent;
  transition: padding-left 0.2s ease, background 0.2s ease;
}
.accordion-item.is-open .accordion-trigger { background: var(--pink-wash); }
.accordion-trigger:hover { padding-left: 34px; }
.accordion-num {
  font-family: var(--font-mono);
  color: var(--pink);
  font-size: 15px;
  min-width: 30px;
  flex-shrink: 0;
}
.accordion-name {
  flex: 1;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(22px, 3.2vw, 34px);
  color: var(--ink);
}
.accordion-icon {
  position: relative;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}
.accordion-icon::before,
.accordion-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--ink);
  transform: translate(-50%, -50%);
}
.accordion-icon::before { width: 16px; height: 2px; }
.accordion-icon::after {
  width: 2px;
  height: 16px;
  transition: transform 0.25s ease;
}
.accordion-item.is-open .accordion-icon::after { transform: translate(-50%, -50%) rotate(90deg); }

.accordion-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s ease;
}
.accordion-item.is-open .accordion-panel { grid-template-rows: 1fr; }
.accordion-panel-inner {
  overflow: hidden;
  min-height: 0;
}

.accordion-placeholder {
  padding-bottom: 40px;
  color: var(--muted);
  font-style: italic;
}

/* --- Project detail content (inside a panel) --- */
.project-body { padding-bottom: 48px; }
/* A panel holding several projects (Brand Identity & Redesign): a rule
   between each one. The meta row's own 20px padding is the gap below it. */
.project-body + .project-body {
  padding-top: 0;
  border-top: 2px solid var(--ink);
}
.project-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 30px;
  margin: 0 0 30px;
  padding: 20px;
  border-bottom: 1px solid var(--line);
}
.project-meta > div { display: flex; flex-direction: column; gap: 4px; }
.project-meta dt {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pink);
}
.project-meta dd {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  color: var(--ink);
}
.project-row {
  position: relative;
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 40px;
  align-items: start;
}
.project-copy {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 60ch;
}
/* Standalone usage (Mineraluxe's meta -> video -> copy -> gallery
   order) needs its own bottom margin; inside .project-row it's a
   grid item and the row's own margin already provides the spacing. */
.project-body > .project-copy { margin-bottom: 44px; }
/* Row usage (copy beside the reel): a small top nudge so it doesn't
   sit flush against the meta divider right above it. */
.project-row > .project-copy { padding-top: 10px; }
.project-copy p {
  color: var(--muted);
  font-size: 17px;
  line-height: 1.7;
}
/* Optional two-column reading layout for longer write-ups (e.g. VBNB) */
.project-copy-split {
  display: block;
  columns: 2;
  column-gap: 48px;
  max-width: 100%;
}
.project-copy-split p { margin: 0 0 16px; }
.project-copy-split p:last-child { margin-bottom: 0; }
/* Variant for two discrete paragraphs (e.g. Pristiva) rather than one
   long flowing one (e.g. Signage & Swag): a real grid keeps both
   paragraphs top-aligned under the heading regardless of length, where
   multicol's auto-balance can otherwise leave one column starting lower
   than the other. */
.project-copy-split--grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 48px;
  columns: unset;
}
.project-copy-split--grid .project-copy-heading { grid-column: 1 / -1; }
/* Single full-width column (e.g. Digital & Campaign, which has no hero) */
.project-copy-split--single { columns: 1; margin-bottom: 40px; max-width: 75%; padding-top: 20px; }
/* Optional lead-in heading above a copy block (e.g. Signage & Swag) —
   spans both columns of a split layout instead of sitting in column 1. */
.project-copy-heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 22px;
  color: var(--ink);
  margin-bottom: 14px;
  column-span: all;
}
.project-reel-wrap {
  justify-self: center;
  width: 100%;
  max-width: 280px;
}
.project-twinkles {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform: translateX(80px);
}
.project-twinkle {
  position: absolute;
  animation: twinkle 2.8s ease-in-out infinite;
}
@keyframes twinkle {
  0%, 100% { opacity: 0.25; transform: rotate(var(--rot, 0deg)) scale(0.7); }
  50% { opacity: 1; transform: rotate(var(--rot, 0deg)) scale(1.1); }
}
@keyframes bubble-float {
  0%, 100% { opacity: 0.55; transform: translate(0, 0); }
  50% { opacity: 1; transform: translate(3px, -12px); }
}
@keyframes play-pulse {
  0%, 100% { opacity: 0.6; transform: rotate(var(--rot, 0deg)) scale(0.85); }
  50% { opacity: 1; transform: rotate(var(--rot, 0deg)) scale(1.05); }
}
@keyframes cursor-nudge {
  0%, 60%, 100% { opacity: 0.6; transform: rotate(var(--rot, 0deg)) translate(0, 0); }
  75% { opacity: 1; transform: rotate(var(--rot, 0deg)) translate(-4px, -4px); }
  85% { opacity: 1; transform: rotate(var(--rot, 0deg)) translate(0, 0) scale(0.88); }
}
@keyframes reg-turn {
  from { opacity: 0.8; transform: rotate(0deg); }
  to { opacity: 0.8; transform: rotate(360deg); }
}
@keyframes pencil-float {
  0%, 100% { transform: translateY(0) rotate(6deg); }
  50% { transform: translateY(-8px) rotate(6deg); }
}
@keyframes chip-bob {
  0%, 100% { transform: rotate(var(--rot, 0deg)) translateY(0); }
  50% { transform: rotate(var(--rot, 0deg)) translateY(-6px); }
}
.project-hero-video { margin-bottom: 0; }
.video-caption {
  margin: 14px 0 44px;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #484848;
}
/* Caption + round icon link (e.g. YouTube channel) on one line */
.video-caption-link {
  display: flex;
  align-items: center;
  gap: 12px;
}
.video-caption-link a {
  width: 34px; height: 34px;
  border: 1px solid #c8c8c8;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.video-caption-link a:hover { border-color: var(--pink); background: rgba(248,102,216,0.1); }
.video-caption-link svg { width: 17px; height: 17px; }
/* Play: ambience reel — copy left (1/3), video right (2/3), same as the drone section */
.play-reel-section {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 48px;
  align-items: center;
  padding-top: 70px;
  padding-bottom: 90px;
}
.play-reel-copy .compare-heading { line-height: 1.1; }
.play-reel-copy p { color: var(--muted); font-size: 17px; }

/* Play: aerial/drone clips — copy left (1/3), video right (2/3) */
.drone-section {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 48px;
  align-items: center;
  padding-top: 70px;
  padding-bottom: 90px;
}
.drone-media .video-frame { border-radius: 3px; overflow: hidden; }
.drone-copy p { color: var(--muted); font-size: 17px; }
/* Stand-in frame until a clip exists (e.g. the Play blooper reel) */
.video-frame--placeholder {
  display: grid;
  place-items: center;
  color: rgba(255, 255, 255, 0.6);
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.04em;
}

/* Play: alternating bands — every other section (1st, 3rd, ...; .play-band is added by the build) sits on
   a softened pink wash (half --pink-wash, half page background). The box-shadow + clip-path pair bleeds
   the colour to the full viewport width without widening .container's content. */
.play-band {
  --band: color-mix(in srgb, var(--pink-wash) 50%, var(--bg));
  background: var(--band);
  box-shadow: 0 0 0 100vmax var(--band);
  clip-path: inset(0 -100vmax);
  padding-top: 70px;
  padding-bottom: 90px;
}

/* Play: every other section (.play-flip, added by the build) mirrors the
   layout — media left (2/3), copy right (1/3). Stacked layouts undo it in
   the 980 block so copy still leads. */
.play-flip { grid-template-columns: 2fr 1fr; }
.play-flip > :first-child { order: 2; }

/* Play: Little Worlds — copy left (1/3), masonry gallery right (2/3) */
.little-worlds-section {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 48px;
  align-items: start;
  padding-top: 70px;
  padding-bottom: 90px;
}
.little-worlds-copy { position: sticky; top: 40px; }
.little-worlds-copy p { color: var(--muted); font-size: 17px; }
/* CSS columns give a natural masonry; thumbs keep their own aspect ratio */
.masonry-grid { columns: 2; column-gap: 16px; }
.masonry-grid .gallery-item { break-inside: avoid; margin-bottom: 16px; }
.masonry-grid .gallery-thumb { aspect-ratio: auto; }
.masonry-grid .gallery-thumb img { height: auto; }
/* Play: Set Design — Little Worlds layout with a 2x2 grid of squares */
.square-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}
/* Set Design: copy + slideshow, then the photos in one full-width row of four */
.set-design-section { row-gap: 16px; }   /* same as the gap between the thumbs */
.set-design-media { min-width: 0; }   /* the slideshow's wide track mustn't widen its grid column */
.set-design-media .carousel { margin-bottom: 0; }
.set-design-section .square-grid { grid-column: 1 / -1; grid-template-columns: repeat(4, 1fr); }
/* Stand-in tile until the real image is in */
.square-grid-placeholder {
  display: grid;
  place-items: center;
  background: var(--line);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.04em;
}
.project-gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
}
.project-gallery img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 3px;
  border: 1px solid var(--line);
}

/* --- Mixed-media (Day & Night): a row of clickable stills (reuses
   the .gallery-grid/.gallery-item lightbox pattern from the imagery
   gallery), then a wide photo beside a tall one. --- */
.project-squares-grid { margin-bottom: 60px; }
/* Small label above a group inside one panel (e.g. Digital & Campaign:
   "Featured Project / Mineraluxe") — same voice as .video-caption. */
.project-subhead {
  margin: 0 0 14px;
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #484848;
}
.project-subhead strong { font-weight: 700; }   /* the part before the slash */
/* Thin rule between those groups — lighter than the 2px rule between
   separate projects (.project-body + .project-body). */
.project-divider {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 0 0 44px;
}
/* 3-up variant (e.g. Digital & Campaign, Signage & Swag: 2 rows of 3) */
.gallery-grid.project-squares-grid--3col { grid-template-columns: repeat(3, 1fr); }

/* Mineraluxe: full-width edit-suite screenshot under the product row */
.project-editshot {
  border-radius: 4px;
  border: 1px solid var(--line);
}

/* Brand panels: full-width hero image (the video pages use a .video-frame
   instead), a 50/50 copy + image split, then a 3-up clickable gallery.
   Below 980px the base .project-row / .gallery-grid rules collapse them. */
.project-hero-image {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
  border-radius: 4px;
  border: 1px solid var(--line);
  margin-bottom: 44px;
}
/* For a product shot / transparent PNG that should sit whole in the frame
   rather than be cropped to fill it — no border box around the empty space. */
.project-hero-image--contain {
  object-fit: contain;
  background: var(--bg);
  border: none;
}
/* Signage & Swag hero: the booth shot sits ~100px right of centre (capped so
   it never runs off the right edge), and the A-frame pool poster stands
   beside it at the far left, clear of the booth on desktop (its floor
   shadow is baked into the PNG). On narrower
   screens they can meet, so the poster stays layered behind the booth (which
   drops the --contain background so the poster isn't hidden by it). */
.signage-hero { position: relative; margin-bottom: 44px; }
.signage-hero .signage-booth {
  position: relative;
  z-index: 1;
  margin-bottom: 0;
  background: none;
  object-position: min(calc(50% + 100px), 100%) 50%;
}
.signage-poster {
  position: absolute;
  left: 0;
  bottom: 2%;          /* feet roughly level with the booth's */
  height: 60%;
  width: auto;
  z-index: 0;
}
.project-row-even { grid-template-columns: 1fr 1fr; }
/* Side slot needs more room than a photo gets (e.g. a slideshow) — copy
   takes 1/3, the side slot takes 2/3. */
.project-row-side-wide { grid-template-columns: 1fr 2fr; }
/* A caption dropped under a side-slot carousel (e.g. the ESG slideshow)
   sits close under it, same as .project-hero-video does for a caption
   under the full-width hero video. */
.project-side-stack .carousel,
.project-carousel-stack .carousel { margin-bottom: 0; }
.project-row-even .project-side-photo {
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
/* A video dropped into the side slot keeps its own ratio instead of the
   4:3 photo default (specificity here has to restate the value, not just
   "unset" it, since aspect-ratio doesn't fall back to the .ratio-3x2 rule). */
.project-row-even .video-frame.ratio-3x2.project-side-photo {
  aspect-ratio: 3 / 2;
  border: none;
}
/* The LinkedIn screenshot is a tall portrait grab — let it run full
   height instead of being cropped into the standard 4:3 side-photo box. */
.project-row-even .project-side-photo[src$="Infra-ESG26-LI.jpg"] {
  aspect-ratio: auto;
  object-fit: contain;
}
.project-trio-row {
  grid-template-columns: repeat(3, 1fr);
  margin-top: 60px;
}

/* In-page slideshow carousel (e.g. the VOX Couture deck in place of a
   project hero). Slides move via a transform on .carousel-track; nav
   with the arrows, arrow keys, or a swipe. See initCarousel in script.js.
   Reduced-motion drops the slide transition via the global rule. */
.carousel {
  position: relative;
  margin-bottom: 44px;
}
.carousel-viewport {
  overflow: hidden;
  border-radius: 4px;
  border: 1px solid var(--line);
}
.carousel-track {
  display: flex;
  transition: transform 0.4s ease;
}
.carousel-slide {
  flex: 0 0 100%;
  width: 100%;
  aspect-ratio: var(--slide-ratio, 16 / 9);
  object-fit: cover;
  display: block;
  background: var(--line);
}
.carousel-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(252, 252, 250, 0.92);
  border: 1.5px solid var(--ink);
  color: var(--ink);
  box-shadow: 2px 2px 0 var(--ink);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.carousel-btn svg { width: 20px; height: 20px; }
.carousel-prev { left: 14px; }
.carousel-next { right: 14px; }
.carousel-btn:hover { box-shadow: 4px 4px 0 var(--ink); }
.carousel-prev:hover { transform: translateY(-50%) translateX(-2px); }
.carousel-next:hover { transform: translateY(-50%) translateX(2px); }
.carousel-btn:active { box-shadow: 1px 1px 0 var(--ink); }
.carousel-status {
  position: absolute;
  right: 14px;
  bottom: 12px;
  margin: 0;
  padding: 3px 11px;
  border-radius: 999px;
  background: rgba(17, 17, 17, 0.78);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.02em;
}

.project-media-pair {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 40px;
  align-items: start;
}
.project-wide-photo {
  width: 100%;
}
.project-side-photo {
  width: 100%;
  display: block;
  border-radius: 3px;
  border: 1px solid var(--line);
}
/* Transparent PNGs (die-cut signage, cut-outs) shouldn't get the hairline
   frame — it just outlines empty space. */
.project-side-photo[src$="bb-dangler.png"] {
  border: none;
  border-radius: 0;
}
.project-tall-photo {
  width: 100%;
  display: block;
  border-radius: 3px;
  border: 1px solid var(--line);
}
.project-media-stack {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
/* A clip that's meant to loop on its own. Wraps the <video> so the
   shared .play-btn can be centred over it as a fallback when autoplay
   is blocked or frozen for reduced motion (see initAutoplayClips). */
.autoplay-clip {
  position: relative;
  overflow: hidden;
  line-height: 0;
}
.autoplay-clip video {
  width: 100%;
  display: block;
}
/* VBNB panel: logo animation sitting in the right column next to the
   copy. Black frame matches the video's own background. */
.vbnb-logo-clip {
  background: var(--ink);
  border-radius: 4px;
  align-self: start;
  max-width: 75%;
}

/* Corporate Comms: looping icon-carousel animation (transparent video)
   in the wide side slot. */
.mattr-icons-clip { align-self: start; }
/* Cards sit well inside the frame's transparent margin, so scaling the
   video up enlarges them without cropping or shifting the layout. */
.mattr-icons-clip video { transform: scale(1.12); }
/* Its ESG slideshow row below gets the same gap the hero leaves above. */
.project-row + .project-carousel-stack { margin-top: 44px; }

/* --- Lost Customers: deflating GIF with an overlapping postcard
   mockup on the left, matching email design on the right. --- */
.lost-visual {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 40px;
  align-items: start;
  margin-bottom: 44px;
}
/* Postcard/margin values below are percentages (not fixed px) so the
   slight-overlap-with-the-gif look scales the same way at every
   breakpoint, since the gif and postcard share the same width and a
   fixed aspect ratio each. */
.lost-visual-media { position: relative; margin-bottom: 68%; }
.lost-gif {
  width: 100%;
  display: block;
  border-radius: 3px;
  border: 1px solid var(--line);
}
.lost-postcard {
  position: absolute;
  width: 136%;
  right: -6%;
  bottom: -83.5%;
  filter: drop-shadow(0 14px 26px rgba(0, 0, 0, 0.22));
}
.lost-email {
  width: 100%;
  display: block;
  border-radius: 3px;
  border: 1px solid var(--line);
}

/* --- About: intro (text + gif placeholder) --- */
.about-intro {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: var(--gutter);
  align-items: center;
  /* First block flows straight out of the <h1> — no divider rule, and
     no extra top padding on top of the page-hero's padding-bottom. */
  border-top: none;
  padding-top: 0;
}
.about-intro-text h2 { line-height: 1em; }
.about-intro-text p { margin-bottom: 16px; }
.about-intro-text p:last-child { margin-bottom: 0; }
.about-intro-gif {
  aspect-ratio: 4 / 5;
  width: 100%;
  max-width: 320px;
  margin: 0 auto;
  display: block;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--line);
}

/* --- About: Competencies (checklist) + Favourite Tools (chip cloud) --- */
.about-skills {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gutter);
  align-items: center;
}
.skills-col { position: relative; }
.skills-col h2 { margin-bottom: 0; }
.skills-col p { margin-bottom: 44px; }

/* Heading, intro line and checklist share one shrink-wrapped, centered
   block so their left edges always line up with each other, whichever
   one happens to be widest. */
.competency-inner { width: fit-content; margin: 0 auto; text-align: left; }

.competency-wrap { position: relative; }
.competency-checklist {
  list-style: none;
  margin: 0;
  padding: 0;
  width: fit-content;
  display: grid;
  grid-template-rows: repeat(6, auto);
  grid-auto-flow: column;
  column-gap: 40px;
  row-gap: 16px;
  position: relative;
  z-index: 1;
  text-align: left;
}
.competency-checklist li {
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 17px;
  color: var(--ink);
}
.check-icon {
  position: relative;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 7px;
  background: var(--pink-wash);
  border: 1px solid var(--pink);
}
.check-icon::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--pink-deep);
  -webkit-mask-image: url('../assets/svg/icon-check.svg');
  mask-image: url('../assets/svg/icon-check.svg');
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: 60%;
  mask-size: 60%;
}
.competency-pencil {
  position: absolute;
  width: 53px;
  height: 90px;
  left: calc(50% + 104px);
  top: 0;
  background-color: var(--pink);
  -webkit-mask: url('../assets/svg/icon-pencil2.svg') no-repeat center / contain;
  mask: url('../assets/svg/icon-pencil2.svg') no-repeat center / contain;
  animation: pencil-float 5s ease-in-out infinite;
  pointer-events: none;
}

.tool-cloud {
  position: relative;
  min-height: 243px;
}
.tool-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(11px, 1.15vw, 13px);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
  padding: 7px 14px;
  border-radius: 999px;
  background: #ebebeb;
  border: 1px solid var(--ink);
  color: var(--ink);
  animation: chip-bob var(--bob-duration, 3.4s) ease-in-out infinite;
  animation-delay: var(--bob-delay, 0s);
  transition: box-shadow 0.2s ease;
}
.tool-chip:hover { box-shadow: 3px 3px 0 var(--ink); }

/* ============================================
   Responsive
   ============================================ */
@media (max-width: 980px) {
  .little-worlds-section { grid-template-columns: 1fr; gap: 32px; }
  .drone-section { grid-template-columns: 1fr; gap: 28px; }
  .play-reel-section { grid-template-columns: 1fr; gap: 28px; }
  .play-flip > :first-child { order: 0; }   /* stacked: copy first, as everywhere else */
  .little-worlds-copy { position: static; }
  .hero { grid-template-columns: 1fr; }
  /* tablet: headline runs on (no break before "Problem solver."), copy and
     icons take the full width; the 640 block narrows them again for phones */
  .hero-headline br { display: none; }
  .hero-copy { max-width: none; }
  /* bigger icons, two loose rows across the width: 5 on top, then 4
     staggered half a column in (10 tracks, each icon spans 2) */
  .hero-right { grid-template-columns: repeat(10, 1fr); grid-template-rows: auto; row-gap: 8px; --icon-size: 78px; }
  .hero-right .doodle-slot { grid-column: span 2; }
  .hero-right .doodle-slot:nth-child(6) { grid-column: 2 / span 2; }
  .doodle-scribble { width: 78px; bottom: -28px; margin-left: 22px; }   /* clear of the now-longer first line */
  .imagery-section .split,
  .brand-section .split { grid-template-columns: 1fr; }
  /* stacked: the cake spills 60% left of the box, so shrink the box and
     shift it right until cake-to-phone fits the column */
  .brand-collage { --drop: 0px; width: 62.5%; margin-left: 37.5%; }
  /* stacked: title + copy lead every section, media follows */
  #video .container { display: flex; flex-direction: column; }
  #video .work-row { order: -1; }
  /* tablet: section titles on one line, copy runs the full width
     (the 640 block brings the title breaks back for phones) */
  .work-title br,
  .imagery-copy .big-title br,
  .brand-copy .big-title br { display: none; }
  .work-copy p,
  .imagery-copy p.desc,
  .brand-copy p.desc { max-width: none; }
  #video .media-wrap { margin: 56px 0 0; }   /* room for the popcorn on the video's corner */
  .imagery-copy { order: -1; }
  .vertical-label { display: none; }   /* all three "// Stuff I Make" captions */
  .popcorn-cluster { display: none; }   /* would sit on the full-width 01 copy */
  /* stacked: sanitizers drop to their natural shape under the copy */
  .imagery-copy .see-work { margin-bottom: 0; }
  .imagery-side { flex: none; margin: 32px 0 0; width: 100%; max-height: none; aspect-ratio: 16 / 9; }
  .work-row { grid-template-columns: 1fr; }
  .gallery-grid,
  .imagery-gallery .gallery-grid,
  .gallery-grid.project-squares-grid--3col { grid-template-columns: repeat(2, 1fr); }
  .project-gallery { grid-template-columns: repeat(2, 1fr); }
  .project-row { grid-template-columns: 1.2fr 1fr; gap: 28px; }
  .project-reel-wrap { max-width: 220px; }
  .project-media-pair { grid-template-columns: 1.2fr 1fr; gap: 28px; }
  .lost-visual { grid-template-columns: 1fr; gap: 32px; }
  .about-intro { grid-template-columns: 1fr; }
  .about-skills { grid-template-columns: 1fr; gap: 50px; }
  /* tablet: About copy runs the full width (Find Me keeps its cap so it
     stays clear of the paw); the 640 block puts the cap back for phones */
  .about-block:not(#find-me) p { max-width: none; }
  .tool-cloud { position: static; min-height: 0; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 18px; }
  .tool-chip { position: static; animation: none; transform: none; }
  /* The larger hero-side media stacks under the heading below tablet width
     (the small icon doodles stay in a row until 640 — see that block). */
  .page-hero.has-decoration:has(.page-hero-media) { flex-direction: column; align-items: flex-start; gap: 28px; }
  .page-hero-media { width: 100%; max-width: 460px; }
  .web-intro { flex-direction: column; align-items: flex-start; gap: 28px; }
}

@media (max-width: 640px) {
  .hero-sparkle--wide { display: none; } /* would sit on the wrapped lede */
  .little-worlds-section { padding-top: 50px; padding-bottom: 60px; }
  .play-reel-section,
  .drone-section { padding-top: 50px; padding-bottom: 60px; }
  .masonry-grid { column-gap: 10px; }
  .square-grid { gap: 10px; }
  .set-design-section .square-grid { grid-template-columns: repeat(2, 1fr); }   /* four across is too small on phones */
  .masonry-grid .gallery-item { margin-bottom: 10px; }
  .nav-links { display: none; }
  .nav-wrap > .btn-pill { display: none; } /* replaced by the overlay's own CTA */
  .nav-toggle { display: flex; }
  .mobile-menu { display: block; }
  .nav-wrap { flex-wrap: wrap; }
  .hero { padding-top: 48px; }
  .about-block:not(#find-me) p { max-width: 60ch; }
  .hero-headline br,
  .work-title br,
  .imagery-copy .big-title br,
  .brand-copy .big-title br { display: inline; }
  .hero-copy { max-width: 46ch; }
  .hero-right .doodle-slot,
  .hero-right .doodle-slot:nth-child(6) { grid-column: auto; }
  .hero-right { grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); row-gap: clamp(10px, 2vw, 30px); max-width: 420px; --icon-size: clamp(56px, 16vw, 64px); }
  .doodle-scribble { width: 92px; bottom: -2px; margin-left: 0; }
  .doodle-arrow { top: calc(-48px - 152px); }
  .work-section { padding: 56px 0; }
  .media-wrap { flex-direction: column; align-items: flex-start; }
  .popcorn-tl { width: 64px; left: -10px; top: -30px; }
  .imagery-grid-top { grid-template-columns: 1fr; }
  .imagery-grid-top img { aspect-ratio: auto; }   /* stacked full-width: natural shape, not 2:3 */
  .footer-cols { flex-direction: column; gap: 32px; }
  .footer-inner { flex-direction: column; gap: 36px; }
  .page-hero { padding-top: 52px; }
  .page-hero.has-decoration { flex-direction: column; align-items: flex-start; gap: 24px; }
  .page-hero-doodle.clapperboard { margin-right: 0; }
  .page-hero-doodle img { width: 76px; }
  .page-hero-doodle.contact-doodles { margin-right: 0; }
  .page-hero-doodle.contact-doodles img { width: 99px; }
  .page-hero-doodle .contact-ginger { margin: 48px 0 0 -14px; }
  .footer-paw { width: 112px; }
  .page-hero-doodle.brand-doodles { width: 200px; margin-right: 0; }
  .page-hero-doodle.brand-doodles .brand-notebook { width: 56%; }
  .page-hero-doodle.brand-doodles .brand-ruler { width: 42%; }
  .page-hero-doodle.brand-doodles .brand-laptop img { width: 100%; }
  .page-hero-doodle.clapperboard { width: 90px; }
  .page-hero-doodle.picture-frame { width: 90px; margin-right: 0; }
  .page-hero-media { width: 100%; max-width: 440px; }
  .work-link-row { padding: 20px 20px; gap: 16px; }
  .work-link-row .arrow { margin-right: 0; }
  .work-link-row:hover .arrow { transform: translateX(6px); }
  .work-link-row .name { line-height: 1.2; }
  .gallery-grid,
  .imagery-gallery .gallery-grid { grid-template-columns: 1fr; gap: 30px; }
  .gallery-grid.web-gallery-grid,
  .gallery-grid.project-squares-grid--3col { grid-template-columns: 1fr; }
  .project-copy-split--single { max-width: 100%; }
  .compare-section { padding-bottom: 60px; }
  .compare-handle { width: 38px; height: 38px; }
  .compare-range::-webkit-slider-thumb { width: 38px; }
  .compare-range::-moz-range-thumb { width: 38px; }
  .lightbox-content { max-width: 92vw; }
  .lightbox-img, .lightbox-video { max-height: 56vh; }
  .lightbox-close { top: 16px; right: 16px; width: 40px; height: 40px; }
  .lightbox-prev { left: 10px; }
  .lightbox-next { right: 10px; }
  .lightbox-prev, .lightbox-next { width: 40px; height: 40px; }
  .accordion-trigger { gap: 14px; padding: 22px 16px; }
  .accordion-trigger:hover { padding-left: 16px; }
  .accordion-name { line-height: 1.2; }
  .project-row { grid-template-columns: 1fr; gap: 32px; }
  .project-twinkles { display: none; }
  .project-copy-split { columns: 1; }
  .project-reel-wrap { justify-self: center; max-width: 220px; }
  .project-gallery { grid-template-columns: repeat(2, 1fr); }
  .project-meta { gap: 20px; }
  .project-media-pair { grid-template-columns: 1fr; gap: 24px; }
  .carousel-btn { width: 38px; height: 38px; }
  .carousel-prev { left: 8px; }
  .carousel-next { right: 8px; }
}

/* Small phones: the 03 collage is too small to read as one picture, so
   stack it as three groups: wall, swag (its own % box built from the
   same mockup coordinates), phone. */
@media (max-width: 480px) {
  /* hero arrow: swing over to the right so its tip clears the headline */
  .doodle-arrow { left: calc(100% - 118px); top: calc(-48px - 152px - 12px); }
  .brand-collage {
    width: auto;
    margin: 8px 0 0;
    aspect-ratio: auto;
    display: flex;
    flex-direction: column;
    gap: 28px;
  }
  .brand-collage > * { position: relative; left: auto; top: auto; }
  .brand-wall { width: 100%; }
  .brand-swag {
    display: block;
    position: relative;
    aspect-ratio: 1060 / 560;
  }
  .brand-mousepad { left: 43.4%; top: 0.9%;  width: 39.2%; }
  .brand-cake     { left: 0.5%;  top: 25.9%; width: 61.3%; }
  .brand-tumbler  { left: 71.5%; top: 22.1%; width: 28.2%; }
  .brand-confetti { left: 40%;   top: 76%;   width: 56%; }
  /* the phone PNG has wide transparent margins: oversize it so the handset
     is ~2/3 of the column, centred, and trim the empty space above/below */
  .brand-phone { width: 120%; margin: -19% 0 -14% -7.6%; }
}
