/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   HOMEPAGE STYLES – only used by index.html.
   Case studies use style.css, so changes here never affect them.
   Written phone-first: the base styles are for phones,
   and the (min-width: 701px) blocks change things for desktop.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */

/* ── Fonts ── */
@font-face {
  font-family: "Neue Montreal";
  src: url("../Assets/fonts/PP Neue Montreal - Free for Personal Use v3.0/otf/PPNeueMontreal-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
}
@font-face {
  font-family: "Neue Montreal";
  src: url("../Assets/fonts/PP Neue Montreal - Free for Personal Use v3.0/otf/PPNeueMontreal-Italic.otf") format("opentype");
  font-weight: 400;
  font-style: italic;
}
@font-face {
  font-family: "Neue Montreal";
  src: url("../Assets/fonts/PP Neue Montreal - Free for Personal Use v3.0/otf/PPNeueMontreal-Semibold.otf") format("opentype");
  font-weight: 500 600;
  font-style: normal;
}
@font-face {
  font-family: "PP Mondwest";
  src: url("../Assets/fonts/PPMondwest-Regular.otf") format("opentype");
  font-display: swap;
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   VARIABLES – change things here first.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
:root {
  /* colours */
  --page: #FFFFFF;
  --fg: #0A0A0A;
  --soft: #6B6B6B;
  --faint: #BDBDBD;
  --tile: #E6E4E0;
  --rule: #E2E2E2;
  /* ONE version of each brand colour is used across the homepage, so the brand stays consistent.
     The older, stronger versions are saved below (…-strong / …-old) – swap them back in here if needed.
     (Homepage only – the case studies and their scribble transitions keep their own colours.) */
  --pink-strong: #FF61A3;       /* saved: original brand pink */
  --green-strong: #22C55E;      /* saved: original brand green */
  --blue-float-old: #3F3CF0;    /* saved: the old float / marquee blue */

  --brand-yellow: #FFF302;
  --adfin-bg: #084235;          /* Adfin tile – same deep green as the Adfin case study */
  --adfin-purple: #B3BFFF;      /* Adfin lavender (same as the case study's sub-subheadings) */
  --brand-blue: #3A39FF;
  --forage-bg: #A98BE3;         /* forage tile – the deck's lilac (the star in the logo) */
  --forage-lime-light: #ECFFC0; /* forage light lime – hover titles */
  --adfin-caption: #35927D;     /* Adfin's subtle dark green (same as the case study's captions) */
  --title-shade: 45%;           /* how much tile colour to keep in the darker/subtler title text – lower = stronger */
  --slack-green: #2EB67D;      /* Slack green – the greenmode case study’s accent */
  --slack-bg: color-mix(in srgb, color-mix(in srgb, var(--brand-blue), var(--pink-strong)) 45%, var(--fg));   /* slack tile – blue + pink, darkened */  --accent: var(--brand-blue);  /* marquee, float accents, "digital", "hand-made" … */
  /* softer versions of the brand pink + green (mixed with white) for the playground bars */
  --soft-mix: 75%;              /* how much brand colour to keep – lower = lighter */
  --pink-soft: color-mix(in srgb, var(--pink-strong) var(--soft-mix), var(--page));
  --green-soft: color-mix(in srgb, var(--green-strong) var(--soft-mix), var(--page));
  --brand-pink: var(--pink-soft);    /* the homepage pink */
  --live-green: var(--green-soft);   /* the homepage green – "shipped" dot, Adfin, side quests */

  --float-bg: #F9EAD6;          /* same beige as the float case study (float.css) */
  --float-ink: var(--accent);
  --sound-bg: #101010;          /* same black as the soundtrack case study (spotify.css) */
  --sound-ink: #F2E35C;
  --deco-bg: var(--brand-pink);   /* decorate tile – the homepage pink */
  --deco-ink: #FFE95C;

  /* fonts */
  --sans: "Neue Montreal", Inter, "Helvetica Neue", Arial, sans-serif;
  --mono: "Roboto Mono", ui-monospace, Menlo, monospace;
  --serif: "Newsreader", Georgia, serif;
  --pixel: "PP Mondwest", "Silkscreen", monospace;
  --display: "Instrument Sans", var(--sans);   /* the "playground" title */

  /* spacing scale */
  --space-3xs: 0.125rem;
  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-sm: 0.75rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-2xl: 3rem;
  --space-3xl: 4rem;
  --space-4xl: 5rem;
  --gutter: var(--space-md);                               /* page edge padding */
  --tile-pad: var(--space-md);                             /* labels inside tiles */
  --tile-pad-wide: var(--space-md);                       /* padding of tiles with text blocks (bigger on desktop) */

  /* text scale */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-md: 1rem;
  --text-lg: 1.25rem;
  --text-xl: 1.5rem;
  --text-2xl: 2rem;
  --text-3xl: 2.5rem;
  --text-4xl: 4rem;

  /* named text sizes (phone values – desktop values are in the media query below) */
  --text-tagline: var(--text-lg);
  --text-tile-title: var(--text-2xl);        /* float, soundtrack, decorate */
  --text-tile-heading: var(--text-lg);       /* black tagline tile */
  --text-tile-small: var(--text-lg);         /* small tiles */
  --text-sketch: var(--text-xs);             /* text inside the UI sketches */
  --text-sketch-heading: var(--text-sm);
  --accent-word-scale: 1.15;                 /* "digital" and "hand-made" are a bit bigger than the tagline */

  /* line height and letter spacing */
  --leading-tight: 0.9;
  --leading-heading: 1.1;
  --leading-snug: 1.25;
  --leading-body: 1.4;
  --leading-nav: 1.5;      /* nav + buttons (matches the case studies' body text) */
  --tracking-tight: -0.05rem;
  --tracking-tighter: -0.1rem;

  /* lines, corners, layers */
  --hairline: 0.0625rem;
  --stroke: 0.125rem;
  --skip-stroke: calc(var(--stroke) * 2);   /* the flower buttons' arrow + × thickness, one setting */
  --radius-sm: 0.5rem;
  --radius-md: 0.75rem;
  --radius-pill: 999rem;
  --button-radius: 0;   /* all buttons are square-cornered (pills were tried: var(--radius-pill)) */
  --button-text: var(--text-facts);       /* same size as the header's "currently" / "previously" (tried --text-sm = nav size, --text-md, --text-lg) */
  --button-leading: var(--leading-snug);  /* same line height as "currently" / "previously" (was --leading-nav) */
  --button-font: var(--sans);              /* same font as the nav links (tried the heading font: var(--display)) */
  --button-pad-block: var(--space-xs);    /* was --space-2xs – roomier, same as the cursor pill's 0.5rem */
  --button-pad-inline: var(--space-md);   /* was --space-sm */
  --underline-offset: 0.25rem;
  --layer-label: 2;
  --dim: 0.7;

  /* sticky bars */
  --nav-height: 3.5rem;

  /* motion */
  --hover-grow: 1.05;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --hover-time: 300ms;
  --bob-time: 4s;
  --scrub-time: 6s;
  --marquee-time: 28s;

  /* header size */
  --header-scale: 0.9;          /* shrinks or grows the logo and all header text together */
  --text-facts: calc(var(--text-md) * var(--header-scale)); /* currently / previously */
}

@media (min-width: 701px) {
  :root {
    --text-facts: calc(var(--text-lg) * var(--header-scale));
    --text-tagline: var(--text-3xl);
    --text-tile-title: var(--text-3xl);
    --text-tile-heading: var(--text-3xl);
    --text-tile-small: var(--text-2xl);
    --text-sketch: var(--text-sm);
    --text-sketch-heading: var(--text-md);
    --tile-pad-wide: var(--space-lg);
  }
}


/* ── Base ── */
/* padding counts inside each box, so tiles keep their exact shape */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
}

body {
  background: var(--page);
  color: var(--fg);
  font-family: var(--sans);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
}

p {
  margin: 0;
}

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

/* hidden holder for the SVG roughen filter */
.svg-defs {
  position: absolute;
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   NAV – name on the left, links on the right.
   HTML: index.html → .nav
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
/* matches the case study header exactly (style.css → header, .name, .header-links),
   so "kinza ghanchi" and the links sit in the same spot on every page */
.nav {
  position: sticky;
  inset-block-start: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  block-size: var(--nav-height);
  padding-inline: var(--space-lg);
  background: var(--page);
  font-size: var(--text-sm);
  line-height: var(--leading-nav);
}

.nav div {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
}

.nav a {
  white-space: nowrap;
}

.nav .me {
  font-weight: 400;   /* case studies ask for 500, but their font only has 400/600 files, so it shows as regular – match that */
}

/* hover (and click): the link wobbles with the roughen filter (home.js keeps the filter moving) */
.nav a:hover,
.nav a:focus-visible,
.nav a.is-jittering {
  filter: url("#roughen");
}

.nav .me {
  padding-inline-start: 0;
}

.nav .is {
  background: var(--fg);
  color: var(--page);
}

.nav .filters {
  display: none;
}

@media (min-width: 701px) {
  .nav .filters {
    display: flex;
  }
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   HEADER (MAST) – logo video, tagline, currently / previously.
   HTML: index.html → header.mast
   Phone: everything stacks. Desktop: logo + text side by side, centred.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.mast {
  --logo-size: calc(34rem * var(--header-scale));
  --logo-text-gap: var(--space-2xl);
  --fact-width: calc(18rem * var(--header-scale));
  --tagline-width: calc(40rem * var(--header-scale));
  --space-above-drawing: 0.18;   /* share of the logo video that's empty above the drawing */
  --space-below-drawing: 0.14;   /* share of the logo video that's empty below the drawing */

  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding-block: var(--space-xs) var(--space-xl);
  padding-inline: var(--gutter);
  background: var(--page);
}

.mast video {
  display: block;
  inline-size: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
}

.mast .line {
  font-size: calc(var(--text-tagline) * var(--header-scale));
  line-height: var(--leading-snug);
}

.mast .facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md) var(--space-xl);
  margin-block-start: var(--space-lg);
  font-size: var(--text-facts);
  line-height: var(--leading-snug);
}

/* "recognition": its own label under "currently", with a little star badge before each award */
.mast .facts-label {
  margin-block-start: var(--space-lg);
}

.mast .awards {
  margin: 0;
  padding: 0;
  list-style: none;
}

.mast .awards li {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.mast .awards li::before {
  content: "";
  flex: none;
  inline-size: var(--text-md);   /* a small star badge, about the size of the text */
  aspect-ratio: 1489 / 1363;    /* the star sticker's own proportions */
  background: var(--accent);
  mask: url("../Assets/star-sticker.svg") center / contain no-repeat;
}

.mast .facts b {
  display: block;
  margin-block-end: var(--space-2xs);
  font-weight: 400;
  color: var(--accent);
}

@media (min-width: 701px) {
  .mast {
    display: grid;
    grid-template-columns: auto auto;
    grid-template-rows: auto auto;
    justify-content: center;
    column-gap: var(--logo-text-gap);
  }
  .mast video {
    grid-column: 1;
    grid-row: 1 / 3;
    inline-size: auto;
    block-size: var(--logo-size);
  }
  .mast .line,
  .mast .facts {
    grid-column: 2;
  }
  /* text lines up with the top and bottom of the drawing, not the video's white box */
  .mast .line {
    grid-row: 1;
    align-self: start;
    max-inline-size: var(--tagline-width);
    margin-block-start: calc(var(--logo-size) * var(--space-above-drawing));
  }
  .mast .facts {
    grid-row: 2;
    align-self: end;
    margin-block: 0 calc(var(--logo-size) * var(--space-below-drawing));
  }
  .mast .facts .col {
    inline-size: var(--fact-width);
  }
}

/* tagline accents: "digital" and "hand-made" */
.line .px,
.line .rough {
  display: inline-block;
  font-size: calc(var(--text-tagline) * var(--header-scale) * var(--accent-word-scale));
  font-weight: 400;
  color: var(--accent);
}

/* "digital" in a pixel font */
.line .px {
  position: relative;
  font-family: var(--pixel);
}

/* "hand-made" wobbling with the roughen filter (home.js changes the noise) */
.line .rough {
  filter: url("#roughen");
  font-family: var(--serif);
  font-style: italic;
}

/* pixel glitch on "digital": home.js draws the word on a canvas laid exactly over it */
.line .px canvas {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  pointer-events: none;
  image-rendering: pixelated;
}

.line .px.bitting .px-text {
  visibility: hidden;
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   MARQUEE – "featured projects" strip.
   HTML: index.html → .marquee
   JS: home.js repeats the text so the loop never shows a gap.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
/* sticky: each marquee sticks just under the nav, and the next one slides up over it –
   so you always know which section you're in */
.marquee {
  --dot-size: 1.125rem;
  position: sticky;
  inset-block-start: var(--nav-height);
  z-index: 9;   /* under the nav (10), over the tiles */
  display: flex;
  align-items: center;
  block-size: calc(var(--dot-size) + var(--space-xs) * 2);   /* a whole-pixel height, so no hairline of page shows under it when stuck */

  overflow: hidden;
  padding-block: var(--space-xs);
  font-size: var(--text-sm);
  background: var(--accent);
  color: var(--page);
}

.marquee .track {
  display: flex;
  inline-size: max-content;
  animation: marquee var(--marquee-time) linear infinite;
}

.marquee .run {
  display: flex;
  flex: none;
  align-items: center;
}

.marquee span {
  padding-inline: var(--space-sm);
  line-height: 1;
  white-space: nowrap;
}

/* flower divider: the svg is used as a mask, so it's painted in the text colour */
.marquee i {
  flex: none;
  inline-size: var(--dot-size);
  aspect-ratio: 1757 / 1632;    /* the flower svg's own proportions */
  background: currentColor;
  mask: url("../Assets/flower.svg") center / contain no-repeat;
}

/* "fun stuff" marquee: decorate's pink, and the star sticker shape instead of the flower */
.marquee--stars {
  background: var(--deco-bg);
}


.marquee--stars i {
  aspect-ratio: 1489 / 1363;    /* the star svg's own proportions */
  mask-image: url("../Assets/star-sticker.svg");
}

/* the track holds two identical runs, so sliding by half loops seamlessly */
@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   GRID – 12 thin columns, so tiles can be 3 or 4 across.
   Desktop: products 3 across (span 4) → tagline + coming soon (span 6) → small tiles 4 across (span 3).
   Phone: products and wide tiles full width, small tiles 2 across.
   HTML: index.html → .frame .grid
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.frame {
  container-type: inline-size;
}

.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.t {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 1 / 1;
}

.t:focus-visible {
  outline: var(--stroke) solid var(--fg);
  outline-offset: calc(var(--stroke) * -2);
}

.p,
.tag,
.ph-adfin,
.soon {
  grid-column: span 12;
}

.divider,
.ph-blank,
.o {
  grid-column: span 6;
}

.tag,
.ph-adfin,
.soon {
  aspect-ratio: 2 / 1;
}

.p-adfin {
  aspect-ratio: 2 / 1;
}

/* forage + slack: solid-colour squares, same size as the old placeholders */
.p-forage,
.p-slack {
  grid-column: span 6;
}

@media (min-width: 701px) {
  .p {
    grid-column: span 4;
  }
  .p-adfin {
    grid-column: span 6;
  }
  .p-forage,
  .p-slack {
    grid-column: span 3;
  }
  .tag,
  .ph-adfin,
  .soon {
    grid-column: span 6;
  }
  .divider,
  .ph-blank,
  .o {
    grid-column: span 3;
  }
  /* "in case you haven’t noticed" stands two squares tall */
  .divider--tall {
    grid-row: span 2;
    aspect-ratio: 1 / 2;
  }
}


/* ── Tagline tile (black) ── */
.tag {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--tile-pad-wide);
  background: var(--fg);
  color: var(--page);
}

.tag h1 {
  margin: 0;
  font-size: var(--text-tile-heading);
  font-weight: 500;
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

.tag h1 em {
  font-style: normal;
  text-decoration: underline;
  text-decoration-thickness: var(--hairline);
  text-underline-offset: var(--underline-offset);
}

.creds {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
  font-family: var(--mono);
  font-size: var(--text-xs);
  color: var(--faint);
}


/* ── Adfin placeholder tile (temporary – sits where the tagline tile was) ── */
.ph-adfin {
  display: grid;
  place-items: center;
  background: var(--live-green);
  color: var(--page);
  font-size: var(--text-tile-heading);
  font-weight: 500;
}

/* ── blank placeholder squares (temporary – next to Adfin) ── */
.ph-blank {
  display: grid;
  place-items: center;
  background: var(--page);
  border: var(--hairline) dashed var(--faint);
  font-size: var(--text-tile-heading);   /* same as the Adfin placeholder */
  font-weight: 500;
  text-align: center;
}

/* the tall box's paragraph sits in the middle (other text boxes sit at the bottom) */
.divider.divider--tall {   /* both classes, so it beats the main .divider rule further down */
  justify-content: center;
  border-block-start: 0;   /* no top line – the playground has space around it now */
}

/* the tall box keeps the paragraph's PP Mondwest font from its old box */
.divider--tall p {
  font-family: var(--pixel);
}

/* ── Coming-soon tile ── */
.soon {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--tile-pad-wide);
  background: var(--page);
  border: var(--hairline) dashed var(--faint);
}

.soon b {
  font-size: var(--text-tile-small);
  font-weight: 500;
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-tight);
}

.soon p {
  font-family: var(--pixel);   /* PP Mondwest – same pixel font as "digital" */
  font-size: calc(var(--text-tagline) * var(--header-scale));   /* same size as the headline in the header */
  line-height: var(--leading-snug);
}

.soon span {
  font-family: var(--mono);
  font-size: var(--text-xs);
  color: var(--soft);
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   PRODUCT TILES – float, soundtrack, decorate.
   Each sets its own --bg and --ink colours.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.p       { color: var(--ink); }

/* the tile's colour sits on its own layer, so it can go black & white on hover without the title */
.p::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--bg);
}
.p-float { --bg: var(--float-bg); --ink: var(--float-ink); --frame-line: #E6CFB1; --title-ink: #816447; --title-hover: var(--brand-blue); }  /* darker tan – lightest that passes 4.5:1 contrast on the beige */
.p-sound { --bg: var(--sound-bg); --ink: var(--sound-ink); --frame-line: #2A2A2A; --title-ink: #7D7D7D; --title-hover: var(--brand-yellow); }  /* lighter grey – passes 4.5:1 contrast on the black */
.p-adfin { --bg: var(--adfin-bg); --ink: var(--page); --frame-line: color-mix(in srgb, var(--adfin-bg) 70%, var(--page)); --title-ink: var(--adfin-caption); --title-hover: var(--live-green); }  /* title = Adfin's subtle caption green, bright green on hover */
.p-forage { --bg: var(--forage-bg); --ink: var(--fg); --frame-line: color-mix(in srgb, var(--forage-bg) 60%, var(--page)); --title-ink: color-mix(in srgb, var(--forage-bg) var(--title-shade), var(--fg)); --title-hover: var(--forage-lime-light); }  /* outline = a lighter tint of the tile, same as decorate's on its pink; darker lilac titles, light lime on hover */
.p-slack  { --bg: var(--slack-bg);  --ink: var(--page);       --frame-line: color-mix(in srgb, var(--slack-bg) 70%, var(--page)); --title-ink: color-mix(in srgb, var(--slack-bg) var(--title-shade), var(--page)); --title-hover: var(--slack-green); }  /* subtle purple titles (the tile is already dark, so they mix toward white), Slack green on hover – the greenmode accent */
.p-deco  { --bg: var(--deco-bg);  --ink: var(--deco-ink);  --frame-line: #FFB8D4; --title-ink: #750033; --title-hover: var(--brand-yellow); }  /* decorate's caption pink (#B8306B) at full saturation – 4.15:1 contrast, just under the 4.5:1 rule */

/* "product 01 ... 2026" along the top */
.kicker {
  position: absolute;
  inset-block-start: var(--tile-pad);
  inset-inline: var(--tile-pad);
  z-index: var(--layer-label);
  display: flex;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: var(--text-xs);
  line-height: 1;
}

/* project name (bottom left) + type (bottom right) – nav font, each case study's sub-subheading colour */
.tile-title {
  position: absolute;
  inset-block-end: var(--tile-pad);
  inset-inline: var(--tile-pad);
  z-index: var(--layer-label);
  display: flex;
  justify-content: space-between;
  font-family: var(--sans);
  font-size: var(--text-sm);
  line-height: 1;
  color: var(--title-ink);
}

/* hover: the whole tile goes black & white (colour + video + frame), only the title turns that case study's accent colour */
.p::before,
.p .cover {
  transition: filter var(--hover-time) var(--ease-out);
}

.p:hover::before,
.p:hover .cover,
.p:focus-visible::before,
.p:focus-visible .cover {
  filter: grayscale(1);
}

/* hover: each label rolls up and a copy in the case study's accent colour rolls in from below */
.roll {
  --roll-time: 450ms;
  display: inline-flex;
  overflow: hidden;
  line-height: 1.2;
}

.roll > span {
  position: relative;
  display: block;
  transition: translate var(--roll-time) var(--ease-out);
}

.roll > span::after {
  content: attr(data-text) / "";   /* the empty alt text stops screen readers reading it twice */
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 100%;
  color: var(--title-hover);   /* each case study's own accent */
}

.p:hover .roll > span,
.p:focus-visible .roll > span {
  translate: 0 -100%;
}

/* the right-hand label follows a beat later */
.roll + .roll > span {
  transition-delay: 60ms;
}

/* "AIGA showcase 2026" star sticker – pops on over the float screen's top-right corner on hover.
   The shape is Assets/star-sticker.svg used as a mask, so it takes any colour. */
.sticker {
  --sticker-size: 10rem;   /* was 8rem – grown to fit the wider AIGA NY logo */
  --sticker-tilt: 12deg;
  position: absolute;
  inset-block-start: var(--space-xl);
  inset-inline-end: var(--space-xl);
  z-index: var(--layer-label);
  display: grid;
  place-content: center;
  inline-size: var(--sticker-size);
  aspect-ratio: 1489 / 1363;    /* the star svg's own proportions */
  --sticker-nudge: 0.03;   /* share of the sticker's size the logo + text sit lower – the star's points make its visual centre a little below the box's middle */
  padding-inline: var(--space-md);
  padding-block-start: calc(var(--sticker-size) * var(--sticker-nudge) * 2);   /* centred content moves down by half the top padding */
  color: var(--page);
  font-size: var(--text-facts);   /* same size as "currently" / "previously" */
  line-height: 1.1;
  text-align: center;
  filter: url("#roughen-sticker");   /* softer copy of the "hand-made" wobble (index.html) – on the whole sticker, since the star mask would cancel it on the shape alone */
  scale: 0;
  rotate: calc(var(--sticker-tilt) * -2);
  transition: scale var(--roll-time, 450ms) var(--ease-out),
              rotate var(--roll-time, 450ms) var(--ease-out);
}

/* the AIGA NY logo (Assets/aiga-ny-logo.png – a cropped copy of the share card, black letters on light grey):
   flipped to white letters on near-black, then the dark background blended away so only the letters show on the star.
   old AIGA logo: --logo-crop: 1280 / 340; --logo-share: 0.55; and no invert */
.sticker-logo {
  --logo-crop: 860 / 162;    /* the cropped image's own shape */
  --logo-share: 0.56;        /* how much of the sticker's width the logo takes – keeps the logo the size it was before the star grew */
  display: block;
  inline-size: calc(var(--sticker-size) * var(--logo-share));
  aspect-ratio: var(--logo-crop);
  margin-inline: auto;
  object-fit: cover;
  filter: invert(1);
  mix-blend-mode: screen;
}

.sticker::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--fg);
  mask: url("../Assets/star-sticker.svg") center / contain no-repeat;
}

.p:hover .sticker,
.p:focus-visible .sticker {
  scale: 1;
  rotate: var(--sticker-tilt);
}

/* tiny green "live" dot before "shipped" */
.is-shipped {
  --dot: 0.375rem;
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

.is-shipped::before {
  content: "";
  inline-size: var(--dot);
  block-size: var(--dot);
  border-radius: var(--radius-pill);
  background: var(--live-green);
}

/* name + description along the bottom */
.label {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: var(--layer-label);
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-sm);
  padding: var(--tile-pad);
}

.label h2 {
  margin: 0;
  font-size: var(--text-tile-title);
  font-weight: 500;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tighter);
}

.label p {
  max-inline-size: 14rem;
  font-size: var(--text-xs);
  text-align: end;
}

.label .go {
  display: inline-block;
  margin-block-start: var(--space-xs);
  border-block-end: var(--hairline) solid currentColor;
}

/* real cover video, filling the whole tile behind the labels */
.cover {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* soundtrack: phone screen centred in the tile, styled like the screens in the case study (spotify.css .cs-screen-video) */
.p-sound .cover {
  --cover-pad: var(--space-2xl);
  inset: var(--cover-pad);
  inline-size: auto;
  block-size: calc(100% - var(--cover-pad) * 2);
  margin: auto;
  border-radius: var(--radius-md);
  outline: var(--hairline) solid var(--frame-line);
}

/* float: the "dump" video from the solution section in a 16:10 screen – same shape and size as decorate's,
   so the 16:9 video zooms in slightly and loses a sliver at the sides */
.p-float .cover {
  --cover-pad: var(--space-2xl);
  inset: 0;
  inline-size: calc(100% - var(--cover-pad) * 2);
  block-size: auto;
  aspect-ratio: 16 / 10;
  margin: auto;
  border-radius: var(--radius-md);
  outline: var(--hairline) solid var(--frame-line);
}

/* slack greenbot: the "green mode" phone demo, as tall as the tile allows, centred, framed like the others */
.p-slack .cover {
  /* --cover-pad: calc(var(--space-2xl) * 3 / 4);   tried: gap shrunk to the tile's size – phone felt too big */
  --cover-pad: var(--space-2xl);   /* same gap as every other cover */
  inset: var(--cover-pad) auto;   /* top + bottom gap; sides left free so the width comes from the phone shape */
  inset-inline-start: 50%;
  translate: -50% 0;               /* centred side to side */
  inline-size: auto;
  block-size: calc(100% - var(--cover-pad) * 2);
  aspect-ratio: 540 / 1160;   /* the video's own phone shape */
  border-radius: calc(var(--radius-md) * 1.5);   /* rounder than the laptop screens, so the phone's own black corners are hidden */
  outline: var(--hairline) solid var(--frame-line);
}

/* the video has a thin black phone edge baked in – zoom it slightly so the edge sits outside the frame */
.p-slack .cover {
  overflow: hidden;
}

.p-slack .cover video {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  scale: 1.04;
}

/* adfin: the launch video in a 16:9 screen, as tall as the tile allows, centred, framed like the others */
.p-adfin .cover {
  --cover-pad: var(--space-2xl);
  inset: 0;
  inline-size: auto;
  block-size: calc(100% - var(--cover-pad) * 2);
  aspect-ratio: 16 / 9;
  margin: auto;
  border-radius: var(--radius-md);
  outline: var(--hairline) solid var(--frame-line);
}

/* decorate: the "spill your deets" video in a laptop-shaped screen (16:10), centred, with a light pink outline */
.p-deco .cover {
  --cover-pad: var(--space-2xl);
  inset: 0;
  inline-size: calc(100% - var(--cover-pad) * 2);
  block-size: auto;
  aspect-ratio: 16 / 10;
  margin: auto;
  border-radius: var(--radius-md);
  outline: var(--hairline) solid var(--frame-line);
  overflow: hidden;
}

/* forage: the final video in a 16:10 screen (its own shape), framed like the others */
.p-forage .cover {
  --cover-pad: var(--space-2xl);
  inset: 0;
  inline-size: calc(100% - var(--cover-pad) * 2);
  block-size: auto;
  aspect-ratio: 16 / 10;
  margin: auto;
  border-radius: var(--radius-md);
  outline: var(--hairline) solid var(--frame-line);
  padding: var(--space-sm);     /* a solid band of the tile colour around the video */
  background: var(--bg);
}

/* the video's own inner frame, zoomed in slightly to crop its edges */
.forage-screen {
  block-size: 100%;
  overflow: hidden;
  border-radius: calc(var(--radius-md) - var(--space-sm) / 2);
}

.forage-screen video {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  scale: 1.15;
}

/* zoomed in on the screen recording exactly like the case study (decorate.css → .dc-proto-video) */
.p-deco .cover video {
  display: block;
  inline-size: 130%;
  translate: -19.2% -17.5%;
}

/* the sketched piece of interface, centred in each tile */
.frag {
  position: absolute;
  inset: 0;
  inline-size: min(calc(100% * 2 / 3), 22rem);
  block-size: fit-content;
  margin: auto;
  font-size: var(--text-sketch);
  transition: transform var(--hover-time) var(--ease-out);
}

.p:hover .frag,
.p:focus-visible .frag {
  transform: scale(var(--hover-grow));
}


/* ── float sketch: the scattered task "dump" ── */
.dump {
  position: relative;
  aspect-ratio: 4 / 3;
}

.chip {
  position: absolute;
  inset-inline-start: var(--x);
  inset-block-start: var(--y);
  rotate: var(--tilt);
  padding-block: var(--space-2xs);
  padding-inline: var(--space-sm);
  background: var(--page);
  border: var(--stroke) solid var(--float-ink);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  animation: bob var(--bob-time) ease-in-out infinite;
  animation-delay: calc(var(--bob-time) / -5 * var(--i)); /* each chip bobs a fifth of a beat later */
}

.chip.go-chip {
  background: var(--float-ink);
  color: var(--page);
}

/* where each chip sits (--x, --y), its tilt, and its place in the bob order (--i) */
.chip-email   { --x: 2%;  --y: 6%;  --tilt: -6deg; --i: 0; }
.chip-laundry { --x: 48%; --y: 0%;  --tilt: 5deg;  --i: 1; }
.chip-deck    { --x: 14%; --y: 40%; --tilt: 3deg;  --i: 2; }
.chip-mom     { --x: 56%; --y: 46%; --tilt: -4deg; --i: 3; }
.chip-start   { --x: 28%; --y: 76%; --tilt: -2deg; --i: 4; }

@keyframes bob {
  50% {
    translate: 0 calc(var(--space-xs) * -1);
  }
}


/* ── soundtrack sketch: replaying the day ── */
.player {
  --player-bg: #1F1F1F;
  --player-text: #EDEDED;
  --player-muted: #9A9A9A;
  --player-track: #3A3A3A;

  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-sm);
  background: var(--player-bg);
  color: var(--player-text);
  border-radius: var(--radius-md);
}

.player .h {
  display: flex;
  justify-content: space-between;
  color: var(--sound-ink);
}

.player ol {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.player li {
  display: flex;
  gap: var(--space-sm);
}

.player li span {
  flex: none;
  inline-size: 4.5rem;
  font-family: var(--mono);
  color: var(--player-muted);
}

.player li.now {
  color: var(--sound-ink);
}

.bar {
  position: relative;
  block-size: var(--space-2xs);
  background: var(--player-track);
  border-radius: var(--radius-pill);
}

.bar i {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 40%;
  background: var(--sound-ink);
  border-radius: var(--radius-pill);
  animation: scrub var(--scrub-time) ease-in-out infinite alternate;
}

@keyframes scrub {
  to {
    inline-size: 70%;
  }
}


/* ── decorate sketch: booking a piercing ── */
.book {
  --book-text: #3A1626;
  --book-muted: #8C6274;
  --book-line: #F3C6D9;

  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-sm);
  background: var(--page);
  color: var(--book-text);
  border-radius: var(--radius-md);
}

.book .h {
  font-size: var(--text-sketch-heading);
  font-weight: 600;
}

.book .sub {
  color: var(--book-muted);
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

.row span {
  padding-block: var(--space-2xs);
  padding-inline: var(--space-xs);
  border: var(--hairline) solid var(--book-line);
  border-radius: var(--radius-sm);
}

.row span.on {
  background: var(--deco-bg);
  border-color: var(--deco-bg);
  color: var(--page);
}

.book button {
  all: unset;
  padding: var(--space-xs);
  background: var(--deco-bg);
  color: var(--deco-ink);
  border-radius: var(--radius-sm);
  font-weight: 600;
  text-align: center;
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   EVERYTHING ELSE – small square tiles.
   Each sets its own --obg (background) and --oink (text).
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.divider {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--tile-pad-wide);
  background: var(--page);
  border-block-start: var(--hairline) solid var(--rule);
}

.divider b,
.o b {
  font-size: var(--text-tile-small);
  font-weight: 500;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
}

/* same size + styling as the headline in the header */
.divider p {
  font-size: calc(var(--text-tagline) * var(--header-scale));
  line-height: var(--leading-snug);
}

/* "move" – styled like "hand-made" (blue italic serif), without the wobble filter */
.divider .move {
  font-family: var(--serif);
  font-style: italic;
  font-size: calc(100% * var(--accent-word-scale));   /* % of the surrounding text size (no em) */
  color: var(--accent);
}

.divider span {
  margin-block-start: var(--space-xs);
  font-family: var(--mono);
  font-size: var(--text-xs);
  color: var(--soft);
}

.o {
  display: flex;
  align-items: flex-end;
  padding: var(--tile-pad-wide);
  background: var(--obg, var(--tile));
  color: var(--oink, var(--fg));
}

.o small {
  display: block;
  margin-block-start: var(--space-xs);
  font-family: var(--mono);
  font-size: var(--text-xs);
  line-height: 1;
  opacity: var(--dim);
}

/* playground covers fill their tile (squares, cropped to fit); no name text on top */
.o {
  padding: 0;
}

/* portrait phone-shaped covers get a tall tile, two squares high */
@media (min-width: 701px) {
  .o-tall {
    grid-row: span 2;
    aspect-ratio: 1 / 2;
  }
}

/* let tiles slot into any gaps the tall ones leave */
.grid {
  grid-auto-flow: dense;
}

.o-vcr          { --obg: #2B2B2B; --oink: #F4F4F4; }
.o-hc-index     { --obg: #3D3BF0; --oink: var(--page); }
.o-wdttg        { --obg: var(--tile); }
.o-gen1         { --obg: #F5D7E3; }
.o-pukaare      { --obg: #1C3B2E; --oink: #E8F1EA; }
.o-td-scrapbook { --obg: #FFF2B8; }
.o-links        { --obg: var(--tile); }
.o-gen2         { --obg: #E7F0D8; }
.o-manuscript   { --obg: #EDE6D6; }
.o-scribble     { --obg: #FFE3EF; }
.o-fellowship   { --obg: #D9E4FF; }
.o-ada          { --obg: #F0E0FF; }
.o-kzkoffee     { --obg: #E8D9C5; }
.o-figbuild     { --obg: var(--tile); }


/* ── Reduced motion: stop all looping animation ── */
@media (prefers-reduced-motion: reduce) {
  .roll > span,
  .sticker {
    transition: none;
  }
  .chip,
  .bar i,
  .marquee .track {
    animation: none;
  }
  .frag {
    transition: none;
  }
}



/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   FOOTER – white band, two halves (layout inspired by kevinzych.com).
   Left: big name, tagline, "say hi" button, copyright. Right: bio + links.
   HTML: index.html → footer.site-footer
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.site-footer {
  --footer-bg: var(--page);   /* white */
  --footer-pad: var(--space-xl);
  --footer-height: 40rem;   /* tall, roomy band to doodle in */

  display: grid;
  gap: var(--space-2xl);
  min-block-size: var(--footer-height);
  align-content: end;   /* text sits at the bottom, leaving open space above to draw in */
  padding: var(--footer-pad) var(--space-lg);
  background: var(--footer-bg);
  color: var(--fg);
  position: relative;
  overflow: hidden;
}

/* doodle layer: moving the mouse over the footer draws an ink line behind the text (home.js → "Footer doodle") */
.footer-canvas {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  pointer-events: none;   /* clicks go straight through to the links */
  filter: url("#roughen");   /* wobbles like "hand-made" (filter in index.html, home.js keeps it moving) */
}

/* "clear": the same flower button as the playground's arrow – a black flower on the white footer, a white × inside,
   one quick spin on hover while the × drops out and a new one slides in. */
.footer-clear {
  --clear-size: calc(var(--space-xl) * 1.75);   /* the flower's width (3.5rem), same as the skip button */
  position: absolute;
  inset-block-start: var(--space-lg);
  inset-inline-end: var(--space-lg);
  z-index: 2;
  display: grid;
  place-items: center;
  inline-size: var(--clear-size);
  aspect-ratio: 1757 / 1632;   /* the flower's own proportions */
  padding: 0;
  background: none;
  border: 0;
  color: var(--footer-bg);   /* the ×: white on the black flower */
}

.footer-clear-flower {
  grid-area: 1 / 1;
  inline-size: 100%;
  block-size: 100%;
  background: var(--fg);
  mask: url("../Assets/flower.svg") center / contain no-repeat;
}

.footer-clear:hover .footer-clear-flower,
.footer-clear:focus-visible .footer-clear-flower {
  animation: skip-spin 600ms var(--ease-out) 1;   /* the same quick turn as the skip button */
}

.footer-clear-icons {
  position: relative;
  z-index: 1;   /* above the masked flower */
  grid-area: 1 / 1;
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: 100%;
  overflow: hidden;
}

.footer-clear-icon {
  grid-area: 1 / 1;
  inline-size: calc(var(--clear-size) / 2.5);
  block-size: calc(var(--clear-size) / 2.5);
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: translate var(--hover-time) var(--ease-out);
}

.footer-clear-icon path {
  vector-effect: non-scaling-stroke;
  stroke-width: var(--skip-stroke);   /* same weight as the skip arrow */
}

.footer-clear-icon--next { translate: 0 -200%; }

.footer-clear:hover .footer-clear-icon,
.footer-clear:focus-visible .footer-clear-icon { translate: 0 200%; }

.footer-clear:hover .footer-clear-icon--next,
.footer-clear:focus-visible .footer-clear-icon--next { translate: 0 0; }

@media (prefers-reduced-motion: reduce) {
  .footer-clear-icon { transition: none; }
  .footer-clear:hover .footer-clear-flower,
  .footer-clear:focus-visible .footer-clear-flower { animation: none; }
}


.footer-side {
  position: relative;
  z-index: 1;   /* text sits above the doodle */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-md);
}

.footer-name {
  --footer-mark-width: calc(var(--text-4xl) * 4);   /* the hand-drawn "kinza" signature (same image as the about page) */
  --mark-inset: 0.013;   /* the drawing starts 1.3% into the image (22 of 1695px) – pulled back so the ink lines up with the nav name */
  display: block;
  inline-size: var(--footer-mark-width);
  margin-inline-start: calc(var(--footer-mark-width) * var(--mark-inset) * -1);
  max-inline-size: 100%;
  block-size: auto;
}

.footer-tagline,
.footer-bio,
.footer-links {
  font-size: var(--text-sm);
  line-height: var(--leading-body);
}

.footer-btn {
  font-family: var(--button-font);
  background: var(--fg);
  color: var(--page);
  border-radius: var(--radius-pill);   /* "say hi" is a pill (the other buttons stay square / flower) */
  padding-block: var(--button-pad-block);
  padding-inline: var(--button-pad-inline);
  font-size: var(--button-text);
  line-height: var(--button-leading);
}

.footer-small {
  margin-block-start: auto;   /* sits at the bottom of the left half */
  font-size: var(--text-sm);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-lg);
  margin-block-start: auto;   /* sits at the bottom of the right half */
}

/* ── OLD SITE TRASH CAN – top-left of the footer (opposite the clear button), links to index-v1.html.
   Hover: the lid flips open, a paper ball pops out, and a speech bubble appears ── */
.trash {
  --trash-size: 3rem;
  --trash-pop: calc(var(--trash-size) / 3);   /* how high the lid + paper jump */
  position: absolute;
  inset-block-start: var(--space-lg);
  inset-inline-start: var(--space-lg);
  z-index: 2;   /* above the doodle */
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  color: var(--fg);
}

.trash-can {
  inline-size: var(--trash-size);
  block-size: auto;
  overflow: visible;   /* the paper + lid can jump outside the drawing */
  fill: var(--page);
  stroke: currentColor;
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  filter: url("#roughen");   /* hand-drawn wobble, like the doodle */
}

.trash-lid,
.trash-paper {
  transform-box: fill-box;
  transition: translate var(--hover-time) var(--ease-out), rotate var(--hover-time) var(--ease-out);
}

.trash-lid {
  transform-origin: right bottom;   /* hinges on its right corner */
}

.trash-paper {
  fill: var(--brand-yellow);   /* a crumpled yellow page, hidden inside the can until hover */
}

.trash:hover .trash-lid,
.trash:focus-visible .trash-lid {
  translate: 0 calc(var(--trash-pop) * -1);
  rotate: 35deg;
}

.trash:hover .trash-paper,
.trash:focus-visible .trash-paper {
  translate: calc(var(--trash-pop) * -1) calc(var(--trash-pop) * -2);
}

/* speech bubble – black like the footer buttons, pops in from the can */
.trash-bubble {
  position: relative;
  background: var(--fg);
  color: var(--page);
  padding-block: var(--button-pad-block);
  padding-inline: var(--button-pad-inline);
  font-size: var(--button-text);
  line-height: var(--button-leading);
  white-space: nowrap;
  transform-origin: left center;
  scale: 0;
  transition: scale var(--hover-time) var(--ease-out);
}

.trash-bubble em {
  font-family: var(--serif);   /* "hand-made" voice */
}

.trash:hover .trash-bubble,
.trash:focus-visible .trash-bubble {
  scale: 1;
}

/* desktop: two equal halves, name a lot bigger */
@media (min-width: 701px) {
  .site-footer {
    grid-template-columns: 1fr 1fr;
  }
  .footer-bio {
    max-inline-size: 36rem;
  }
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   PLAYGROUND – masonry like the old homepage.
   The text box keeps its quarter-width, two-squares-tall spot on the left;
   4 columns of covers fill the rest, each cover at its own natural shape.
   Each card is placed in a column by hand in index.html (old grid rules: no same project touching).
   Hover: the cover is covered in white with the name + year in big type, like the old homepage.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.playground {
  --pg-hover-size: 3rem;   /* name size on hover */
  --pg-gap: var(--space-xl);   /* space between columns and between covers */
  container-type: inline-size;
  display: flex;
  align-items: flex-start;
  gap: var(--pg-gap);
  padding-block: var(--space-3xl);
  padding-inline: var(--space-lg);
}

.pg-text-col {
  flex: 0 0 25%;
}

.pg-col {
  flex: 1;
  min-inline-size: 0;
  display: flex;
  flex-direction: column;
  gap: var(--pg-gap);
}

/* each column starts at a different height, so the covers feel scattered rather than lined up */
.pg-col:nth-child(1) { margin-block-start: var(--space-3xl); }
.pg-col:nth-child(2) { margin-block-start: var(--space-lg); }
.pg-col:nth-child(3) { margin-block-start: var(--space-4xl); }
.pg-col:nth-child(4) { margin-block-start: var(--space-xl); }

.pg-card {
  position: relative;
  display: block;
  overflow: hidden;
  break-inside: avoid;
}

.pg-card video,
.pg-card img {
  display: block;
  inline-size: 100%;
  block-size: auto;
}

.pg-hover {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: space-between;
  gap: var(--space-xs);
  padding: var(--space-xs);
  background: var(--page);
  color: var(--fg);
  opacity: 0;
  pointer-events: none;
}

.pg-card:hover .pg-hover,
.pg-card:focus-visible .pg-hover {
  opacity: 1;
}

/* hover overlay switched off for now – delete this rule to bring it back */
.pg-hover {
  display: none;
}

.pg-name span {
  display: block;
  font-size: var(--pg-hover-size);
  font-weight: 500;
  line-height: 0.85;
  letter-spacing: var(--tracking-tighter);
  white-space: nowrap;
}

.pg-year {
  font-size: var(--text-sm);
  white-space: nowrap;
}

/* index: zoomed in like the old homepage (style-v1.css → .card--zoom-xl) */
.pg-zoom-xl video {
  object-fit: cover;
  transform: scale(1.8) translateY(2%);
  transform-origin: center;
}

/* coming-soon projects: greyed out on hover */
.pg-hover--soon {
  color: var(--faint);
}

/* phones: 2 columns; the text box goes full width on top */
@media (max-width: 700px) {
  .playground {
    --pg-gap: var(--space-md);
    display: block;
    columns: 2;
    column-gap: var(--pg-gap);
  }
  .pg-card {
    margin-block-end: var(--pg-gap);
  }
  .pg-col {
    display: contents;
  }
  .pg-text-col {
    column-span: all;
  }
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   INTRO TEXT – the "As an illustrator…" paragraph after the product section.
   Styled like the header: white space around it, headline-size text.
   HTML: index.html → section.intro-text
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.intro-text {
  --reel-width: 18rem;          /* same width as one masonry column */
  --reel-height: 40rem;         /* how much of the reel shows at once */
  --reel-gap: var(--space-xl);
  --reel-time: 60s;             /* one full loop – higher = slower */

  --text-reel-gap: calc(var(--space-4xl) * 1.5);   /* space between the paragraph and the reel */

  display: grid;
  grid-template-columns: minmax(0, 44rem) var(--reel-width);
  justify-content: center;   /* text + reel sit together as one group in the middle */
  align-items: center;
  gap: var(--text-reel-gap);
  padding-block: var(--space-4xl);
  padding-inline: var(--space-lg);
  background: var(--page);
}

.intro-text p {
  max-inline-size: 44rem;
  font-size: calc(var(--text-tagline) * var(--header-scale));   /* same as the header headline */
  line-height: var(--leading-snug);
}

/* the window the covers scroll through – clean hard edges top and bottom */
.reel {
  block-size: var(--reel-height);
  overflow: hidden;
}

/* two identical runs stacked; sliding up by half loops seamlessly */
.reel-track {
  animation: reel-up var(--reel-time) linear infinite;
}

.reel:hover .reel-track {
  animation-play-state: paused;   /* stops so people can click a project */
}

.reel-run {
  display: flex;
  flex-direction: column;
  gap: var(--reel-gap);
  padding-block-end: var(--reel-gap);   /* same gap between the end of one run and the start of the next */
}

.reel-card {
  display: block;
  overflow: hidden;   /* keeps the zoomed index cover inside its box */
}

.reel-card video,
.reel-card img {
  display: block;
  inline-size: 100%;
  block-size: auto;
}

@keyframes reel-up {
  to {
    transform: translateY(-50%);
  }
}

/* phones: text on top, reel underneath */
@media (max-width: 700px) {
  .intro-text {
    --reel-height: 28rem;
    grid-template-columns: 1fr;
    justify-items: center;
  }
  .reel {
    inline-size: var(--reel-width);
  }
}

@media (prefers-reduced-motion: reduce) {
  .reel-track {
    animation: none;
  }
  .reel {
    overflow-y: auto;
  }
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   ABOUT STRIP – the "As an illustrator…" paragraph in its own section:
   left half, vertically centred; the right half is left open for a visual.
   HTML: index.html → section.about-strip
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.about-strip {
  --about-height: 36rem;

  display: grid;
  gap: var(--space-2xl);
  padding-block: var(--space-4xl);
  padding-inline: var(--space-lg);
  background: var(--brand-blue);
  color: var(--page);
}

.about-text {
  display: grid;
  align-content: center;
}

.about-text p {
  max-inline-size: var(--about-text-width);
  font-family: var(--sans);   /* same styling as the header headline */
  font-size: calc(var(--text-tagline) * var(--header-scale));
  line-height: var(--leading-snug);
}

/* empty for now – the visual goes here */
.about-visual {
  min-block-size: var(--about-height);
}

@media (min-width: 701px) {
  .about-strip {
    grid-template-columns: 1fr 1fr;
  }
  .about-text {
    justify-items: center;   /* centred within the left half */
  }
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   CATEGORY BARS – all bars start closed at the right edge. Scrolling down, the page is held when the
   section's top reaches the nav; each new gesture opens the next bar (sliding left), and one more after the
   last lets the page continue. Scrolling up never holds. Clicking a bar opens it any time. "skip ↓" jumps past.
   js: home.js → "Category bars". .cat-work is where the media goes later.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.about-scroll {
  --bar-label-size: var(--text-xl);   /* the category names on the bars */
  --bar-width: calc(var(--bar-label-size) + var(--space-sm) * 2);   /* label + its padding on each side */
  --bar-time: 600ms;
  --bar-ease: cubic-bezier(0.7, 0, 0.2, 1);
  --bar-fade-time: 300ms;      /* the open bar's content fading in */
  --bar-fade-delay: 350ms;     /* waits until the bar has mostly opened */
  --about-text-width: 26rem;   /* the paragraph's column on desktop */
  --skip-size: calc(var(--space-xl) * 1.75);   /* the skip circle's diameter (3.5rem; was 2.5rem) */
  --card-stagger: 80ms;        /* covers come in one after another once a bar opens */

  background: var(--brand-blue);   /* blue all the way down, so no gaps show while it's pinned */
}

/* bars sit together at the right edge until one opens; the empty space beside them is pink */
.cats {
  background: var(--brand-pink);
  display: flex;
  justify-content: flex-end;
  align-self: stretch;
  min-inline-size: 0;
}

.cat {
  display: flex;
  flex: 0 0 var(--bar-width);
  overflow: hidden;
  background: var(--bar-bg);
  color: var(--bar-ink);
  transition: flex-grow var(--bar-time) var(--bar-ease),
              flex-basis var(--bar-time) var(--bar-ease);
}

/* the open bar takes all the room the closed bars don't */
.cat.is-open {
  flex: 1 1 0;
}

/* closed bars can be clicked to open */
.cat:not(.is-open) {
  cursor: pointer;
}

/* while the page is held at the section (home.js adds this to <html>) – stops trackpad momentum */
.is-holding-scroll {
  overflow: hidden;
}

.cat--1 { --bar-bg: var(--brand-yellow); --bar-ink: var(--fg); }   /* hand-coded */
.cat--2 { --bar-bg: var(--brand-pink); --bar-ink: var(--fg); }     /* illustration */
.cat--3 { --bar-bg: var(--brand-yellow);        --bar-ink: var(--fg); }       /* vibe-coded */
.cat--4 { --bar-bg: var(--live-green); --bar-ink: var(--fg); }    /* side quests – softer Adfin green */

/* category name running up the bar */
.cat-bar {
  flex: 0 0 auto;
  padding-block: var(--space-sm);
  padding-inline: var(--space-sm);
  writing-mode: vertical-rl;
  font-size: var(--bar-label-size);
  line-height: 1;
}

/* where the media goes later – fades in once the bar has opened */
.cat-work {
  flex: 1;
  min-inline-size: 0;
  opacity: 0;
  transition: opacity var(--bar-fade-time);
}

.cat.is-open .cat-work {
  opacity: 1;
  transition-delay: var(--bar-fade-delay);
}

/* ── MODE 1: PIXELS (class cats--pixels on .cats) ──
   the covers in an open bar: solid pixel blocks sitting on a pixel grid.
   Hover one and it morphs into the cover like the cursor does – the pixel shrinks into its centre while
   the cover grows out of it (same timing + ease as the cursor, css/cursor.css). Nothing tilts.
   Sizes and spots are fixed, so nothing can stretch the section. */
.cats--pixels .cat-grid {
  --square-size: 5rem;                              /* one pixel */
  --square-grown: calc(var(--square-size) * 4);     /* the cover's box on hover */

  position: relative;
  block-size: 100%;
}

.cats--pixels .cat-card {
  position: absolute;
  inset-inline-start: calc((var(--col) + 0.5) * var(--square-size));   /* centre of its grid cell */
  inset-block-start: calc((var(--row) + 0.5) * var(--square-size));
  z-index: 1;
  display: grid;
  inline-size: var(--square-grown);
  block-size: var(--square-grown);
  translate: -50% -50%;   /* grows from the centre of its pixel */
  pointer-events: none;   /* only the pixel itself is hoverable (see ::before) */
}

/* pixels are just there when a bar opens – no fade */
.cats--pixels .cat-work {
  opacity: 1;
  transition: none;
}

/* the pixel: a solid block, the size of one grid cell */
.cats--pixels .cat-card::before {
  content: "";
  grid-area: 1 / 1;
  place-self: center;
  inline-size: var(--square-size);
  block-size: var(--square-size);
  background: var(--pixel-color);
  filter: url("#roughen");   /* wobbling edges, same as "hand-made" (filter in index.html, home.js keeps it moving) */
  pointer-events: auto;
  transition: scale var(--cursor-morph-time) var(--cursor-ease);
}

/* the cover + its caption, as one unit: hidden at the centre until hover, then grows out together,
   so the caption always sits right under the actual picture */
.cats--pixels .cat-reveal {
  grid-area: 1 / 1;
  place-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-inline-size: 100%;
  max-block-size: 100%;
  scale: 0;
  transition: scale var(--cursor-morph-time) var(--cursor-ease);
}

/* the cover at its real shape, no bigger than the grown box either way */
.cats--pixels .cat-card video,
.cats--pixels .cat-card img {
  display: block;
  inline-size: auto;
  block-size: auto;
  max-inline-size: var(--square-grown);
  max-block-size: var(--square-grown);
}

/* zoomed-in cover (index): enlarged, with the edges trimmed by the same amount, so the frame keeps its size */
.cat-card--zoom video,
.cat-card--zoom img {
  --cover-zoom: 1.3;
  scale: var(--cover-zoom);
  clip-path: inset(calc((1 - 1 / var(--cover-zoom)) * 50%));
}

.cats--pixels .cat-card:hover,
.cats--pixels .cat-card:focus-visible {
  z-index: 3;   /* grows over its neighbours */
  pointer-events: auto;
}

.cats--pixels .cat-card:hover::before,
.cats--pixels .cat-card:focus-visible::before {
  scale: 0;
}

.cats--pixels .cat-card:hover .cat-reveal,
.cats--pixels .cat-card:focus-visible .cat-reveal {
  scale: 1;
}

/* name · year right under the cover, on the bar's own colour so it stays readable over anything behind it;
   fades in once the cover has grown (like the cursor's words) */
.cats--pixels .cat-caption {
  align-self: flex-start;
  padding-block: var(--space-2xs);
  padding-inline: var(--space-xs);
  background: var(--bar-bg);
  color: var(--bar-ink);
  font-size: var(--text-sm);
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--cursor-text-time);
}

.cats--pixels .cat-card:hover .cat-caption,
.cats--pixels .cat-card:focus-visible .cat-caption {
  opacity: 1;
  transition-delay: var(--cursor-text-delay);
}

/* each bar's pixels are the same colour as its label text */
.cat {
  --pixel-color: var(--bar-ink);
}

/* where each pixel sits on the grid (--col, --row count whole pixels from the top-left).
   Kept within columns 2–7 and rows 2–4, so a grown cover always fits inside the bar. */
.cats--pixels .cat-grid--4 .cat-card:nth-child(1) { --col: 2; --row: 2; }
.cats--pixels .cat-grid--4 .cat-card:nth-child(2) { --col: 6; --row: 2; }
.cats--pixels .cat-grid--4 .cat-card:nth-child(3) { --col: 3; --row: 4; }
.cats--pixels .cat-grid--4 .cat-card:nth-child(4) { --col: 7; --row: 4; }
.cats--pixels .cat-grid--2 .cat-card:nth-child(1) { --col: 3; --row: 2; }
.cats--pixels .cat-grid--2 .cat-card:nth-child(2) { --col: 6; --row: 4; }
.cats--pixels .cat-grid--1 .cat-card:nth-child(1) { --col: 4; --row: 3; }
.cats--pixels .cat-grid--5 .cat-card:nth-child(1) { --col: 2; --row: 2; }
.cats--pixels .cat-grid--5 .cat-card:nth-child(2) { --col: 5; --row: 2; }
.cats--pixels .cat-grid--5 .cat-card:nth-child(3) { --col: 7; --row: 3; }
.cats--pixels .cat-grid--5 .cat-card:nth-child(4) { --col: 3; --row: 4; }
.cats--pixels .cat-grid--5 .cat-card:nth-child(5) { --col: 5; --row: 4; }


/* ── MODE 2: MASONRY (class cats--masonry on .cats) ──
   Each open bar is a 6 × 7 grid of square cells with small gaps. Each cover spans a block of cells close to
   its own shape, so it barely crops; the cells left over form clean empty squares and rectangles.
   Where each cover goes: the --area lines below (row-start / col-start / row-end / col-end). */
.cats--masonry .cat-grid {
  --grid-cols: 6;
  --grid-rows: 7;

  display: grid;
  grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  grid-template-rows: repeat(var(--grid-rows), minmax(0, 1fr));
  block-size: 100%;   /* no gaps – covers sit edge to edge */
}

.cats--masonry .cat-card {
  grid-area: var(--area);
  min-block-size: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity var(--bar-fade-time);
}

.cats--masonry .cat-card video,
.cats--masonry .cat-card img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.cats--masonry .cat-caption {
  display: none;
}

/* the cover + caption wrapper (used by pixels mode) doesn't affect the masonry layout */
.cats--masonry .cat-reveal {
  display: contents;
}

/* hand-coded: index, WDTTG, manuscript, links */
.cats--masonry .cat--1 .cat-card:nth-child(1) { --area: 1 / 1 / 3 / 5; }
.cats--masonry .cat--1 .cat-card:nth-child(2) { --area: 1 / 5 / 3 / 7; }
.cats--masonry .cat--1 .cat-card:nth-child(3) { --area: 3 / 3 / 5 / 7; }
.cats--masonry .cat--1 .cat-card:nth-child(4) { --area: 5 / 1 / 7 / 4; }
/* illustration: the VCR, pukaare */
.cats--masonry .cat--2 .cat-card:nth-child(1) { --area: 1 / 1 / 4 / 5; }
.cats--masonry .cat--2 .cat-card:nth-child(2) { --area: 5 / 3 / 7 / 7; }
/* vibe-coded: figma-make-a-thon */
.cats--masonry .cat--3 .cat-card:nth-child(1) { --area: 3 / 1 / 6 / 7; }
/* fun stuff: gen x kinza, td scrapbook, gen x kinza, parsons fellowship, figma-make-a-thon */
.cats--masonry .cat--4 .cat-card:nth-child(1) { --area: 1 / 5 / 5 / 7; }
.cats--masonry .cat--4 .cat-card:nth-child(2) { --area: 1 / 1 / 3 / 5; }
.cats--masonry .cat--4 .cat-card:nth-child(3) { --area: 5 / 1 / 8 / 3; }
.cats--masonry .cat--4 .cat-card:nth-child(4) { --area: 5 / 3 / 7 / 7; }
.cats--masonry .cat--4 .cat-card:nth-child(5) { --area: 3 / 1 / 5 / 5; }

/* covers appear one after another once the bar has opened */
.cats--masonry .cat.is-open .cat-card {
  opacity: 1;
}

.cats--masonry .cat.is-open .cat-card:nth-child(1) { transition-delay: var(--bar-fade-delay); }
.cats--masonry .cat.is-open .cat-card:nth-child(2) { transition-delay: calc(var(--bar-fade-delay) + var(--card-stagger)); }
.cats--masonry .cat.is-open .cat-card:nth-child(3) { transition-delay: calc(var(--bar-fade-delay) + var(--card-stagger) * 2); }
.cats--masonry .cat.is-open .cat-card:nth-child(4) { transition-delay: calc(var(--bar-fade-delay) + var(--card-stagger) * 3); }
.cats--masonry .cat.is-open .cat-card:nth-child(5) { transition-delay: calc(var(--bar-fade-delay) + var(--card-stagger) * 4); }

/* "playground" in a white strip along the top of the bars area, black Instrument Sans letters with the roughen wobble.
   It's SVG text: home.js → "Playground title" sizes the SVG to the word, so it always fills the width exactly. */
.cats-title {
  margin: 0;
  padding: var(--space-sm);
  background: var(--page);
}

.cats-title {
  display: grid;
}

.cats-title-fit {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  min-block-size: 0;
  overflow: visible;
}

.cats-title-fit text {
  fill: var(--fg);
  font-family: var(--display);
  font-weight: 400;   /* regular, not bold */
  filter: url("#roughen");   /* wobbles like "hand-made" (filter in index.html, home.js keeps it moving) */
  font-size: var(--text-4xl);   /* any size works – the SVG scales it to the strip's width */
  letter-spacing: var(--tracking-tighter);
}

/* "skip ↓" at the bottom-left of the pinned area */
.cats-skip {
  position: absolute;
  inset-block-end: var(--space-md);
  inset-inline-start: var(--space-3xl);   /* bottom-left, under the paragraph – clear of the title */
  z-index: 2;
  display: grid;
  place-items: center;
  inline-size: var(--skip-size);
  aspect-ratio: 1757 / 1632;   /* the flower's own proportions */
  padding: 0;
  background: none;
  border: 0;
  color: var(--accent);   /* the arrow: brand blue on the white flower */
}

/* the flower: solid white, the same shape as the cursor + the marquee, with a quick spin on hover (the arrow stays upright) */
.cats-skip-flower {
  grid-area: 1 / 1;
  inline-size: 100%;
  block-size: 100%;
  background: var(--page);
  mask: url("../Assets/flower.svg") center / contain no-repeat;
}

/* one quick full turn each time you hover (it ends exactly where it started, so there's no jump) */
.cats-skip:hover .cats-skip-flower,
.cats-skip:focus-visible .cats-skip-flower {
  animation: skip-spin 600ms var(--ease-out) 1;
}

@keyframes skip-spin {
  to { rotate: 1turn; }
}

/* the arrows sit on top; they're cut off at the button's edge as they slide through
   (blue on the blue strip, so they only show where they're over the white flower) */
.cats-skip-icons {
  position: relative;
  z-index: 1;   /* above the masked flower, which would otherwise paint on top of them */
  grid-area: 1 / 1;
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: 100%;
  overflow: hidden;
}

/* the arrow: a long thin line with a chevron head */
.cats-skip-arrow {
  grid-area: 1 / 1;
  inline-size: calc(var(--skip-size) / 2);
  block-size: calc(var(--skip-size) / 2);
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: translate var(--hover-time) var(--ease-out);
}

/* the arrow's line is exactly as thick as the ring: non-scaling, so the width isn't shrunk by the drawing's size */
.cats-skip-arrow path {
  vector-effect: non-scaling-stroke;
  stroke-width: var(--skip-stroke);   /* the arrow's thickness (the ring is gone now – it's the flower) */
}

/* the second arrow waits above the circle */
.cats-skip-arrow--next {
  translate: 0 -200%;
}

/* hover: the first arrow drops out the bottom while the second slides in from the top */
.cats-skip:hover .cats-skip-arrow,
.cats-skip:focus-visible .cats-skip-arrow {
  translate: 0 200%;
}

.cats-skip:hover .cats-skip-arrow--next,
.cats-skip:focus-visible .cats-skip-arrow--next {
  translate: 0 0;
}

@media (prefers-reduced-motion: reduce) {
  .cats-skip-arrow { transition: none; }
  .cats-skip-flower { animation: none; }
}


/* space between the paragraphs */
.about-text p + p {
  margin-block-start: var(--space-xl);
}

/* key words in the paragraph, in brand yellow */
.about-text .hl {
  color: var(--brand-yellow);
}

/* styled like "hand-made" in the header: italic serif, a touch bigger, wobbling (filter in index.html, home.js keeps it moving) */
.about-text .hl--rough {
  display: inline-block;
  font-family: var(--serif);
  font-style: italic;
  font-size: calc(100% * var(--accent-word-scale));   /* % of the surrounding text size (no em) */
  filter: url("#roughen");
}

/* PP Mondwest, like "digital" in the header (same size boost) */
.about-text .hl--pixel {
  font-family: var(--pixel);
  font-size: calc(100% * var(--accent-word-scale));   /* % of the surrounding text size (no em) */
}

/* desktop: the section fills the screen under the nav; text vertically centred on the left, bars on the right */
@media (min-width: 701px) {
  .about-scroll .about-strip {
    position: relative;   /* anchors the "skip ↓" button */
    padding-inline-start: var(--space-3xl);   /* breathing room from the left edge */
    grid-template-columns: minmax(0, var(--about-text-width)) minmax(0, 1fr);
    /* 2 rows: the title strip on top (never shorter than --title-min, otherwise ~15% of the strip), the bars below.
       The paragraph is in the left column across BOTH rows and centred, so it sits in the exact middle of the screen
       whatever height the title strip is. */
    --title-min: calc(var(--space-4xl) + var(--space-xl));   /* so on shorter windows (Chrome with a bookmarks bar) the title still looks as big as in Safari */
    grid-template-rows: minmax(var(--title-min), 3fr) 17fr;
    row-gap: 0;
    align-items: stretch;
    block-size: calc(100vh - var(--nav-height) + var(--hairline));   /* exception to rem-only: "full screen minus the nav",
       plus one hairline so a half-pixel of the footer can never peek out underneath while the page is held here */
    padding-block: 0;
    padding-inline-end: 0;
  }
  .about-scroll .cats-title {
    grid-column: 2;
    grid-row: 1;
  }
  .about-scroll .cats {
    grid-column: 2;
    grid-row: 2;
  }
  .about-scroll .about-text {
    padding-block-end: calc(var(--skip-size) + var(--space-md) * 2);   /* room for the skip circle + its gap: lifts the centred paragraph up so the circle sits clear of the last line */
    grid-row: 1 / 3;   /* both rows – centred in the whole strip (less that room), equal space above and below */
    align-self: center;
    align-content: center;
  }
  .about-scroll .about-text p {
    max-inline-size: 100%;   /* stays inside its column */
  }
}

/* phones: no pinning – bars stack with their names across the top, skip button not needed */
@media (max-width: 700px) {
  .cats,
  .cat {
    display: block;
  }
  .cat-bar {
    writing-mode: horizontal-tb;
  }
  .cat-work,
  .cat-card {
    opacity: 1;
  }
  .cat-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    padding: var(--space-xs);
  }
  .cat-card {
    position: static;
    translate: none;
    inline-size: var(--square-size);
    block-size: var(--square-size);
  }
  .cats-skip {
    display: none;
  }

}

@media (prefers-reduced-motion: reduce) {
  .cat,
  .cat-work,
  .cat-card {
    transition: none;
  }
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   DOODLE NOTE (test) – a small form in the footer to leave a note and send your doodle.
   Sends with Netlify Forms (only works once deployed). js: home.js → "Doodle note".
   No outlines: fields are solid blocks, the button matches the others.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.doodle-note {
  position: relative;
  z-index: 1;   /* above the doodle canvas */
  display: grid;
  gap: var(--space-sm);
  inline-size: min(100%, 24rem);
  font-size: var(--button-text);
}

.doodle-note-field {
  display: grid;
  gap: var(--space-2xs);
}

.doodle-note-field input,
.doodle-note-field textarea {
  padding-block: var(--button-pad-block);
  padding-inline: var(--button-pad-inline);
  background: var(--tile);
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--fg);
  font: inherit;
  resize: vertical;
}

.doodle-note-check {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.doodle-note .footer-btn {
  justify-self: start;
  border: 0;
  font: inherit;
}

.doodle-note-status:empty {
  display: none;
}

/* hidden field that only bots fill in */
.doodle-note-trap {
  display: none;
}


/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   AWARDS RIBBON – a black ribbon tab on the right edge, just under the nav.
   It slides in from the side shortly after the page loads (same glide as the cursor),
   and scrolls away with the header. HTML: index.html → aside.awards-ribbon
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
.awards-ribbon {
  --ribbon-width: 12rem;
  --ribbon-notch: var(--space-lg);     /* depth of the V cut on the left edge */
  --ribbon-delay: 800ms;
  --ribbon-time: var(--cursor-morph-time);

  position: absolute;
  inset-block-start: calc(var(--nav-height) + var(--space-xl));
  inset-inline-end: 0;
  z-index: 5;
  display: grid;
  justify-items: center;
  gap: var(--space-sm);
  inline-size: var(--ribbon-width);
  padding-block: var(--space-md);
  padding-inline: calc(var(--ribbon-notch) + var(--space-sm)) var(--space-md);
  background: var(--fg);
  color: var(--page);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, var(--ribbon-notch) 50%);   /* ribbon tail */
  animation: ribbon-in var(--ribbon-time) var(--cursor-ease) var(--ribbon-delay) both;
}

@keyframes ribbon-in {
  from {
    translate: 100% 0;
  }
}

.awards-ribbon-label {
  font-size: var(--text-xs);
}

/* the AIGA logo: cropped to the lettering, its black background blended into the ribbon */
.awards-ribbon-aiga {
  --logo-share: 0.7;   /* share of the ribbon's inner width */
  display: block;
  inline-size: calc(100% * var(--logo-share));
  aspect-ratio: 1280 / 340;
  object-fit: cover;
  mix-blend-mode: screen;
}

.awards-ribbon-badge,
.awards-ribbon-badge img {
  display: block;
  inline-size: 100%;
}

@media (max-width: 700px) {
  .awards-ribbon {
    --ribbon-width: 9rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .awards-ribbon {
    animation: none;
  }
}

/* forage is locked for now: no link, "coming soon" pops up on hover instead of the case study cursor */
.soon-tag {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  z-index: var(--layer-label);
  padding-block: var(--button-pad-block);
  padding-inline: var(--button-pad-inline);
  background: var(--fg);
  color: var(--page);
  font-size: var(--button-text);
  line-height: var(--button-leading);
  translate: -50% -50%;
  scale: 0;
  transition: scale var(--hover-time) var(--ease-out);
  pointer-events: none;
}

/* .p-forage.is-locked:hover .soon-tag { scale: 1; }   moved onto the cursor label instead (js/flower-cursor.js → SOON) */

/* ── FigBuild badge on the forage tile: sized to the tile titles, and the "2026" pill only slides out while the tile is hovered
   (css/figbuild-badge.css holds the badge itself; this just fits it to the tile) ── */
.p-forage .figbuild-badge {
  --fb-size: var(--text-sm);
  --fb-pad-block: calc(var(--text-sm) * 0.15);
  --fb-pad-inline: calc(var(--text-sm) * 0.45);
  --fb-gap: var(--space-3xs);
  --fb-reach: calc(var(--text-sm) * 4);
  --fb-ink: var(--fg);
  --fb-paper: var(--page);
}

.p-forage .figbuild-window,
.p-forage .figbuild-year { animation-name: none; }   /* no motion until hover */

/* at rest the "2026" pill is tucked away (the animation's own first frame) */
.p-forage .figbuild-window { max-inline-size: 0; }
.p-forage .figbuild-year   { transform: translateX(-100%); }

.p-forage:hover .figbuild-window { animation-name: figbuild-open; }
.p-forage:hover .figbuild-year   { animation-name: figbuild-slide; }

@media (prefers-reduced-motion: reduce) {
  .p-forage:hover .figbuild-window,
  .p-forage:hover .figbuild-year { animation-name: none; }
}


/* forage tile: "fig-build" stays plain text until the tile is hovered, then turns into the FigBuild badge (and its "2026" slides out) */
.fb-swap {
  display: inline-grid;
  justify-items: end;
  align-items: center;
}

.fb-swap > * { grid-area: 1 / 1; }

.fb-swap-text,
.p-forage .figbuild-badge { transition: opacity var(--hover-time) var(--ease-out); }

.p-forage .figbuild-badge { opacity: 0; }

.p-forage:hover .fb-swap-text { opacity: 0; }
.p-forage:hover .figbuild-badge { opacity: 1; }

/* the text just fades into the badge – no roll on it */
.p:hover .fb-swap-text > span { translate: 0 0; }
.fb-swap-text > span::after { content: none; }


/* footer facts: who + where, the site's version, and the live New York time (js/home.js → "Footer clock") */
.footer-facts {
  margin-block-start: var(--space-lg);
  font-size: var(--text-sm);
  line-height: var(--leading-body);
  color: var(--soft);
}

.footer-facts p {
  margin: 0;
}

.footer-clock {
  font-variant-numeric: tabular-nums;   /* the digits don't jiggle as seconds tick */
}
