@charset "UTF-8";
/* ============================================================
   Ramya Samudrala — portfolio
   Design tokens. Change colour or type here, nowhere else.
   ============================================================ */

:root {
  /* Palette. Cool paper canvas so her own (saturated) work carries
     the colour; the page supplies the frame, not the noise. */
  --paper:      #EFF1FB;
  /* Warm paper, not cream: cream drops the pink headline to 4.28:1 and
     fails AA. This holds it at 4.66:1 while still reading as paper. */
  --card:       #FDFBF6;
  --ink:        #12143A;
  --ink-soft:   rgba(18, 20, 58, 0.62);
  --ink-faint:  rgba(18, 20, 58, 0.14);
  /* Deep enough to survive the grain. A lighter pink measures fine on
     clean paper but drops under 4.5:1 wherever the texture darkens it. */
  --pink:       #B81A6A;
  --blue:       #3B4AE0;
  --hilite:     #FFE45C;

  /* Sky — hero only. Deepest at the top, fading to within 1.05:1 of
     --paper at the bottom so the handoff to the page canvas is invisible. */
  --sky-1:      #5AA9F0;
  --sky-2:      #9BCEF7;
  --sky-3:      #DCEEFC;

  /* Measured contrast — check here before colouring anything new.
     The paper figures are sampled from the ACTUAL grained render, not
     from the flat token, because the texture darkens what sits on it:
     pink  on grained paper = 5.4:1  PASS -> headline caps (darkest 1% of grain)
     blue  on grained paper = 5.6:1  PASS -> cursive word
     white on --pink   = 6.2:1  PASS  -> pink fills take WHITE text
     ink   on --pink   = 2.9:1  FAIL  -> never set ink on pink
     pink  on --paper  = 5.5:1  PASS
     white on --blue   = 6.5:1  PASS  -> blue panels take white text
     ink   on --blue   = 2.7:1  FAIL  -> never set ink on blue
     ink   on --hilite = 13.9:1 PASS  -> notes
     ink   on sky      = 7-15:1 PASS  -> all hero text is full ink
     pink  on sky      = 1.9-4.1 FAIL -> pink never sits directly on sky;
                                         it only appears on white paper or
                                         as a fill carrying white text */

  /* Type. Two display faces doing different jobs:
     Archivo = her content's voice (caption typography, hooks).
     Syne    = the site's voice (section headers, wordmark). */
  --f-hook:   "Archivo", system-ui, sans-serif;
  --f-script: "Dancing Script", cursive;
  --f-hand:   "Caveat", cursive;
  --f-disp:   "Syne", system-ui, sans-serif;
  --f-body:   "Instrument Sans", system-ui, sans-serif;
  --f-mono:   "JetBrains Mono", ui-monospace, monospace;
  --f-pixel:  "Silkscreen", "JetBrains Mono", monospace;

  --frame: 10px;
  --gut: clamp(1.25rem, 5vw, 4.5rem);
  --maxw: 1240px;
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: 6.5rem; }

body {
  margin: 0;
  padding: var(--frame);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* The frame — a printed-page border that holds the bright content in. */
.frame {
  position: fixed;
  inset: 0;
  border: var(--frame) solid var(--ink);
  pointer-events: none;
  z-index: 90;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1.25rem;
  z-index: 100;
}
.skip:focus { left: var(--frame); }

/* Ink, not pink: a pink ring measures 2.47:1 on the sky and misses the 3:1
   floor for non-text. Ink is 7:1 there and 15.7:1 on paper, and the offset
   keeps the ring on the page background rather than on a pink fill. */
:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
}

/* ============================================================
   NAV
   ============================================================ */

/* Fixed rather than sticky so the sky runs underneath it — a paper strip
   above the sky would read as a mistake. Transparent at rest; it picks up
   a background once you've scrolled off the hero. */
.nav {
  position: fixed;
  top: var(--frame);
  left: var(--frame);
  right: var(--frame);
  z-index: 80;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem var(--gut);
  background: transparent;
  transition: background 0.25s ease, backdrop-filter 0.25s ease;
}

.nav.is-stuck {
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px);
}

/* Wordmark. Set in the display face rather than the body face so it reads
   as a mark and not as another nav link, but sized to match the pills. */
.nav__mark {
  display: inline-flex;
  align-items: center;
  font-family: var(--f-disp);
  font-weight: 700;
  font-size: 0.9375rem;
  letter-spacing: -0.005em;
  color: var(--ink);
  text-decoration: none;
  margin-right: 0.35rem;
  white-space: nowrap;
}

/* Nav links sit on the left, next to the mark; the CTA keeps the right. */
.nav__pills {
  display: flex;
  gap: 0.4rem;
  margin-right: auto;
}

/* Contact lives in the CTA on desktop; it rejoins the row on mobile.
   Scoped so the later .pill display rule can't cancel it. */
.nav__pills .nav__contact { display: none; }

.pill {
  display: inline-block;
  padding: 0.44rem 0.95rem;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}
.pill:hover {
  background: var(--ink);
  color: var(--paper);
  transform: translateY(-1px);
}

.pill--cta {
  background: var(--pink);
  border-color: var(--ink);
  color: #fff;          /* ink on pink is 3.3:1 — white is 4.8:1 */
  font-weight: 600;
}
.pill--cta:hover { background: var(--ink); color: var(--paper); }

/* On narrow screens the pills scroll sideways rather than disappearing —
   hiding the nav on the device most recruiters use would be the wrong trade. */
@media (max-width: 860px) {
  .nav { padding: 0.7rem 1rem; gap: 0.5rem; }
  .nav__mark { margin-right: 0.25rem; }
  .nav__pills {
    /* Same reason as .slot — without this the pill row refuses to shrink
       and pushes the fixed nav past the viewport instead of scrolling. */
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    margin-right: -1rem;
    padding-right: 1rem;
    -webkit-mask-image: linear-gradient(to right, #000 84%, transparent);
            mask-image: linear-gradient(to right, #000 84%, transparent);
  }
  .nav__pills::-webkit-scrollbar { display: none; }
  .nav__pills .nav__contact { display: inline-block; }
  .pill--cta { display: none; }
  .pill { padding: 0.4rem 0.8rem; font-size: 0.8125rem; }
}

/* A second, smaller sparkle top-left. Positioned rather than inline so it
   sits off the type instead of pushing the centred headline sideways.
   Doubled class to outrank .hook__star, and sized in rem/vw because this
   one lives outside .hook, where `em` would resolve against body text. */
.hook__star.hook__star--sm {
  position: absolute;
  left: 7%;
  top: 13%;
  width: clamp(0.6rem, 0.4rem + 0.6vw, 1rem);
  height: clamp(0.6rem, 0.4rem + 0.6vw, 1rem);
  margin: 0;
  rotate: -14deg;
}

/* ============================================================
   SKY — hero only
   ============================================================ */

.sky {
  position: relative;
  isolation: isolate;
  background: linear-gradient(
    180deg,
    var(--sky-1) 0%,
    var(--sky-2) 46%,
    var(--sky-3) 100%
  );
  /* Clears the fixed nav. */
  padding-top: clamp(4.25rem, 4rem + 1.5vw, 5.25rem);
}

/* Soft cloud bank. Built in CSS so the hero works today.
   DROP-IN SLOT: when the Figma cloud cut-outs land in assets/textures/,
   replace this gradient stack with background-image: url(...) — nothing
   else needs to change. */
/* Two layers drifting at different speeds so the sky has depth rather than
   sliding as one flat sheet. Each layer is twice the width of the hero with
   the puffs tiled every quarter of itself, so translating it by half its
   width lands exactly on a tile boundary and the loop is seamless.
   transform is used rather than background-position to keep it on the GPU. */
.sky__clouds {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}

/* Clouds are fractal noise, not stacked ellipses. Stacked gradients always
   read as discrete blobs; turbulence gives the soft irregular formations a
   real sky has. stitchTiles makes the noise tile seamlessly across the tile
   width, and each layer travels exactly one tile, so the loop never jumps.
   The mask thins them toward the horizon. */
.sky__clouds::before,
.sky__clouds::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: calc(100% + var(--tile));
  background-size: var(--tile) 100%;
  background-repeat: repeat-x;
  will-change: transform, translate;
  animation: drift linear infinite;
  /* The drift animation owns `transform`, so the cursor parallax rides on the
     separate `translate` property instead. The two compose rather than
     fight. Far layer moves less than the near one, which is the parallax. */
  transition: translate 700ms cubic-bezier(0.2, 0.8, 0.2, 1);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,0.92) 38%, rgba(0,0,0,0.32) 74%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,0.92) 38%, rgba(0,0,0,0.32) 74%, transparent 100%);
}

/* High, thin, barely moving. */
.sky__clouds::before {
  translate: calc(var(--mx, 0px) * 0.35) calc(var(--my, 0px) * 0.35);
  --tile: 1200px;
  opacity: 0.5;
  animation-duration: 300s;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1200' height='520'%3E%3Cfilter id='c' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.0032 0.009' numOctaves='6' seed='5' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1.5 0 0 0 -0.62'/%3E%3C/filter%3E%3Crect width='1200' height='520' filter='url(%23c)'/%3E%3C/svg%3E");
}

/* Lower, denser, still slow — a sky you notice only if you watch it. */
.sky__clouds::after {
  translate: calc(var(--mx, 0px) * 1) calc(var(--my, 0px) * 1);
  --tile: 1600px;
  opacity: 0.85;
  animation-duration: 210s;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='520'%3E%3Cfilter id='c' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.0021 0.0065' numOctaves='7' seed='17' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1.9 0 0 0 -0.72'/%3E%3C/filter%3E%3Crect width='1600' height='520' filter='url(%23c)'/%3E%3C/svg%3E");
}

@keyframes drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(calc(-1 * var(--tile)), 0, 0); }
}

/* ============================================================
   HERO
   ============================================================ */

.hero {
  position: relative;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 5rem) var(--gut) clamp(3.5rem, 8vw, 6rem);
  text-align: center;
}

.eyebrow {
  margin: 0 0 clamp(1.5rem, 4vw, 2.75rem);
  font-family: var(--f-mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* Full ink, not ink-soft: soft measures 3.4:1 on the saturated sky. */
  color: var(--ink);
}

/* Identity block. Both lines take full ink, not ink-soft — soft measures
   3.4:1 against the saturated top of the sky. Set in the display and mono
   faces so it reads as a title block rather than another paragraph, and
   kept well under the headline's size so it introduces rather than competes. */
.ident {
  margin-bottom: clamp(1.6rem, 3.5vw, 2.5rem);
}

/* Archivo, not Syne: the name sits directly above an Archivo Black
   headline, and two different display faces stacked that close read as
   two different designs rather than one. */
.ident__name {
  margin: 0 0 0.45rem;
  font-family: var(--f-hook);
  font-weight: 800;
  font-stretch: 105%;
  font-size: clamp(1.375rem, 1.1rem + 1.15vw, 2.375rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
}

.ident__role {
  margin: 0;
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: clamp(0.75rem, 0.7rem + 0.26vw, 0.9375rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
}

.hero__stage { position: relative; }

/* Torn paper behind the headline — the one texture on the page.
   Everything else stays flat so this reads as deliberate.
   The shape and grain are drawn by the inline <svg class="paper">;
   the text sits above it, unfiltered, so the tear can't distort the type. */
.hero__paper {
  position: relative;
  padding: clamp(1.75rem, 4.5vw, 3.25rem) clamp(1.5rem, 4vw, 3rem);
  transform: rotate(-0.8deg);
}

.paper {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  overflow: visible;
}

.paper__fill { fill: var(--card); }

/* Creases. Kept low because this stacks with the grain below it, and both
   darken the paper the headline sits on — measured, not guessed. */
.paper__wrinkle {
  opacity: 0.16;
  mix-blend-mode: multiply;
}

/* Multiply at low opacity. soft-light was tried first and is luminance-
   neutral on near-white paper — it barely moves it, so the texture
   disappeared entirely. Multiply gives real tooth; the headline pink is
   set deep enough to stay above 4.5:1 through the darkest grain pixels.
   Measured, not assumed — see the contrast table in :root. */
.paper__grain {
  opacity: 0.18;
  mix-blend-mode: multiply;
}

@media (max-width: 560px) {
  /* Less tooth on small screens — grain at phone scale reads as dirt. */
  .paper__grain { opacity: 0.12; }
}

/* Headline: heavy caps with one word in loose script, as in the
   reference. The script word overlaps the caps rather than sitting
   politely after them — that overlap is what gives it the energy. */

.hook {
  margin: 0;
  /* Max is capped so "EARN ATTENTION" holds one line once the paper stops
     growing at --maxw. Remember the caps carry font-stretch: 112%, so the
     phrase is ~12% wider than the nominal size suggests. Below ~460px it
     stacks to three lines, which is fine — it just reads as a taller block. */
  font-size: clamp(2.1rem, 7.4vw, 6rem);
  line-height: 0.92;
  letter-spacing: -0.03em;
}

.hook__line {
  display: block;
  position: relative;
}

.hook__cap {
  font-family: var(--f-hook);
  font-weight: 900;
  font-stretch: 112%;
  text-transform: uppercase;
  color: var(--pink);
  /* Soft ink offset, the way the reference sets pink on white. */
  text-shadow: 0.045em 0.05em 0 rgba(18, 20, 58, 0.14);
}

/* The script word is a connector here, not the subject, so it sits a touch
   smaller and clear of the caps. A negative margin works when it follows a
   long word; after a short one it just collides. */
.hook__script {
  font-family: var(--f-script);
  font-weight: 700;
  font-size: 1.02em;
  line-height: 0.8;
  letter-spacing: 0;
  text-transform: none;
  color: var(--blue);
  display: inline-block;
  margin-left: 0.22em;
  transform: rotate(-3.5deg) translateY(-0.08em);
}

/* Flex so the star stays on the same row as the words. As plain inline
   content it wraps to its own line the moment the phrase fills the width. */
.hook__line--2 {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  margin-top: 0.04em;
}

/* The negative right margin cancels the star's contribution to the line
   box, so it can't push the headline onto an extra line. It hangs off the
   end instead, which also keeps the words optically centred. */
.hook__star {
  width: 0.26em;
  height: 0.26em;
  fill: var(--hilite);
  stroke: var(--ink);
  stroke-width: 2.5;
  flex: none;
  margin-top: 0.2em;
  margin-left: 0.16em;
  margin-right: -0.42em;
}

/* --- The signature device: a strategy note --------------------
   Used here on the headline, and on every work sample below.
   It exists to show reasoning, never to decorate.              */

.note {
  position: relative;
  margin: 0;
  background: var(--hilite);
  color: var(--ink);
  padding: 0.85rem 1rem 0.95rem;
  max-width: 13.5rem;
  box-shadow: 0 8px 20px rgba(18, 20, 58, 0.16);
  transform: rotate(-3.5deg);
  font-family: var(--f-hand);
  font-size: 1.1875rem;
  line-height: 1.22;
}

.note__tape {
  position: absolute;
  top: -0.7rem;
  left: 50%;
  width: 4.75rem;
  height: 1.4rem;
  margin-left: -2.375rem;
  background: rgba(255, 255, 255, 0.55);
  border-left: 1px dashed rgba(18, 20, 58, 0.18);
  border-right: 1px dashed rgba(18, 20, 58, 0.18);
  transform: rotate(-3deg);
}

.note__label {
  display: block;
  margin-bottom: 0.15rem;
  font-family: var(--f-mono);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.75;
}

.note__arrow {
  position: absolute;
  width: 7.5rem;
  color: var(--ink);
  pointer-events: none;
}

/* .note--hero removed with the hero note. The base .note above stays —
   it's the annotation device for the work samples. */

.hero__sub {
  max-width: 38rem;
  margin: clamp(2.25rem, 5vw, 3rem) auto 0;
  font-size: clamp(1.0625rem, 1rem + 0.45vw, 1.3125rem);
  line-height: 1.5;
  color: var(--ink);
  text-wrap: pretty;
}

/* Capability chips. Last one inverts — a borrowed beat from the
   reference, kept because it gives the row a stopping point. */
.chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.45rem;
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
}
/* Pixel buttons. Stepped corners are clipped rather than rounded, and the
   ink outline is a second clipped layer sitting 3px outside the fill —
   a real border would round with the box and break the pixel read.
   Layers are ordered by negative z-index inside the li's own stacking
   context, so the label always paints on top. */
.chips li {
  position: relative;
  isolation: isolate;
  padding: 0.62rem 0.95rem 0.55rem;
  background: none;
  border: 0;
  border-radius: 0;
  color: #fff;                 /* 6.2:1 on the pink fill */
  /* Same face and weight as the "See the work" button. */
  font-family: var(--f-body);
  font-weight: 600;
  font-size: 0.8125rem;
  line-height: 1.15;
  letter-spacing: 0;
}

.chips li::before,
.chips li::after {
  content: "";
  position: absolute;
  clip-path: polygon(
    0 6px, 3px 6px, 3px 3px, 6px 3px, 6px 0,
    calc(100% - 6px) 0, calc(100% - 6px) 3px, calc(100% - 3px) 3px,
    calc(100% - 3px) 6px, 100% 6px,
    100% calc(100% - 6px), calc(100% - 3px) calc(100% - 6px),
    calc(100% - 3px) calc(100% - 3px), calc(100% - 6px) calc(100% - 3px),
    calc(100% - 6px) 100%,
    6px 100%, 6px calc(100% - 3px), 3px calc(100% - 3px),
    3px calc(100% - 6px), 0 calc(100% - 6px)
  );
}

/* Outline */
.chips li::before {
  inset: -3px;
  z-index: -2;
  background: var(--ink);
}

/* Fill, with a pixel highlight along the top-left inner edge */
.chips li::after {
  inset: 0;
  z-index: -1;
  background: var(--pink);
  box-shadow: inset 3px 3px 0 0 rgba(255, 255, 255, 0.28);
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.7rem;
  margin-top: 2.25rem;
}

.btn {
  display: inline-block;
  padding: 0.82rem 1.6rem;
  border: 2px solid var(--ink);
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.9375rem;
  text-decoration: none;
  color: var(--ink);
  transition: transform 0.18s ease, background 0.18s ease, color 0.18s ease;
}
.btn--primary { background: var(--pink); color: #fff; }
.btn--ghost   { background: transparent; }
.btn:hover    { transform: translateY(-2px); }
.btn--ghost:hover { background: var(--ink); color: var(--paper); }

/* ============================================================
   SNAPSHOT — KPI row
   Figures stay in ink. The rule carries the accent, not the type.
   ============================================================ */

.snapshot {
  border-top: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
  background: var(--card);
}

.snapshot__grid {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 3.25rem) var(--gut);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

.stat { min-width: 0; }

.stat__rule {
  display: block;
  width: 2.25rem;
  height: 4px;
  background: var(--pink);
  margin-bottom: 0.9rem;
}

.stat__value {
  margin: 0;
  font-family: var(--f-hook);
  font-weight: 900;
  font-stretch: 105%;
  font-size: clamp(2.1rem, 4.4vw, 3.4rem);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.stat__label {
  margin: 0.55rem 0 0.2rem;
  font-family: var(--f-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.stat__meta {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--ink-soft);
}

/* Unfilled content is loud on purpose — nothing ships half-finished. */
.todo {
  font-family: var(--f-mono) !important;
  font-size: 0.9rem !important;
  font-weight: 700 !important;
  letter-spacing: 0.02em;
  background: var(--hilite);
  box-shadow: 0 0 0 0.3rem var(--hilite);
  display: inline-block;
  line-height: 1.5 !important;
}

@media (max-width: 860px) {
  .snapshot__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 460px) {
  .snapshot__grid { grid-template-columns: 1fr; }
}

/* ============================================================
   WORK SECTIONS
   ============================================================ */

/* Section header: full-width strip, label left, figure right. */
.labelbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem var(--gut);
  background: var(--pink);
  color: #fff;                    /* 6.2:1 on pink */
  border-top: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
}

.labelbar__label {
  font-family: var(--f-disp);
  font-weight: 800;
  font-size: clamp(0.9375rem, 0.85rem + 0.4vw, 1.25rem);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.labelbar__figure {
  font-family: var(--f-mono);
  font-weight: 700;
  font-size: clamp(0.6875rem, 0.65rem + 0.2vw, 0.8125rem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* The figure can't sit beside a long label on a phone, and nowrap made it
   push the page sideways. Stack them instead of shrinking the type. */
@media (max-width: 620px) {
  .labelbar {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
  }
  .labelbar__figure { white-space: normal; }
}

/* Case panel: one full-bleed colour block per community. */
.case { border-bottom: 2px solid var(--ink); }

.case__inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(2.25rem, 5vw, 4rem) var(--gut) clamp(2.5rem, 5.5vw, 4.5rem);
}

/* Text left, work right. The samples used to sit under a full-width column
   of copy, which made each panel tall and pushed the second community far
   down the page. Side by side, both read in one screen. */
/* Weighted toward the work, not the copy. The text column runs out well
   before the thumbnails do, so the leftover width goes to the images. */
.case__inner--split {
  display: grid;
  grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.25fr);
  gap: clamp(1.75rem, 3vw, 3rem);
  align-items: start;
}
.case__main { min-width: 0; }

/* Edge to edge. max-width:none makes the inner match the label bar's own
   gutters, so it still lines up with every other section while giving the
   creative the full width to work with. */
.case__inner--full { max-width: none; }

/* Two-column header for a panel that runs full width. Without it the copy
   sits in a half-width block and leaves a dead right-hand side. */
.case__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
  margin-bottom: clamp(2.25rem, 4.5vw, 3.25rem);
}
.case__head .metrics { margin-top: 0; }
.case__head .case__thought { margin-top: clamp(1.25rem, 2.5vw, 1.75rem); }

@media (max-width: 860px) {
  .case__head {
    grid-template-columns: 1fr;
    gap: clamp(1.5rem, 3vw, 2rem);
  }
}
.case__inner--split .samples { margin-top: 0; }
.case__inner--split .samples__grid { grid-template-columns: repeat(3, 1fr); }

@media (max-width: 1000px) {
  .case__inner--split { grid-template-columns: 1fr; }
  .case__inner--split .samples { margin-top: clamp(2rem, 4.5vw, 3rem); }
}
@media (max-width: 600px) {
  .case__inner--split .samples__grid { grid-template-columns: repeat(2, 1fr); }
}

/* ink on blue is 2.7:1, so blue panels are white-on-blue throughout.
   Muted tones are set per panel rather than with a shared opacity: on blue,
   white needs alpha >= 0.80 to clear 4.5:1 for text and >= 0.55 for a line.
   The same opacity that reads fine on paper fails on blue. */
.case--blue {
  background: var(--blue);
  color: #fff;
  --muted: rgba(255, 255, 255, 0.84);   /* 5.1:1 */
  --line:  rgba(255, 255, 255, 0.6);    /* 3.4:1 */
}
.case--paper {
  background: var(--card);
  color: var(--ink);
  --muted: rgba(18, 20, 58, 0.72);
  --line:  rgba(18, 20, 58, 0.4);
}

.case__eyebrow {
  margin: 0 0 0.5rem;
  font-family: var(--f-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.case__title {
  margin: 0 0 0.45rem;
  font-family: var(--f-hook);
  font-weight: 900;
  font-stretch: 108%;
  font-size: clamp(1.75rem, 1.3rem + 2.1vw, 3.25rem);
  line-height: 1;
  letter-spacing: -0.025em;
}

.case__meta {
  margin: 0;
  font-size: 0.875rem;
  color: var(--muted);
}

/* Before -> after, because the delta is the claim, not the total. */
.growth {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.75rem;
  margin: clamp(1.75rem, 4vw, 2.5rem) 0 0;
  font-family: var(--f-hook);
  font-variant-numeric: tabular-nums;
}

.growth__from {
  font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2.25rem);
  font-weight: 700;
  /* No strikethrough: the arrow already says "before". Striking the handover
     figure reads as dismissing it, which isn't the claim. */
  opacity: 0.55;
}

.growth__arrow {
  font-size: clamp(1.25rem, 1rem + 1vw, 1.875rem);
  opacity: 0.7;
}

.growth__to {
  font-size: clamp(2.75rem, 2rem + 3.4vw, 5rem);
  font-weight: 900;
  font-stretch: 110%;
  line-height: 0.9;
  letter-spacing: -0.035em;
}

.growth__delta {
  flex-basis: 100%;
  margin-top: 0.35rem;
  font-family: var(--f-mono);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Supporting metrics. Secondary to the growth figure above them, so they
   share a size and sit on one line rather than competing for the eye. */
.metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem clamp(1.5rem, 4vw, 3rem);
  list-style: none;
  margin: clamp(1.5rem, 3vw, 2rem) 0 0;
  padding: 0;
}
.metrics li { display: flex; flex-direction: column; gap: 0.15rem; }
.metrics__n {
  font-family: var(--f-hook);
  font-weight: 900;
  font-size: clamp(1.375rem, 1.15rem + 1vw, 2rem);
  line-height: 1;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
}
.metrics__l {
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.metrics__note {
  margin: 0.7rem 0 0;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* The point of view. One short paragraph, not a column of beats. */
.case__thought {
  max-width: 40rem;
  margin: clamp(1.75rem, 4vw, 2.5rem) 0 0;
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.1875rem);
  line-height: 1.55;
}

/* The four beats. "What I changed" is the one that proves strategy. */
.beats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem);
  margin-top: clamp(2rem, 4.5vw, 3rem);
}

.beat p { margin: 0; font-size: 0.9375rem; line-height: 1.55; }

.beat__h {
  margin: 0 0 0.5rem;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

@media (max-width: 800px) {
  .beats { grid-template-columns: 1fr; }
}

/* Named campaigns with their own numbers. The events lede claims this work
   is judged on turnout rather than impressions, and the RSVP figure is what
   makes that claim land. */
.campaigns { margin-top: clamp(2rem, 4.5vw, 3rem); }

.campaigns__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 3.5vw, 3rem);
  align-items: start;
}
@media (max-width: 820px) {
  .campaigns__grid { grid-template-columns: 1fr; gap: 2rem; }
}

.campaign { min-width: 0; }

.campaign__name {
  margin: 0 0 1rem;
  padding-bottom: 0.7rem;
  border-bottom: 2px solid var(--line);
  font-family: var(--f-disp);
  font-weight: 700;
  font-size: clamp(1rem, 0.94rem + 0.35vw, 1.1875rem);
  line-height: 1.25;
}

.campaign__stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.1rem 1.25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.campaign__stats li { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.campaign__stats b {
  font-family: var(--f-hook);
  font-weight: 900;
  font-size: clamp(1.375rem, 1.15rem + 1vw, 2rem);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.campaign__stats span {
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Work sample slots. Labelled so an empty one reads as "asset pending"
   rather than as a broken image. */
.samples { margin-top: clamp(2rem, 4.5vw, 3rem); }

.samples__label {
  margin: 0 0 0.9rem;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.samples__grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0.75rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.slot {
  /* Grid items default to min-width:auto, which lets content push a 1fr
     track wider than its share and overflow the page. */
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  border: 2px dashed var(--line);
  color: var(--muted);
  text-align: center;
  padding: 0.5rem;
  font-family: var(--f-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.slot em { font-style: normal; color: var(--line); }

/* Slots are <a> elements with no href yet, so they are inert and skipped by
   keyboard navigation. Adding href turns them into real links and switches
   on the affordance below, with no other change needed. */
.slot { text-decoration: none; }
.slot[href] {
  cursor: pointer;
  border-style: solid;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.slot[href]:hover,
.slot[href]:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 8px 20px rgba(18, 20, 58, 0.18);
}
/* A filled slot stops being a placeholder: solid edge, no padding, and the
   thumbnail crops to the slot's ratio rather than letterboxing. */
.slot--filled {
  border-style: solid;
  padding: 0;
  overflow: hidden;
  box-shadow: 0 10px 24px rgba(18, 20, 58, 0.2);
}
/* On the blue panels a white edge is what makes them read as separate
   objects sitting on the surface rather than windows cut into it. */
.case--blue .slot--filled {
  border-color: rgba(255, 255, 255, 0.9);
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.26);
}
.slot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.slot--reel { aspect-ratio: 9 / 16; }
.slot--card { aspect-ratio: 4 / 5; }

@media (max-width: 900px) {
  .samples__grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 460px) {
  .samples__grid { grid-template-columns: repeat(2, 1fr); }
}

/* Ink panel — the closer. paper on ink is 15.7:1. */
.case--ink {
  background: var(--ink);
  color: var(--paper);
  --muted: rgba(239, 241, 251, 0.78);
  --line:  rgba(239, 241, 251, 0.45);
}

.case__lede + .samples__label { margin-top: clamp(1.75rem, 4vw, 2.5rem); }

.case__lede {
  max-width: 44rem;
  margin: 0.9rem 0 0;
  font-size: clamp(1rem, 0.96rem + 0.25vw, 1.125rem);
  line-height: 1.55;
  color: var(--muted);
}

/* Brand marquee. The row is duplicated in the markup and the track travels
   exactly one row width, so the loop is seamless with no jump. Runs on
   transform to stay on the GPU. */
.marquee {
  overflow: hidden;
  padding: clamp(1.75rem, 4vw, 2.75rem) 0;
  background: #fff;
  border-bottom: 2px solid var(--line);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}

.marquee__track {
  display: flex;
  width: max-content;
  will-change: transform;
  animation: marquee 32s linear infinite;
}

.marquee:hover .marquee__track { animation-play-state: paused; }

.marquee__row {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.5vw, 2rem);
  list-style: none;
  margin: 0;
  padding: 0 clamp(0.5rem, 1.25vw, 1rem);
}

/* Uniform white plates. The supplied logos have wildly different canvases —
   some transparent, some on white, IKEA full-bleed blue — and dropping them
   straight onto the paper panel shows those boxes. A plate normalises them.
   Fixed box + object-fit:contain means a square mark and a wide wordmark
   both sit at a sensible optical size without per-logo tuning. */
/* No plates. The band itself is white instead, which is what lets the
   logos sit bare: several of them carry their own white background, and on
   the paper panel those would read as visible boxes. */
.marquee__item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: clamp(7.5rem, 6.5rem + 4vw, 10rem);
  height: clamp(3.75rem, 3.25rem + 2vw, 5rem);
  padding: 0 0.9rem;
}

.marquee__row img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  /* Explicit, NOT a percentage. A % height here has no definite containing
     block to resolve against, so it silently falls back to auto — which is
     what let the square logos (Starbucks, Veg Non Veg) burst out of the
     plate while every plate still measured the same size. This clamp is the
     plate height less its breathing room. */
  max-height: clamp(2.35rem, 1.85rem + 2vw, 3.6rem);
  object-fit: contain;
}

/* Left to right, as asked: the track starts shifted and travels back. */
@keyframes marquee {
  from { transform: translate3d(-50%, 0, 0); }
  to   { transform: translate3d(0, 0, 0); }
}

/* Client roster */
.roster {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  list-style: none;
  margin: 0 0 2rem;
  padding: 0;
}
.roster li {
  padding: 0.45rem 0.95rem;
  border: 2px solid var(--line);
  font-family: var(--f-disp);
  font-weight: 700;
  font-size: 0.9375rem;
}
.roster__more {
  border-style: dashed !important;
  color: var(--muted);
  font-family: var(--f-mono) !important;
  font-weight: 500 !important;
  font-size: 0.8125rem !important;
}
.roster--plain li {
  border: 0;
  padding: 0.2rem 0;
  font-family: var(--f-mono);
  font-weight: 500;
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.roster--plain li + li::before {
  content: "· ";
  margin-right: 0.4rem;
}

.samples__grid--four  { grid-template-columns: repeat(4, 1fr); }
/* Full-width panel, only three cards: let them run big. The Goa map in
   particular is unreadable at thumbnail size. */
.samples__grid--three { grid-template-columns: repeat(3, 1fr); }
.samples__grid--five  { grid-template-columns: repeat(5, 1fr); }
/* Two grids stacked: portrait reels above, 4:5 cards below. Mixing the
   two ratios in one grid leaves ragged rows, and cropping them to match
   would cut the hook text off the top of every reel. */
.samples__grid + .samples__grid { margin-top: 0.75rem; }
@media (max-width: 800px) {
  .samples__grid--four { grid-template-columns: repeat(2, 1fr); }
  .samples__grid--three { grid-template-columns: repeat(2, 1fr); }
  .samples__grid--five  { grid-template-columns: repeat(3, 1fr); }
}

/* Process — numbered because it is a real sequence that loops. */
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem);
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: none;
}
.step { min-width: 0; border-top: 3px solid var(--pink); padding-top: 0.9rem; }
.step p { margin: 0; font-size: 0.9375rem; line-height: 1.5; color: var(--muted); }
.step__n {
  display: block;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--pink);
}
.step__h {
  margin: 0.3rem 0 0.5rem;
  font-family: var(--f-disp);
  font-weight: 700;
  font-size: 1.0625rem;
}
/* AI note. Sits where the steps end, as a standing capability rather
   than another numbered stage, because it runs across all six. */
.aiwork {
  margin-top: clamp(2rem, 4.5vw, 3rem);
  padding-top: clamp(1.5rem, 3vw, 2rem);
  border-top: 2px solid var(--line);
}
.aiwork p {
  margin: 0;
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.125rem);
  line-height: 1.55;
}

/* Two tools side by side. One reads as an anecdote; two read as a way
   of working. */
.aiwork__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 3.5vw, 3rem);
  align-items: start;
}
@media (max-width: 820px) {
  .aiwork__grid { grid-template-columns: 1fr; gap: 2rem; }
}
.aiwork__item { min-width: 0; }

.aiwork__close {
  margin-top: clamp(1.5rem, 3vw, 2rem) !important;
  padding-top: clamp(1.25rem, 2.5vw, 1.75rem);
  border-top: 2px solid var(--line);
  font-family: var(--f-hand);
  font-size: 1.375rem !important;
  line-height: 1.3 !important;
}

.aiwork__h {
  margin: 0.15rem 0 0.6rem;
  font-family: var(--f-hook);
  font-weight: 900;
  font-stretch: 105%;
  font-size: clamp(1.25rem, 1.1rem + 0.7vw, 1.75rem);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

/* In and out, so the thing reads as a tool with a spec rather than a claim. */
.aiwork__io {
  display: grid;
  gap: 0.5rem;
  list-style: none;
  margin: 1.1rem 0;
  padding: 0;
}
.aiwork__io li {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: baseline;
  padding-left: 0.9rem;
  border-left: 3px solid var(--pink);
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--muted);
}
.aiwork__k {
  flex: none;
  font-family: var(--f-mono);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
}

.aiwork__note {
  font-size: 0.9375rem !important;
  color: var(--muted);
}

.steps__loop {
  margin: clamp(1.75rem, 4vw, 2.5rem) 0 0;
  font-family: var(--f-hand);
  font-size: 1.25rem;
  color: var(--ink);
}
@media (max-width: 860px) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .steps { grid-template-columns: 1fr; } }

/* Bio. Sits in Contact rather than in its own About section: by the time
   someone reaches here they have seen the work and are deciding whether to
   write. A face and two facts at that moment do more than a mid-page bio. */
.bio {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: center;
  padding-bottom: clamp(1.75rem, 3.5vw, 2.5rem);
  margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem);
  border-bottom: 2px solid var(--line);
}
/* No frame. The cut-out is the shape, sitting on the panel the way the
   product cut-outs do on the reference site. The drop-shadow follows the
   silhouette rather than a box, which a box-shadow cannot do. */
.bio__cutout {
  display: block;
  height: clamp(7rem, 5.5rem + 6vw, 11rem);
  width: auto;
  filter: drop-shadow(0 12px 18px rgba(0, 0, 0, 0.45));
  transform: rotate(-2.5deg);
}

.bio__text p {
  margin: 0;
  max-width: 46rem;
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.125rem);
  line-height: 1.55;
}
@media (max-width: 620px) {
  .bio { grid-template-columns: 1fr; justify-items: start; }
}

/* Contact */
.contact {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
@media (max-width: 800px) { .contact { grid-template-columns: 1fr; } }

.contact__links {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}
.contact__links a {
  color: var(--paper);
  font-family: var(--f-mono);
  font-size: 0.875rem;
  text-underline-offset: 4px;
}

.form__row { display: grid; gap: 0.35rem; margin: 0 0 1rem; }
.form label {
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.form input,
.form textarea {
  width: 100%;
  padding: 0.7rem 0.8rem;
  background: transparent;
  border: 2px solid var(--line);
  color: var(--paper);
  font: inherit;
  font-size: 0.9375rem;
}
.form input:focus,
.form textarea:focus { border-color: var(--paper); outline: none; }
.form textarea { resize: vertical; }
.form .btn { border-color: var(--paper); margin-top: 0.25rem; }
.form .btn[disabled] { opacity: 0.6; pointer-events: none; }

/* Off-screen rather than display:none — a hidden field that is not rendered
   at all is skipped by some bots, which defeats the point. */
.form__honey {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.form__status {
  margin: 0.9rem 0 0;
  min-height: 1.2em;
  font-family: var(--f-mono);
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--muted);
}
.form__status--ok    { color: #8CF5C8; }   /* 9.6:1 on the ink panel */
.form__status--error { color: #FFC9DD; }   /* 9.1:1 on the ink panel */
.form__status a { color: inherit; text-underline-offset: 3px; }

/* Footer */
.foot {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: clamp(2.5rem, 5vw, 4rem) var(--gut);
  text-align: center;
}
/* The closer. Set in the display face, not the handwriting one: two
   handwritten asides in a row read as a tic, and this one carries more
   weight standing on its own above the signature. */
.foot__closer {
  margin: 0 0 1.1rem;
  font-family: var(--f-hook);
  font-weight: 900;
  font-stretch: 105%;
  font-size: clamp(1.25rem, 1.05rem + 1vw, 2rem);
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ink);
}

.foot__sig {
  margin: 0 0 0.5rem;
  font-family: var(--f-script);
  font-weight: 700;
  font-size: 2.25rem;
  color: var(--pink);
  line-height: 1;
}
.foot__meta {
  margin: 0;
  font-family: var(--f-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* ============================================================
   MOTION
   ============================================================ */

/* Rise only. The rotation that used to live here belonged to the sticky
   note, and a rotated full-width panel is wider than the viewport, which
   gave the whole page a horizontal scrollbar. Anything that needs a tilt
   opts into it explicitly below. */
/* Scoped to .js on purpose. Hiding content by default and relying on script
   to show it means one broken line of JS blanks whole sections of the page,
   which is exactly what happened once during this build. Without JS these
   rules never apply and everything is simply visible. */
.js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.js .reveal.is-in {
  opacity: 1;
  transform: none;
}

/* The note is the one element that keeps its tilt through the reveal. */
.js .note.reveal { transform: translateY(14px) rotate(-3.5deg); }
.js .note.reveal.is-in { transform: rotate(-3.5deg); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .sky__clouds::before,
  .sky__clouds::after { animation: none; translate: none; transition: none; }
  .marquee__track { animation: none; transform: none; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .js .note.reveal { transform: rotate(-3.5deg); }
  .btn, .pill { transition: none; }
}
