/* ==========================================================================
   Home page ("Chartreuse" direction) and the Play page. Loaded after site.css.
   Sections: 1 tokens · 2 intro scene · 3 work · 4 about · 5 play
   ========================================================================== */

/* 1. Tokens --------------------------------------------------------------- */
.home {
  /* Type: a high-contrast serif for headlines, a geometric sans for the rest.
     Case study pages keep their own fonts (site.css and digital-equity/). */
  --font-sans: 'Jost', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --ink-3: #675D51;
  --gold-1: #8A5A00; --gold-2: #C98A00; --gold-3: #F4B400; --gold-4: #F7C948; --gold-5: #FAE08A; --gold-6: #FCF0C9;
  --card-border: rgba(42, 35, 29, .06);
  /* Palette: the sun's yellow, with cobalt blue as the one highlight colour.
     Overrides the shared lime accent tokens from site.css for this page. */
  --cobalt: #0047AB;           /* 7.4:1 on cream */
  --cobalt-dark: #00337D;
  --lime: var(--cobalt);
  --lime-hl: rgba(0, 71, 171, .14);
  --lime-soft: rgba(0, 71, 171, .1);
  --olive: var(--cobalt-dark);
  --card-shadow: 0 24px 60px -36px rgba(201, 138, 0, .3);
  --card-shadow-hover: 0 30px 60px -34px rgba(201, 138, 0, .4);
  font-weight: 400;
  background-color: var(--cream);
}
.home .cap { font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-3); }
.home main { position: relative; z-index: 1; }
.brand--sans { font-family: var(--font-sans); font-size: 1rem; font-weight: 400; }

/* Key phrase marker: sits 36% high, fills on hover for links */
.klink, .home .hl {
  color: var(--cobalt); text-decoration: none;
  background-image: linear-gradient(var(--lime-hl), var(--lime-hl)); background-repeat: no-repeat;
  background-size: 100% 36%; background-position: 0 92%; transition: background-size .3s;
}
a.klink:hover, a.klink:focus-visible { background-size: 100% 100%; color: var(--cobalt-dark); }
.mark { font-weight: 600; }

/* 2. Intro scene ------------------------------------------------------------
   Without JS, or with reduced motion: a still composition (greeting, sun
   glow, headline). With motion, js/site.js sets --p (0 → 1) as you scroll
   through the tall .scene, and these rules play the sequence:
     0–.25 hold on the greeting · .25–.65 the sun rises to the centre of the
     screen, shrinking to 60% · .58–.74 the headline appears on it · then hold   */
.scene { position: relative; }
.scene-stage {
  position: relative; min-height: 100vh; min-height: 100svh; overflow: hidden;
  display: grid; place-items: center; padding: calc(var(--header-h) + 24px) var(--gutter) 96px;
}
.sig { font-size: clamp(1.25rem, 1rem + 1vw, 1.75rem); font-weight: 300; line-height: 1.4; text-align: center; }
.sig b { font-weight: 500; }
/* Small aside pinned to the bottom centre of the intro, above the scroll cue */
.psst { position: absolute; left: 0; right: 0; bottom: 104px; z-index: 2; padding-inline: var(--gutter); text-align: center; font-size: 12px; letter-spacing: .04em; font-style: italic; color: var(--ink-2); }
.scene h1 {
  font-family: var(--font-serif); font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem); line-height: 1.3; font-weight: 400; letter-spacing: -0.01em; color: var(--ink);
  text-align: center; max-width: 640px; text-wrap: balance;
}
.scene-copy { position: relative; z-index: 2; display: grid; gap: clamp(28px, 4vw, 48px); justify-items: center; }

/* Rotating role after "Hi, I'm Rhea": every role sits in one grid cell, so
   the line keeps the width of the longest and doesn't jump as they change */
.rotator { display: inline-grid; text-align: left; vertical-align: bottom; }
.rotator > span { grid-area: 1 / 1; opacity: 0; transform: translateY(.45em); transition: opacity .5s var(--ease), transform .5s var(--ease); }
.rotator > span.is-on { opacity: 1; transform: none; }
.rotator > span.is-off { opacity: 0; transform: translateY(-.45em); }

.sun {
  position: absolute; left: 50%; bottom: calc(-1 * min(66vw, 600px)); z-index: 1; pointer-events: none;
  width: min(100vw, 900px); aspect-ratio: 1; margin-left: calc(-.5 * min(100vw, 900px)); border-radius: 50%;
  background: radial-gradient(circle at 50% 52%, #FFD200 0%, #FFD200 55%, #FFDB33 74%, rgba(255, 224, 77, .55) 88%, rgba(255, 228, 102, 0) 100%);
  filter: blur(46px); opacity: .5;
  transform-origin: 50% 50%;
}
/* js/site.js swaps in a pre-rendered grainy bitmap, so scaling it each frame stays cheap */
.sun.is-baked { filter: none; background: none; border-radius: 0; }
.sun.is-baked::before { content: ""; position: absolute; inset: -30%; background: var(--sun-img) center / 100% 100% no-repeat; }

/* Fine grain over the sun (added by js/site.js). It covers the stage and
   never scales; a radial mask that follows the sun keeps it on the circle. */
.sun-grain {
  --s: min(100vw, 900px); --o: min(66vw, 600px);
  --k: calc(1 - var(--e, 0) * .4);
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: var(--grain-img) 0 0 / 180px 180px repeat;
  mix-blend-mode: overlay;
  --y: calc((1 - var(--e, 0)) * (100% + var(--o) - var(--s) * .5) + var(--e, 0) * 50%);
  opacity: .2;
  -webkit-mask-image: radial-gradient(circle calc(var(--s) * .62 * var(--k)) at 50% var(--y), #000 0%, #000 40%, transparent 82%);
          mask-image: radial-gradient(circle calc(var(--s) * .62 * var(--k)) at 50% var(--y), #000 0%, #000 40%, transparent 82%);
}

.scroll-cue--line { gap: 8px; }
.cuebar { display: block; width: 1px; height: 38px; background: linear-gradient(var(--lime), transparent); transform-origin: top; }
@keyframes cuel { 0%, 100% { transform: scaleY(.4); opacity: .5; } 50% { transform: scaleY(1); opacity: 1; } }
.js-motion .cuebar { animation: cuel 1.8s ease-in-out infinite; }

/* Scroll-driven version */
.js-scene .scene {
  height: 300vh;
  /* --e: how far the sun has risen, 0 → 1, eased out */
  --t: clamp(0, (var(--p, 0) - .25) / .4, 1);
  --e: calc(var(--t) * (2 - var(--t)));
}
.js-scene .scene-stage { position: sticky; top: 0; height: 100vh; height: 100svh; }
.js-scene .scene-copy { grid-area: 1 / 1; }
.js-scene .sig, .js-scene .scene h1 { grid-area: 1 / 1; }
.js-scene .sig, .js-scene .psst {
  /* fades as the sun rises */
  opacity: calc(1 - clamp(0, (var(--p, 0) - .25) / .13, 1));
  transform: translateY(calc(clamp(0, (var(--p, 0) - .25) / .13, 1) * -24px));
}
.js-scene .scene h1 {
  opacity: clamp(0, (var(--p, 0) - .58) / .16, 1);
  transform: translateY(calc((1 - clamp(0, (var(--p, 0) - .58) / .16, 1)) * 24px));
}
.js-scene .sun {
  /* rises from below the fold until its centre meets the centre of the screen */
  transform:
    translateY(calc(var(--e) * -1 * (50vh + min(66vw, 600px) - min(100vw, 900px) * .5)))
    scale(calc(1 - var(--e) * .4));
  transform:
    translateY(calc(var(--e) * -1 * (50svh + min(66vw, 600px) - min(100vw, 900px) * .5)))
    scale(calc(1 - var(--e) * .4));
}
.js-scene .scene .scroll-cue { opacity: calc(1 - clamp(0, (var(--p, 0) - .1) / .08, 1)); }

/* 3. Work ------------------------------------------------------------------ */
.home .work-aside .tagline { font-family: var(--font-serif); font-size: clamp(1.125rem, 1rem + .5vw, 1.375rem); line-height: 1.35; font-weight: 400; letter-spacing: -0.005em; color: var(--ink); }
.home .work-aside .experiences { font-size: clamp(1rem, .92rem + .35vw, 1.25rem); line-height: 1.55; color: var(--ink-2); }

.home .cards { counter-reset: card; gap: clamp(20px, 2.4vw, 28px); }
.home .cards > li { counter-increment: card; }

/* Card: cover image edge to edge on top, then title, one sentence, and the role at the foot */
.home .card {
  display: flex; flex-direction: column; padding: 6px; border-radius: 14px; color: inherit; text-decoration: none;
  background: #FFFDF8; border: 1px solid rgba(42, 35, 29, .22);
  box-shadow: 0 1px 2px rgba(42, 35, 29, .04), 0 18px 40px -24px rgba(42, 35, 29, .25);
  transition: box-shadow .3s;
}
.home .card:hover, .home .card:focus-visible { background: #FFFDF8; box-shadow: 0 1px 2px rgba(42, 35, 29, .06), 0 24px 48px -22px rgba(42, 35, 29, .32); }
.home .card-media { flex: none; aspect-ratio: 4 / 3; height: auto; min-height: 0; border-radius: 10px; background: #ECE6DA; }
.home .card-media > img { width: 100%; height: 100%; object-fit: cover; }
.home .card-body { flex: 1; display: flex; flex-direction: column; gap: 12px; padding: clamp(18px, 2.4vw, 30px) clamp(16px, 2.2vw, 28px) clamp(16px, 2vw, 26px); text-align: left; }
.home .card-title { font-family: var(--font-serif); font-size: clamp(1.75rem, 1.2rem + 1.8vw, 2.75rem); line-height: 1.08; font-weight: 400; letter-spacing: -0.015em; }
.home .card:hover .card-title { transform: none; }
.home .card-desc { margin: 0; font-size: clamp(.9375rem, .9rem + .2vw, 1.0625rem); line-height: 1.5; color: var(--ink-2); }
.home .card-foot { margin: auto 0 0; padding-top: 16px; }
.home .card-tag { font-size: clamp(1rem, .95rem + .3vw, 1.25rem); color: var(--ink); }

/* Stack (js/site.js adds .js-deck): the cards column is pinned and the
   cards sit one behind the other, each peeking out above the one in front.
   Scrolling slides the front card off to the right to show the next.     */
.js-deck .deck-stage {
  --peek: 30px;
  position: sticky; top: var(--header-h); height: calc(100vh - var(--header-h)); height: calc(100svh - var(--header-h));
  display: flex; flex-direction: column; justify-content: flex-end; padding-block: 24px;
}
.js-deck .work-head, .js-deck .work-count { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); margin: 0; }
.js-deck .cards { position: relative; display: block; width: 100%; height: calc(100% - var(--peek) * var(--behind, 4)); }
.js-deck .cards > li { position: absolute; inset: 0; will-change: transform, opacity; }
.js-deck .work { overflow-x: clip; } /* the card leaving to the right never widens the page */
.js-deck .card { height: 100%; }
.js-deck .card-media { aspect-ratio: auto; flex: 1 1 0; min-height: 0; }
.js-deck .card-body { flex: none; min-height: 42%; }

/* Counter pill under the cards */
.home .work-count {
  position: sticky; bottom: 20px; z-index: 2; justify-self: center; width: max-content; margin: 24px auto 0;
  background: var(--cream); padding: 8px 16px; border-radius: 999px; box-shadow: 0 6px 20px -10px rgba(42, 35, 29, .25);
}
.home .work-head { justify-content: flex-start; }

/* 4. About ----------------------------------------------------------------- */
.home .about-grid { align-items: end; }
.home .about-photo { display: grid; grid-template-columns: 1fr; gap: 16px; max-width: 480px; }
.home .about-photo .portrait { aspect-ratio: 480 / 611; border-radius: 24px; background: #F4E5DB; }
.home .about-photo figcaption { order: 0; writing-mode: horizontal-tb; transform: none; max-height: none; font-size: var(--fs-xs); }
.home .about-copy { font-weight: 300; line-height: 1.7; max-width: 700px; gap: 16px; }
.home .about-copy h2 { font-family: var(--font-sans); font-weight: 300; letter-spacing: -0.02em; }
@media (min-width: 900px) {
  .home .about-grid { grid-template-columns: minmax(300px, 480px) minmax(0, 700px); justify-content: space-between; }
}
@media (max-width: 899.98px) {
  .home .about-photo { max-width: 260px; margin-inline: auto; text-align: center; }
}


/* 5. Play ------------------------------------------------------------------
   A loose wall of side projects. Tiles flow in columns (masonry), so tall,
   square and wide images all sit together without cropping.               */
.play-intro { position: relative; overflow: hidden; padding: calc(var(--header-h) + clamp(56px, 9vw, 120px)) 0 clamp(40px, 6vw, 80px); text-align: center; }
.play-intro .container { position: relative; z-index: 1; display: grid; gap: 20px; justify-items: center; }
.play-intro h1 { font-family: var(--font-serif); font-size: clamp(3.5rem, 2rem + 7vw, 8rem); line-height: .95; font-weight: 400; letter-spacing: -0.03em; }
.play-lede { font-size: clamp(1.125rem, 1rem + .5vw, 1.5rem); font-weight: 300; line-height: 1.45; max-width: 36ch; color: var(--ink-2); }
.play-sun {
  position: absolute; left: 50%; top: 0; width: min(90vw, 720px); aspect-ratio: 1; transform: translate(-50%, -38%); border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, var(--gold-3) 0%, var(--gold-4) 30%, var(--gold-5) 52%, var(--gold-6) 72%, rgba(252, 240, 201, 0) 100%);
  filter: blur(40px); opacity: .75;
}
.js-motion .play-sun { animation: playsun 9s ease-in-out infinite alternate; }
@keyframes playsun { to { transform: translate(-50%, -32%) scale(1.08); } }

.play-wall { padding-bottom: clamp(72px, 10vw, 140px); }
.tiles { list-style: none; padding: 0; columns: 3 260px; column-gap: clamp(16px, 2.4vw, 32px); }
.tiles > li { list-style: none; break-inside: avoid; margin-bottom: clamp(16px, 2.4vw, 32px); }
.tile {
  display: block; padding: 12px; border-radius: clamp(20px, 2vw, 26px); color: inherit; text-decoration: none;
  background: rgba(246, 239, 224, .84); border: 1px solid var(--card-border); box-shadow: var(--card-shadow);
  transition: transform .45s var(--ease), box-shadow .45s var(--ease), background-color .3s;
}
.tile-media { border-radius: 16px; overflow: hidden; background: #F4E5DB; }
/* A real image sets its own shape: the placeholder ratio no longer applies */
.tile-media:has(img) { aspect-ratio: auto !important; }
.tile-media img { display: block; width: 100%; height: auto; }
.tile-body { display: grid; gap: 4px; padding: 14px 6px 6px; }
.tile-title { font-family: var(--font-serif); font-size: clamp(1.25rem, 1.1rem + .5vw, 1.5rem); font-weight: 400; line-height: 1.25; }
.tile-tag { font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
a.tile:focus-visible { outline: 2px solid var(--cobalt); outline-offset: 4px; }
/* Playful hover: each tile tips a little, alternating direction */
@media (hover: hover) {
  a.tile:hover { background: rgba(246, 239, 224, .98); box-shadow: var(--card-shadow-hover); }
  .js-motion a.tile:hover { transform: rotate(-1.2deg) translateY(-4px); }
  .js-motion .tiles > li:nth-child(even) a.tile:hover { transform: rotate(1.2deg) translateY(-4px); }
}
.show-drafts .tiles > li[data-draft] .tile { outline: 2px dashed rgba(42, 35, 29, .3); outline-offset: 4px; }

/* "Coming soon" note: js/site.js shows it while no tile is published */
.play-empty { display: none; text-align: center; font-size: clamp(1.125rem, 1rem + .4vw, 1.375rem); font-weight: 300; color: var(--ink-2); padding-block: 24px 48px; }
.play-empty.is-empty { display: block; }

/* Ping pong (js/pong.js) -------------------------------------------------
   The game draws on one fixed canvas that never takes clicks, under the
   header. With a mouse, the paddle replaces the yellow dot cursor.        */
.pong { position: fixed; inset: 0; z-index: 90; width: 100%; height: 100%; pointer-events: none; }
.has-paddle .cursor-dot { display: none; }
.has-paddle, .has-paddle * { cursor: none !important; }
.pong-bar {
  position: relative; z-index: 2; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px 20px;
  padding: calc(var(--header-h) + 20px) var(--gutter) 0;
}
.pong-switch {
  display: inline-flex; align-items: center; gap: 10px; padding: 8px 16px 8px 8px; border: 1px solid var(--card-border); border-radius: 999px;
  background: rgba(246, 239, 224, .9); box-shadow: var(--card-shadow); font: inherit; font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase; color: var(--ink);
}
.pong-switch:focus-visible { outline: 2px solid var(--cobalt); outline-offset: 3px; }
.pong-track { position: relative; width: 36px; height: 20px; border-radius: 999px; background: rgba(42, 35, 29, .16); transition: background-color .25s; }
.pong-knob { position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(42, 35, 29, .3); transition: transform .25s var(--ease); }
.pong-switch[aria-checked="true"] .pong-track { background: #F4B400; }
.pong-switch[aria-checked="true"] .pong-knob { transform: translateX(16px); }
.pong-hint, .pong-score { margin: 0; font-size: var(--fs-xs); color: var(--ink-3); }
.pong-score b { color: var(--ink); font-weight: 600; }
@media not ((hover: hover) and (pointer: fine)) { .pong-hint { display: none; } }
/* Focus mode: only the game is left */
.pong-focus body { overflow: hidden; }
.pong-focus .play-intro, .pong-focus .play-wall, .pong-focus .site-footer, .pong-focus .pong-hint { display: none; }
/* Touch screens: the canvas takes the finger, so dragging moves the paddle */
.pong-focus .pong { pointer-events: auto; touch-action: none; }
.pong-focus main { z-index: 95; }
