/* Cookie Daddy — neon graffiti one-pager
   Base: near-black wall. Neon lives on small elements.
   One drenched band per page: the magenta merch section. */

:root {
  /* the ground, tinted toward the magenta hue per DESIGN.md */
  --bg: oklch(12% 0.01 330);
  --bg-raise: #111013;
  --line: #232126;
  --ink: #f2f0f4;
  --ink-dim: #9b96a3;
  --ink-wall: #b9b3bf;    /* small copy painted straight onto the wall */
  --ink-quiet: #8b8592;   /* small copy on a solid panel, never on the wall */
  --ink-faint: #5c5763;   /* hairlines + decorative marks only, never body copy */
  --cyan: #35e0ff;
  --magenta: #ff36b0;
  --green: #6dff4a;
  --yellow: #ffe23c;

  /* every translucent black on the page derives from --bg, nothing hardcodes
     the ground colour. scrim = the whole-viewport wall wash; plate = the
     local shadow behind a block of small copy. */
  --scrim-top: color-mix(in srgb, var(--bg) 44%, transparent);
  --scrim-mid: color-mix(in srgb, var(--bg) 70%, transparent);
  --scrim-base: color-mix(in srgb, var(--bg) 84%, transparent);
  --plate: color-mix(in srgb, var(--bg) 78%, transparent);
  --plate-soft: color-mix(in srgb, var(--bg) 40%, transparent);
  /* solid backing for copy that can land on a blown-out photo highlight
     (not just the wall scrim); heavier than --plate so it holds contrast
     against a near-white pixel, not just the darker wall photograph */
  --plate-solid: color-mix(in srgb, var(--bg) 92%, transparent);
  --font-display: "Anton", sans-serif;
  --font-stencil: "Black Ops One", "Anton", sans-serif;
  --font-marker: "Permanent Marker", cursive;
  --font-body: "Space Grotesk", sans-serif;
  --pad-x: clamp(20px, 5vw, 72px);
  /* small text sits on a photographed wall: this keeps it off the bright
     spray without dropping a plate behind every paragraph */
  --wall-shadow:
    0 1px 10px color-mix(in srgb, var(--bg) 90%, transparent),
    0 0 2px color-mix(in srgb, var(--bg) 80%, transparent);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 24px;
  /* the jump bar owns the bottom edge */
  scroll-padding-bottom: 88px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; height: auto; }

a { color: inherit; }

:focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 3px;
  border-radius: 2px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 18px;
  background: var(--cyan);
  color: var(--bg);
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-decoration: none;
}

.skip:focus {
  left: var(--pad-x);
  top: 12px;
}

/* outline-offset clears the link's own fill, so the ring lands on the
   wall behind it, not on the cyan block itself: the default cyan ring
   measures clean there (verified 12.5-12.9:1 at both widths). An
   earlier pass here swapped the ring to --bg thinking it was matching
   its own fill and made it worse (~1:1 against the dark wall instead);
   reverted. No override needed. */

/* ---------- graffiti wall background + particle canvas ----------
   Fixed div instead of background-attachment: fixed; Chrome mobile
   resizes fixed-bg during address-bar collapse. 100lvh + translateZ
   keeps it stable. Body bg color is the load/JS-off fallback. */

.wall {
  position: fixed;
  top: 0; left: 0;
  width: 100vw;
  height: 100lvh;
  z-index: -2;
  background: url("assets/bg-wall.webp") center / cover no-repeat var(--bg);
  transform: translateZ(0);
}

/* readability scrim: every viewport ends dark, so body copy clears 4.5:1
   wherever the wall's bright spray lands behind it */
.wall::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    var(--scrim-top),
    var(--scrim-mid) 55%,
    var(--scrim-base)
  );
}

#fx {
  position: fixed;
  top: 0; left: 0;
  width: 100vw;
  height: 100lvh;
  z-index: -1;
  pointer-events: none;
}

/* ---------- top bar ---------- */

.topbar {
  position: absolute;
  top: 0; left: 0; right: 0;
  z-index: 30;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 20px var(--pad-x);
}

.topbar-mark {
  font-family: var(--font-stencil);
  /* floor halved 10/20 (was 24px): on phones 3.4vw lands at 11-13px */
  font-size: clamp(11px, 3.4vw, 44px);
  letter-spacing: 0.14em;
  color: var(--ink);
  text-decoration: none;
  padding-block: 4px;
}

.topbar-note {
  flex: none;
  font-size: 13px;
  color: var(--ink-quiet);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-shadow: var(--wall-shadow);
  text-decoration: none;
  /* 44px tall including the line box, negative margin keeps the optical
     alignment with the mark's baseline */
  padding: 12px 10px;
  margin: -12px -10px;
  transition: color 160ms ease-out;
}

@media (hover: hover) {
  .topbar-note:hover { color: var(--cyan); }
}

/* ---------- hero ---------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: 88px var(--pad-x) 32px;
  /* the tag is drawn wider than the gutter on purpose (see .hero-logo);
     clip, not hidden, so the hero never becomes a scroll container */
  overflow-x: clip;
}

.hero-inner {
  position: relative;
  z-index: 2;
  /* pinned to the gutter, so the oversized logo box overflows both sides
     evenly instead of stretching this column past the viewport */
  width: 100%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.hero-h1 {
  margin: 0;
  line-height: 0;
}

/* The cutout is square and the painted tag only fills the middle ~78% of
   it; the rest is thin overspray. So the box is drawn wider than the
   viewport on phones (the overspray runs off the edge, the tag itself stays
   inside the gutter) and the transparent top and bottom are pulled back in
   with negative margins.

   --hero-chrome is everything else in the hero that has to stay above the
   fold: top padding, eyebrow, tagline, both CTAs, bottom padding. The logo
   gets whatever height is left, divided by 0.76 because the margins hand
   0.24 of the box back. Measured at 320x640, 375x667, 390x844, 1440x800. */
.hero-logo {
  --hero-chrome: 290px;
  --logo: min(1240px, 118vw, calc((100svh - var(--hero-chrome)) / 0.76));
  width: var(--logo);
  height: var(--logo);
  max-width: none;
  margin-block: calc(var(--logo) * -0.12);
  object-fit: contain;
  filter: drop-shadow(0 24px 80px rgba(255, 54, 176, 0.14));
}

/* LOCKED (Carter, 2026-10-27): on desktop the logo is the big one, full
   stop. Do not clamp it to the fold again; the CTAs landing below the fold
   on short laptop viewports is accepted. Phones keep the fold math above. */
@media (min-width: 1024px) {
  .hero-logo {
    --logo: min(1400px, 86vw);
    /* the overspray is painted edge to edge, so only the bottom gets pulled
       back in, and only a little: the drips run to the bottom edge and a
       bigger pull puts them on the tagline. Values agreed 10/20. */
    margin-block: calc(var(--logo) * -0.03) calc(var(--logo) * -0.05);
  }
}

.eyebrow {
  margin: 0 0 16px;
  font-size: 12px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ink-wall);
  text-shadow: var(--wall-shadow);
}

.topbar-note { color: var(--ink-wall); }

/* hero only (section heads keep the faint wall version): read like the
   tagline, a size up, and drawn over the logo's overspray, not under it */
.hero .eyebrow:not(.eyebrow-ink) {
  position: relative;
  z-index: 1;
  font-size: clamp(14px, 1.5vw, 17px);
  color: var(--ink-dim);
  /* no plate here: its dark halo sat on top of the logo's overspray and
     read as an erased blotch. The text shadow alone carries legibility. */
  background: none;
  box-shadow: none;
  text-shadow: var(--wall-shadow), 0 0 14px rgba(0, 0, 0, 0.9);
}


.tagline {
  margin: 18px 0 0;
  font-size: clamp(17px, 2.2vw, 21px);
  color: var(--ink-dim);
  letter-spacing: 0.02em;
  text-shadow: var(--wall-shadow);
  /* controls where the line breaks instead of leaving it to the gutter */
  text-wrap: balance;
}

/* ---------- buttons ---------- */

.cta-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px 18px;
  margin-top: 28px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0 26px;
  font-family: var(--font-display);
  font-size: 18px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  border: 2px solid transparent;
  border-radius: 2px;
  transition: transform 160ms cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow 160ms cubic-bezier(0.16, 1, 0.3, 1),
              background-color 160ms ease-out,
              color 160ms ease-out;
}

.btn-primary {
  background: var(--magenta);
  color: var(--bg);
  box-shadow: 4px 4px 0 var(--cyan);
}

.btn-primary:focus-visible {
  transform: translate(2px, 2px);
  box-shadow: 2px 2px 0 var(--cyan);
}

/* the default 3px outline-offset lands the ring's bottom/right edge
   directly on the button's own cyan hard-shadow: same color, 1:1. Push
   the ring past the shadow so the whole perimeter sits on the wall. */
.btn-primary:focus-visible {
  outline-offset: 7px;
}

.btn-ghost {
  border-color: var(--ink-wall);
  color: var(--ink);
  background: var(--plate);
}

.btn-ghost:focus-visible {
  border-color: var(--cyan);
  color: var(--cyan);
  transform: translate(2px, 2px);
}

.btn-ink {
  background: var(--bg);
  color: var(--ink);
  box-shadow: 4px 4px 0 var(--cyan);
}

.btn-ink:focus-visible {
  color: var(--cyan);
  transform: translate(2px, 2px);
  box-shadow: 2px 2px 0 var(--cyan);
}

/* hover-only echoes of the focus-visible states above: gated to
   hover-capable pointers so a tap doesn't leave a touch device stuck
   showing the pressed state until the next tap elsewhere */
@media (hover: hover) {
  .btn-primary:hover {
    transform: translate(2px, 2px);
    box-shadow: 2px 2px 0 var(--cyan);
  }
  .btn-ghost:hover {
    border-color: var(--cyan);
    color: var(--cyan);
    transform: translate(2px, 2px);
  }
  .btn-ink:hover {
    color: var(--cyan);
    transform: translate(2px, 2px);
    box-shadow: 2px 2px 0 var(--cyan);
  }
}

/* ---------- shared section bits ---------- */

section {
  padding: clamp(80px, 10vw, 136px) var(--pad-x);
  /* mirrors html's scroll-padding-top so a section landed on via the
     jump bar (or any anchor/focus scroll) never sits flush against the
     viewport edge */
  scroll-margin-top: 24px;
}

/* the fixed jump bar owns the bottom edge; give the two spots the report
   found it landing on (step 03, the merch head) matching scroll-margin so
   a browser-driven scroll into either (anchor jump, Tab focus) reserves
   the bar's footprint instead of parking content behind it */
.steps,
.merch-head {
  scroll-margin-bottom: 88px;
}

.section-head { max-width: 760px; margin-bottom: clamp(40px, 6vw, 68px); }

.section-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(44px, 7vw, 92px);
  line-height: 0.92;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  text-wrap: balance;
}

/* the rotation strip is the index under the wall, not a second headline
   act: same head component, one step down the scale */
.section-title-sm { font-size: clamp(30px, 4.2vw, 54px); }

.section-sub {
  margin: 18px 0 0;
  color: var(--ink-dim);
  font-size: clamp(16px, 1.8vw, 19px);
  max-width: 62ch;
  text-wrap: pretty;
  text-shadow: var(--wall-shadow);
}

/* ---------- the wall plate ----------
   Small copy is painted straight onto a photographed wall. Averaged over a
   text box the scrim already clears AA, but at desktop width a single bright
   spray tag sits behind a whole line and local contrast collapses. A shadow
   sits behind the text box itself, feathered by the box-shadow blur, so it
   reads as the wall going dark rather than as a panel. Nothing animates it,
   nothing moves: width: fit-content keeps the shadow hugging the copy. */

.topbar-note,
.eyebrow:not(.eyebrow-ink),
.tagline,
.section-sub,
.drop-label,
.drop-line,
.drop-note,
.step-num,
.step-tag,
.step-note,
.about-copy,
.share-status {
  width: fit-content;
  background: var(--plate);
  box-shadow: 0 0 20px 7px var(--plate), 0 0 56px 26px var(--plate-soft);
}

/* the stencil split is one mark, so it takes one plate, not two */
.about-split {
  background: var(--plate);
  box-shadow: 0 0 20px 7px var(--plate), 0 0 56px 26px var(--plate-soft);
}

/* ---------- lineup: the tag wall ----------
   Not a card grid: 12 column wall, per tile span + tilt set inline,
   tiles hang from the top of each row so the bottom edge stays ragged. */

.tag-wall {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  align-items: start;
  grid-auto-flow: row dense;
  gap: clamp(14px, 2.2vw, 26px);
  max-width: 1180px;
}

/* Span and tilt come from position on the wall, not from the markup, so a
   tile that moves between the two groups at runtime lands correctly with no
   JavaScript doing layout. Twelve step cycle: rows of 5+4+3, 7+5, 4+3+5,
   5+7, 7+5, every one of them filling the 12 column wall. */
.tag-wall > .tag:nth-child(12n + 1)  { --span: 5; --tilt: -2deg; }
.tag-wall > .tag:nth-child(12n + 2)  { --span: 4; --tilt: 1.5deg; }
.tag-wall > .tag:nth-child(12n + 3)  { --span: 3; --tilt: -1deg; }
.tag-wall > .tag:nth-child(12n + 4)  { --span: 7; --tilt: 1deg; }
.tag-wall > .tag:nth-child(12n + 5)  { --span: 5; --tilt: -1.5deg; }
.tag-wall > .tag:nth-child(12n + 6)  { --span: 4; --tilt: 2deg; }
.tag-wall > .tag:nth-child(12n + 7)  { --span: 3; --tilt: -0.8deg; }
.tag-wall > .tag:nth-child(12n + 8)  { --span: 5; --tilt: 1.2deg; }
.tag-wall > .tag:nth-child(12n + 9)  { --span: 5; --tilt: -1.6deg; }
.tag-wall > .tag:nth-child(12n + 10) { --span: 7; --tilt: 0.9deg; }
.tag-wall > .tag:nth-child(12n + 11) { --span: 7; --tilt: -1.2deg; }
.tag-wall > .tag:nth-child(12n + 12) { --span: 5; --tilt: 1.6deg; }

/* An 11-tile week (the whole library, which is also the default when no
   week is posted) ends on the 7+7 step, so tile 11 sat alone on a half
   empty row. When the week group stops at tile 11, run 9-11 as one 4/4/4
   row instead. Rotation tiles have their own fixed span and are untouched. */
.tag-wall:has(> .tag[data-state="week"]:nth-child(12n + 11) + [data-break]) > .tag:is(:nth-child(12n + 9), :nth-child(12n + 10), :nth-child(12n + 11)) {
  --span: 4;
}

/* the first tile on the wall is the one that gets to be loud */
.tag-wall > .tag[data-state="week"]:first-child .tag-name {
  font-size: clamp(26px, 3.4vw, 40px);
}

.tag {
  --accent: var(--cyan);
  /* print colour on the chip. Every wrapper colour in the set clears 5.7:1
     or better against this near-black, so it is the default; the matte
     black wrapper overrides it to ink, which is what that pack prints. */
  --accent-on: #0a0a0a;
  --edge: color-mix(in srgb, var(--accent) 35%, var(--line));
  --tilt: 0deg;
  position: relative;
  grid-column: span 12;
  overflow: hidden;
  background: var(--bg-raise);
  border: 1px solid var(--edge);
  border-radius: 6px;
  transform: rotate(var(--tilt));
  transition: transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
              border-color 200ms ease-out,
              box-shadow 200ms ease-out;
}

/* Square, uncropped, every tile. The wrapper shots put the pack on one
   diagonal and the cookie on the other, so any band crop clips one end of
   the composition. The wall gets its irregularity from column span and
   tilt instead, which survives a re-render that reframes the shot. */
.tag-photo {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.tag-body { padding: 16px 20px 18px; }

@media (hover: hover) {
  .tag:hover {
    transform: rotate(0deg) translateY(-4px);
    border-color: var(--accent);
    box-shadow: 0 14px 44px -14px color-mix(in srgb, var(--glow, var(--accent)) 45%, transparent);
  }
}

/* the flavour line off the pack itself: print on the wrapper colour, not
   glowing text floating on the tile. Makes the colour-per-flavour system
   legible without a legend. */
.tag-name {
  display: inline-block;
  padding: 3px 12px 5px;
  border-radius: 2px;
  background: var(--accent);
  color: var(--accent-on);
  font-family: var(--font-marker);
  font-size: clamp(21px, 2.5vw, 27px);
  line-height: 1.2;
}

.tag-desc {
  display: block;
  margin-top: 12px;
  font-size: 14px;
  color: var(--ink-dim);
  letter-spacing: 0.02em;
}

.tag-wall > .tag[data-state="week"]:first-child .tag-body {
  padding: 20px 24px 24px;
}

/* ---------- 20g+ protein: every tile carries it ----------
   Readable text of the pill printed on the pack, echoing its shape. Every
   flavor is a protein cookie, so this is on every tile, not a sub-line. */

.tag-macro {
  display: inline-block;
  margin-top: 14px;
  padding: 3px 11px 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-quiet);
}

/* ---------- off this week ----------
   Same wall, same nodes, one attribute apart. Tiles in the rotation group
   shrink to an index under the week's tiles: dimmed art, name only, no
   tilt, no lift. /api/menu flips data-state and moves the node; nothing
   else has to change. */

.wall-break {
  grid-column: span 12;
  margin: clamp(40px, 6vw, 76px) 0 clamp(4px, 1vw, 12px);
}

.wall-break .section-sub { max-width: 52ch; }

.tag[data-state="rotation"] {
  transform: none;
  border-color: var(--line);
  border-radius: 3px;
}

/* off this week, and it looks it. Not opacity: a half transparent tile on
   the photographed wall reads as broken, not as parked. */
.tag[data-state="rotation"] .tag-photo { filter: brightness(0.66) saturate(0.8); }

.tag[data-state="rotation"] .tag-body { padding: 10px 12px 12px; }

.tag[data-state="rotation"] .tag-name {
  padding: 2px 8px 3px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 13px;
  line-height: 1.35;
  letter-spacing: 0.04em;
}

.tag[data-state="rotation"] .tag-desc,
.tag[data-state="rotation"] .tag-macro { display: none; }

@media (hover: hover) {
  .tag[data-state="rotation"]:hover {
    transform: none;
    border-color: var(--line);
    box-shadow: none;
  }
  .tag[data-state="rotation"]:hover .tag-photo { filter: none; }
}

/* ---------- where it's at ---------- */

.cart-grid {
  display: grid;
  grid-template-columns: 7fr 5fr;
  gap: clamp(40px, 6vw, 88px);
  align-items: start;
  max-width: 1180px;
}

.drop {
  border-top: 2px solid var(--magenta);
  padding-top: 22px;
}

.drop-label {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ink-wall);
  text-shadow: var(--wall-shadow);
}

.drop-line {
  margin: 14px 0 0;
  font-family: var(--font-display);
  font-size: clamp(38px, 6vw, 76px);
  line-height: 0.98;
  text-transform: uppercase;
  letter-spacing: 0.005em;
}

.drop-handle {
  display: block;
  /* fit-content so the focus ring hugs the handle text instead of the
     full column width, which used to carry it across "posted on" above */
  width: fit-content;
  padding-block: 4px;
  color: var(--magenta);
  text-decoration: none;
  text-shadow: 0 0 30px rgba(255, 54, 176, 0.35);
  transition: color 160ms ease-out, text-shadow 160ms ease-out;
}

@media (hover: hover) {
  .drop-handle:hover {
    color: var(--cyan);
    text-shadow: 0 0 30px rgba(53, 224, 255, 0.4);
  }
}

.drop-note {
  margin: 20px 0 0;
  color: var(--ink-dim);
  font-size: 16px;
  max-width: 40ch;
  text-shadow: var(--wall-shadow);
}

/* three steps, tagged on the wall: no boxes, no icons */

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(26px, 4vw, 44px);
}

.step {
  position: relative;
  padding-left: 62px;
}

.step:nth-child(2) { margin-left: clamp(0px, 3vw, 34px); }
.step:nth-child(3) { margin-left: clamp(0px, 1.5vw, 16px); }

.step-num {
  position: absolute;
  left: 0;
  top: 2px;
  font-family: var(--font-stencil);
  font-size: 34px;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px var(--ink-wall);
}

.step-tag {
  display: block;
  font-family: var(--font-marker);
  font-size: clamp(26px, 3.4vw, 40px);
  line-height: 1.05;
  color: var(--ink);
  transform: rotate(-1.5deg);
  transform-origin: left center;
}

.step:nth-child(2) .step-tag { transform: rotate(1.2deg); color: var(--cyan); }
.step:nth-child(3) .step-tag { transform: rotate(-0.8deg); color: var(--green); }

.step-note {
  display: block;
  margin-top: 8px;
  font-size: 15px;
  color: var(--ink-wall);
  max-width: 32ch;
  text-shadow: var(--wall-shadow);
}

/* ---------- merch: the one drenched band ---------- */

.merch {
  position: relative;
  background: var(--magenta);
  color: var(--bg);
  padding-block: clamp(72px, 9vw, 120px);
}

.merch-inner {
  max-width: 1320px;
  margin-inline: auto;
}

.merch-head { max-width: 720px; }

/* solid ink inside the drenched band: faded black measured 4.10:1 at 12px,
   and stencil ink is the right look anyway */
.eyebrow-ink { color: var(--bg); text-shadow: none; }

/* the cyan focus ring is unmissable on the near-black wall and lands at
   2.07:1 on magenta, so the band flips it to ink */
.merch :focus-visible { outline-color: var(--bg); }

.merch-title {
  color: var(--bg);
  font-size: clamp(52px, 9vw, 118px);
  line-height: 0.9;
}

.merch-sub {
  margin: 20px 0 0;
  font-family: var(--font-marker);
  font-size: clamp(20px, 2.6vw, 28px);
  line-height: 1.3;
  color: var(--bg);
}

.merch-head .btn-ink { margin-top: 24px; }

.merch-rack {
  list-style: none;
  margin: clamp(44px, 6vw, 72px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(16px, 2.4vw, 32px);
  align-items: start;
}

.piece { margin: 0; }

/* two pieces, tee and hat: the hat hangs lower so the pair reads as a
   rack, not a two-up grid */
.piece:nth-child(2) { margin-top: clamp(28px, 5vw, 72px); }

.piece img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border: 2px solid var(--bg);
  box-shadow: 10px 10px 0 color-mix(in srgb, var(--bg) 30%, transparent);
  transition: transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
              box-shadow 200ms cubic-bezier(0.16, 1, 0.3, 1);
}

.piece-name {
  display: block;
  margin-top: 16px;
  font-family: var(--font-display);
  font-size: clamp(18px, 2vw, 26px);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bg);
}

@media (hover: hover) {
  .piece:hover img {
    transform: rotate(-1.4deg) translateY(-6px);
    box-shadow: 14px 16px 0 color-mix(in srgb, var(--bg) 32%, transparent);
  }
  .piece:nth-child(even):hover img { transform: rotate(1.4deg) translateY(-6px); }
}

.merch-fine {
  margin: clamp(36px, 5vw, 56px) 0 0;
  font-size: 14px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bg);
}

/* ---------- about ---------- */

.about-grid {
  display: grid;
  grid-template-columns: 3fr 2fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
  max-width: 1080px;
}

.about-copy {
  margin: 18px 0 0;
  color: var(--ink-dim);
  font-size: clamp(16px, 1.8vw, 19px);
  max-width: 55ch;
  text-wrap: pretty;
  text-shadow: var(--wall-shadow);
}

.about-split {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  font-family: var(--font-stencil);
  text-transform: uppercase;
  line-height: 1.1;
  font-size: clamp(26px, 3.4vw, 48px);
}

.split-a {
  color: var(--magenta);
  text-shadow: 0 0 22px rgba(255, 54, 176, 0.35);
}

.split-b {
  color: var(--green);
  text-shadow: 0 0 22px rgba(109, 255, 74, 0.3);
}

.rules {
  list-style: none;
  margin: clamp(48px, 7vw, 84px) 0 0;
  padding: 0;
  max-width: 1080px;
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 2vw, 22px);
}

.rule {
  font-family: var(--font-marker);
  font-size: clamp(26px, 4.4vw, 52px);
  line-height: 1.1;
  color: var(--ink);
  /* no single word stranded on the second line at phone widths */
  text-wrap: balance;
}

.rule:first-child { transform: rotate(-1.2deg); transform-origin: left center; }
.rule:last-child {
  color: var(--magenta);
  transform: rotate(0.8deg);
  transform-origin: left center;
  text-shadow: 0 0 26px rgba(255, 54, 176, 0.3);
}

/* ---------- 404 ---------- */

.error-code {
  font-size: clamp(72px, 16vw, 200px);
  margin: 0;
}

/* ---------- footer ---------- */

.footer {
  padding: clamp(72px, 9vw, 120px) var(--pad-x) clamp(104px, 12vw, 132px);
  border-top: 1px solid var(--line);
  text-align: left;
}

.footer-handle {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(34px, 5vw, 56px);
  line-height: 1;
  letter-spacing: 0.02em;
}

.footer-handle a {
  display: inline-block;
  padding-block: 6px;
  color: var(--ink);
  text-decoration: none;
  transition: color 160ms ease-out;
}

@media (hover: hover) {
  .footer-handle a:hover { color: var(--magenta); }
}

.footer-email {
  margin: 14px 0 0;
  font-size: 16px;
}

.footer-email a,
.drop-note a,
.merch-sub a {
  color: inherit;
  text-underline-offset: 3px;
  white-space: nowrap;
}

@media (hover: hover) {
  .footer-email a:hover,
  .drop-note a:hover { color: var(--magenta); }
}

.footer-marker {
  margin: 26px 0 0;
  font-family: var(--font-marker);
  font-size: clamp(20px, 2.4vw, 28px);
  color: var(--cyan);
  transform: rotate(-1.4deg);
  transform-origin: left center;
}

/* ---------- send this to someone ----------
   The one action on the page that can fail, so it says which way it went. */

.drop-share {
  margin: 26px 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
}

.btn-line {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 16px;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-wall);
  background: var(--plate);
  border: 1px solid var(--line);
  border-radius: 2px;
  cursor: pointer;
  transition: color 160ms ease-out, border-color 160ms ease-out;
}

@media (hover: hover) {
  .btn-line:hover { color: var(--cyan); border-color: var(--cyan); }
}

.share-status {
  font-size: 14px;
  color: var(--ink-wall);
  text-shadow: var(--wall-shadow);
}

.share-status.is-ok { color: var(--green); }
.share-status.is-warn { color: var(--yellow); }

/* ---------- jump bar ----------
   Six sections and 10,000px of scroll needed somewhere to stand. Tag pills,
   the documented component, pinned to the bottom left rather than a full
   width bar so the wall keeps the rest of the edge. */

.jump {
  position: fixed;
  left: var(--pad-x);
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 40;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 8px;
  transition: opacity 240ms cubic-bezier(0.16, 1, 0.3, 1),
              transform 240ms cubic-bezier(0.16, 1, 0.3, 1),
              visibility 240ms;
}

/* visibility, not just opacity: an invisible bar must not be tabbable */
.jump.is-hidden {
  visibility: hidden;
  opacity: 0;
  transform: translateY(14px);
  pointer-events: none;
}

.jump a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 14px;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  text-decoration: none;
  color: var(--ink-dim);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  border: 1px solid var(--line);
  border-radius: 2px;
  transition: color 160ms ease-out, border-color 160ms ease-out;
}

@media (hover: hover) {
  .jump a:hover { color: var(--cyan); border-color: var(--cyan); }
}

.jump a[aria-current="true"] {
  color: var(--magenta);
  border-color: var(--magenta);
}

.jump-mark {
  min-width: 44px;
  font-family: var(--font-stencil);
  font-size: 15px;
  letter-spacing: 0.1em;
  color: var(--ink) !important;
}

.jump-follow {
  color: var(--bg) !important;
  background: var(--magenta) !important;
  border-color: var(--magenta) !important;
}

@media (hover: hover) {
  .jump-follow:hover {
    background: var(--cyan) !important;
    border-color: var(--cyan) !important;
  }
}

/* ---------- responsive ---------- */

.tag[data-state="rotation"] { grid-column: span 4; }

@media (min-width: 700px) {
  .tag { grid-column: span 6; }
  .tag[data-state="rotation"] { grid-column: span 3; }
}

@media (min-width: 1000px) {
  .tag { grid-column: span var(--span, 4); }
  .tag[data-state="rotation"] { grid-column: span 2; }
}

/* the band was leaving 600 by 500px of flat magenta to the right of the
   title, then stacking a four column rack under it. One composition
   instead: head and fine print left, rack filling the right. */
@media (min-width: 1080px) {
  .merch-inner {
    display: grid;
    grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
    column-gap: clamp(40px, 5vw, 88px);
    align-items: start;
  }
  .merch-head { max-width: none; grid-column: 1; grid-row: 1; }
  .merch-rack { grid-column: 2; grid-row: 1 / span 2; margin-top: 0; }
  .merch-fine { grid-column: 1; grid-row: 2; margin-top: clamp(40px, 5vw, 64px); }
}

@media (max-width: 900px) {
  .about-grid { grid-template-columns: 1fr; }
  .about-split { align-items: flex-start; text-align: left; }
  .cart-grid { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  /* the bar spans the gutter on phones and the labels tighten up */
  .jump { left: 12px; right: 12px; justify-content: space-between; gap: 6px; }
  .jump::after {
    content: "";
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    height: 128px;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(to top, var(--scrim-base), transparent);
  }
  .jump a { padding: 0 10px; font-size: 11px; letter-spacing: 0.08em; }
  .jump-mark { font-size: 13px; }
}

@media (max-width: 520px) {
  /* the mark and the handle start crowding each other; the hero CTA
     carries the follow action on phones */
  .topbar-note { display: none; }
}

/* at 320 the five pills in the jump bar ran past the right gutter and the
   Follow pill got clipped. Tighten the pills rather than drop one: all five
   still clear 44px of height. */
@media (max-width: 374px) {
  .jump { gap: 4px; }
  .jump a { padding: 0 6px; font-size: 10px; letter-spacing: 0.04em; }
  .jump-mark { min-width: 34px; font-size: 12px; }
}

/* phones: two 3:4 shots side by side land at ~130px wide at 320, too small
   to read a wordmark on a shirt. Stack them instead, staggered, tee left
   and larger, hat right. */
@media (max-width: 559px) {
  .merch-rack { grid-template-columns: 1fr; gap: 28px; }
  .piece:nth-child(1) { width: 86%; }
  .piece:nth-child(2) { width: 74%; justify-self: end; margin-top: 0; }
  .piece:nth-child(2) .piece-name { text-align: right; }
}

@media (max-width: 560px) {
  /* two balanced lines beats one line hugging the gutter */
  .tagline { max-width: 30ch; }
  .cta-row { width: 100%; }
  .cta-row .btn { flex: 1 1 auto; }
  .step { padding-left: 52px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .tag, .piece img, .btn, .jump { transition: none; }
  .tag:hover { transform: rotate(var(--tilt)); }
  .tag[data-state="rotation"]:hover { transform: none; }
  .piece:hover img { transform: none; }
}
