/* ==========================================================================
   lab.css — "The Lab": a sheet of wet paper where each project is a pool of
   pigment. Loads AFTER exhibit-page.css and reuses its tokens, washes, grain,
   nav, reveal, golden-hour, footer and html.evening dark theme.

   This sheet adds: the theme-toggle styling (exhibit-page.css never styles the
   gallery.js-injected button), the bento mosaic of watercolor pools, the
   palette filter (paint dabs), the entrance/hover/FLIP/page-transition motion,
   and full html.evening overrides + reduced-motion fallbacks for everything new.
   ========================================================================== */

:root {
  --mat: #fbf7ee; /* exhibit-page.css only defines --mat in evening; mirror day */
  --hairline: rgba(46, 58, 72, 0.16);

  /* Type → pigment defaults (a tile may override via inline --accent). */
  --accent-game: #d98ba0;        /* rose      */
  --accent-game-deep: #b9637c;
  --accent-tool: #7fa8c9;        /* pond      */
  --accent-tool-deep: #4a7299;
  --accent-experiment: #a292c4;  /* wisteria  */
  --accent-experiment-deep: #7c6aa6;
  --accent-intro: #cdb878;       /* gold      */
  --accent-intro-deep: #a8924f;
}

/* ==========================================================================
   Theme toggle — gallery.js injects <button class="theme-toggle"> into the
   .exhibit-nav. exhibit-page.css doesn't style it, so we do (echoing gallery.css).
   ========================================================================== */

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.6rem;
  height: 2.6rem;
  margin-left: 1rem;
  flex-shrink: 0;
  padding: 0;
  border: 1px solid rgba(46, 58, 72, 0.35);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.25s ease, background-color 0.25s ease, color 0.25s ease;
}

.theme-toggle:hover {
  border-color: var(--pond-ink);
  background-color: rgba(127, 168, 201, 0.14);
}

html.evening .theme-toggle {
  border-color: rgba(233, 227, 211, 0.32);
}

html.evening .theme-toggle:hover {
  border-color: var(--pond-ink);
  background-color: rgba(159, 194, 224, 0.16);
}

/* ==========================================================================
   Layout shell — wider than the reading-column exhibit room; content above
   washes (z:0) and paint canvas (z:1).
   ========================================================================== */

.lab {
  position: relative;
  z-index: 2;
  max-width: 74rem;
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 3rem) clamp(1.1rem, 5vw, 3rem) clamp(4rem, 8vw, 7rem);
}

.lab-head {
  max-width: 42rem;
  margin-bottom: clamp(2.4rem, 5vw, 3.6rem);
}

.lab-title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(3rem, 9vw, 5.8rem);
  line-height: 1.02;
  letter-spacing: 0.01em;
  color: var(--ink);
  margin-bottom: 1rem;
}

.lab-subtitle {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.25rem, 3vw, 1.7rem);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 32em;
}

/* ==========================================================================
   Palette filter — a row of paint dabs (wet blots), not chrome buttons.
   ========================================================================== */

.palette {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(0.5rem, 1.6vw, 0.9rem);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.dab {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 2.75rem; /* generous tap target */
  padding: 0.5rem 1.05rem 0.5rem 0.7rem;
  border: 1px solid var(--hairline);
  border-radius: 2rem;
  background: rgba(251, 247, 238, 0.6);
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.82rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.3s ease, border-color 0.3s ease, background-color 0.3s ease,
    transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.3s ease;
}

.dab:hover {
  color: var(--ink);
  transform: translateY(-1px);
}

.dab:focus-visible {
  outline: 2px solid var(--pond-deep);
  outline-offset: 3px;
}

/* The wet blot — a soft pigment dot with a ragged watercolor edge. */
.dab-blot {
  width: 1.05rem;
  height: 1.05rem;
  border-radius: 54% 46% 57% 43% / 49% 56% 44% 51%;
  background: radial-gradient(circle at 38% 36%,
    var(--dab-accent, var(--ink-soft)) 0%,
    var(--dab-accent, var(--ink-soft)) 42%,
    rgba(0, 0, 0, 0) 78%);
  filter: url(#lab-soft);
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.dab--all { --dab-accent: var(--ink-soft); }
.dab--game { --dab-accent: var(--accent-game); }
.dab--tool { --dab-accent: var(--accent-tool); }
.dab--experiment { --dab-accent: var(--accent-experiment); }

.dab.is-active {
  color: var(--ink);
  border-color: var(--dab-accent, var(--ink-soft));
  background: rgba(251, 247, 238, 0.92);
  box-shadow: 0 6px 18px -12px rgba(46, 58, 72, 0.5);
}

.dab.is-active .dab-blot {
  transform: scale(1.18);
}

/* ==========================================================================
   THE MOSAIC — asymmetric bento. Tiles are watercolor POOLS.
   ========================================================================== */

.mosaic {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 12.5rem;
  grid-auto-flow: dense;
  gap: clamp(0.9rem, 2vw, 1.5rem);
}

/* Spans — composed, not random. */
.pool[data-span="1x1"] { grid-column: span 1; grid-row: span 1; }
.pool[data-span="2x1"] { grid-column: span 2; grid-row: span 1; }
.pool[data-span="2x2"] { grid-column: span 2; grid-row: span 2; }

.pool {
  position: relative;
  display: flex;
  min-width: 0;
  isolation: isolate;
}

/* The pigment pool itself: a soft accent bloom on the paper with a ragged
   wet edge from the SVG displacement filter. Lives behind the content. */
.pool-skin {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: 1.4rem;
  background:
    radial-gradient(125% 120% at 30% 22%,
      color-mix(in srgb, var(--accent) 34%, transparent) 0%,
      color-mix(in srgb, var(--accent) 14%, transparent) 46%,
      rgba(0, 0, 0, 0) 78%),
    radial-gradient(95% 100% at 78% 84%,
      color-mix(in srgb, var(--accent-deep) 26%, transparent) 0%,
      rgba(0, 0, 0, 0) 62%),
    linear-gradient(180deg,
      rgba(251, 247, 238, 0.9) 0%,
      rgba(251, 247, 238, 0.78) 100%);
  border: 1px solid var(--hairline);
  box-shadow:
    0 1px 2px rgba(46, 58, 72, 0.08),
    0 18px 34px -22px rgba(46, 58, 72, 0.4);
  filter: url(#lab-soft);
  transition: box-shadow 0.4s ease, transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Default accent per type (override with inline --accent on the <li>). */
.pool { --accent: var(--accent-tool); --accent-deep: var(--accent-tool-deep); }
.pool[data-type="game"] { --accent: var(--accent-game); --accent-deep: var(--accent-game-deep); }
.pool[data-type="tool"] { --accent: var(--accent-tool); --accent-deep: var(--accent-tool-deep); }
.pool[data-type="experiment"] { --accent: var(--accent-experiment); --accent-deep: var(--accent-experiment-deep); }
.pool[data-type="intro"] { --accent: var(--accent-intro); --accent-deep: var(--accent-intro-deep); }

/* Content layer (above the skin). */
.pool-body {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: clamp(1.1rem, 2.4vw, 1.6rem);
  gap: 0.55rem;
}

.pool-link {
  display: block;
  width: 100%;
  color: inherit;
  text-decoration: none;
}

.pool-link:focus-visible {
  outline: none;
}

.pool-link:focus-visible ~ .pool-skin,
.pool-link:focus-visible .pool-skin {
  outline: 2px solid var(--accent-deep);
  outline-offset: 3px;
}

/* --- meta row: type label + status badge --- */
.pool-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.15rem;
}

.pool-type {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.66rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.type-dot {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 56% 44% 53% 47% / 47% 55% 45% 53%;
  background: radial-gradient(circle at 36% 34%,
    var(--accent) 0%, var(--accent-deep) 75%, rgba(0, 0, 0, 0) 100%);
  filter: url(#lab-soft);
}

.status {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.2rem 0.55rem;
  border-radius: 1rem;
  white-space: nowrap;
}

.status--live {
  color: #355f30;
  background: rgba(147, 180, 139, 0.32);
  border: 1px solid rgba(147, 180, 139, 0.55);
}

.status--building {
  color: #7a5f12;
  background: rgba(205, 184, 120, 0.32);
  border: 1px solid rgba(205, 184, 120, 0.6);
}

.status--idea {
  color: var(--ink-soft);
  background: rgba(90, 106, 121, 0.12);
  border: 1px solid rgba(90, 106, 121, 0.3);
}

/* --- titles + copy --- */
.pool-title {
  position: relative;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  line-height: 1.12;
  color: var(--ink);
  margin-top: auto; /* push title block toward the bottom of the pool */
}

/* Painted underline — wipes in on hover/focus, left to right. */
.pool-title::after {
  content: "";
  display: block;
  width: 100%;
  height: 2px;
  margin-top: 0.4rem;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent-deep), var(--accent));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.pool-title--intro {
  margin-top: 0;
  font-size: clamp(1.7rem, 3.4vw, 2.5rem);
  font-weight: 400;
  line-height: 1.08;
}

.pool-desc {
  font-size: 0.93rem;
  line-height: 1.6;
  color: var(--ink);
  opacity: 0.82;
  transition: opacity 0.4s ease;
}

.pool-kicker {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.66rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--accent-deep);
}

.pool-hint {
  margin-top: 0.5rem;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.pool-tags {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.55rem;
}

.pool-tags li {
  font-family: var(--font-body);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  padding: 0.15rem 0.5rem;
  border-radius: 1rem;
  border: 1px solid var(--hairline);
  background: rgba(251, 247, 238, 0.5);
}

.pool-cta {
  margin-top: 0.7rem;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-deep);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}

/* Intro pool: a touch larger gold bloom, content top-aligned. */
.pool--intro .pool-body { justify-content: flex-start; gap: 0.7rem; }

/* ==========================================================================
   HOVER / FOCUS = PIGMENT BLEEDS OPEN
   The pool lifts, the bloom spreads (rougher displaced edge + brighter wash),
   the underline paints in, copy crisps up, CTA arrives.
   ========================================================================== */

@media (hover: hover) and (pointer: fine) {
  .pool-link:hover .pool-skin,
  .pool[data-status="idea"]:hover .pool-skin,
  .pool[data-status="building"]:hover .pool-skin,
  .pool--intro:hover .pool-skin {
    filter: url(#lab-rough);
    transform: scale(1.012);
    box-shadow:
      0 1px 2px rgba(46, 58, 72, 0.1),
      0 26px 46px -22px rgba(46, 58, 72, 0.5);
  }
}

/* Hover (linking) + focus-within (keyboard) share the bleed-open look. */
.pool-link:hover .pool-skin,
.pool:focus-within .pool-skin,
.pool--intro:hover .pool-skin,
.pool[data-status="idea"]:hover .pool-skin,
.pool[data-status="building"]:hover .pool-skin {
  background:
    radial-gradient(135% 130% at 30% 22%,
      color-mix(in srgb, var(--accent) 48%, transparent) 0%,
      color-mix(in srgb, var(--accent) 20%, transparent) 50%,
      rgba(0, 0, 0, 0) 80%),
    radial-gradient(105% 110% at 78% 84%,
      color-mix(in srgb, var(--accent-deep) 34%, transparent) 0%,
      rgba(0, 0, 0, 0) 64%),
    linear-gradient(180deg,
      rgba(253, 250, 243, 0.94) 0%,
      rgba(251, 247, 238, 0.82) 100%);
}

.pool-link:hover .pool-title::after,
.pool:focus-within .pool-title::after,
.pool--intro:hover .pool-title::after,
.pool[data-status="idea"]:hover .pool-title::after {
  transform: scaleX(1);
}

.pool-link:hover .pool-desc,
.pool:focus-within .pool-desc,
.pool[data-status="idea"]:hover .pool-desc {
  opacity: 1;
}

.pool-link:hover .pool-cta,
.pool:focus-within .pool-cta {
  opacity: 1;
  transform: translateX(0);
}

/* ==========================================================================
   ENTRANCE = WET BLEED-IN (richer than .reveal; orchestrated by lab.js).
   lab.js adds .lab-staged to <html> (so the field is hidden pre-animation),
   sets a per-tile --i, then adds .bloomed to play. The .reveal class on each
   <li> stays inert because lab.js neutralizes gallery.js reveals on pools.
   ========================================================================== */

html.lab-staged .mosaic .pool {
  opacity: 0;
  transform: scale(0.94) translateY(14px);
  clip-path: inset(0 0 100% 0 round 1.4rem); /* wipes open from the top */
}

html.lab-staged .mosaic .pool.bloomed {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0 round 1.4rem);
  transition:
    opacity 0.8s ease calc(var(--i, 0) * 70ms),
    transform 0.85s cubic-bezier(0.22, 1, 0.36, 1) calc(var(--i, 0) * 70ms),
    clip-path 0.85s cubic-bezier(0.22, 1, 0.36, 1) calc(var(--i, 0) * 70ms);
}

/* ==========================================================================
   FLIP filter re-layout — lab.js measures positions, sets --flip-x/y, then
   clears them on the next frame so tiles glide to their new spot.
   ========================================================================== */

.pool.is-flipping {
  transform: translate(var(--flip-x, 0px), var(--flip-y, 0px));
  transition: none;
  z-index: 3;
}

.pool.is-flipping.flip-play {
  transform: none;
  transition: transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Tiles leaving the field bleed out; arriving tiles bleed in. */
.pool.is-hidden {
  display: none;
}

.pool.bleed-out {
  opacity: 0;
  transform: scale(0.9);
  filter: url(#lab-rough);
  transition: opacity 0.4s ease, transform 0.4s ease;
  pointer-events: none;
}

.pool.bleed-in {
  animation: pool-bleed-in 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes pool-bleed-in {
  0% { opacity: 0; transform: scale(0.92); clip-path: inset(0 0 100% 0 round 1.4rem); }
  100% { opacity: 1; transform: none; clip-path: inset(0 0 0 0 round 1.4rem); }
}

/* ==========================================================================
   PAGE TRANSITION — paint blooms out from the click point, then we navigate.
   Native cross-document View Transitions where supported; JS overlay fallback.
   ========================================================================== */

@view-transition {
  navigation: auto;
}

#bloom-overlay {
  position: fixed;
  z-index: 200;
  left: var(--bloom-x, 50%);
  top: var(--bloom-y, 50%);
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: radial-gradient(circle,
    var(--bloom-accent, var(--pond)) 0%,
    var(--bloom-accent, var(--pond)) 55%,
    color-mix(in srgb, var(--bloom-accent, var(--pond)) 70%, transparent) 100%);
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
  pointer-events: none;
}

#bloom-overlay.blooming {
  opacity: 1;
  /* scaled to comfortably cover any viewport from the click point */
  transform: translate(-50%, -50%) scale(2200);
  transition: transform 0.62s cubic-bezier(0.5, 0, 0.4, 1), opacity 0.5s ease;
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */

@media (max-width: 900px) {
  .mosaic {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 12rem;
  }
  /* Re-map spans for 2 columns. */
  .pool[data-span="2x2"] { grid-column: span 2; grid-row: span 2; }
  .pool[data-span="2x1"] { grid-column: span 2; grid-row: span 1; }
  .pool[data-span="1x1"] { grid-column: span 1; grid-row: span 1; }
}

@media (max-width: 600px) {
  .mosaic {
    grid-template-columns: 1fr;
    grid-auto-rows: minmax(11rem, auto);
  }
  .pool[data-span="2x2"],
  .pool[data-span="2x1"],
  .pool[data-span="1x1"] {
    grid-column: span 1;
    grid-row: span 1;
  }
}

@media (max-width: 480px) {
  .dab {
    font-size: 0.74rem;
    letter-spacing: 0.1em;
    padding: 0.5rem 0.85rem 0.5rem 0.6rem;
  }
}

/* ==========================================================================
   REDUCED MOTION — everything degrades to instant / no travel.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .dab,
  .dab-blot,
  .pool-skin,
  .pool-title::after,
  .pool-desc,
  .pool-cta {
    transition: none;
  }

  html.lab-staged .mosaic .pool,
  html.lab-staged .mosaic .pool.bloomed {
    opacity: 1;
    transform: none;
    clip-path: none;
    transition: none;
  }

  .pool.is-flipping,
  .pool.is-flipping.flip-play {
    transform: none;
    transition: none;
  }

  .pool.bleed-out {
    transition: none;
  }

  .pool.bleed-in {
    animation: none;
  }

  /* No page-transition bloom: navigate plainly. */
  #bloom-overlay,
  #bloom-overlay.blooming {
    transition: none;
    opacity: 0;
    transform: translate(-50%, -50%) scale(0);
  }

  /* Hover bleed-open still allowed (it's a state, not a loop) but kept calm. */
  .pool-link:hover .pool-skin,
  .pool:focus-within .pool-skin,
  .pool[data-status="idea"]:hover .pool-skin {
    transform: none;
  }
}

/* ==========================================================================
   EVENING — dark theme overrides for every new surface/text colour.
   exhibit-page.css already flips --paper/--ink/--mat etc.; here we re-tune the
   pool skins, dabs, badges and bloom so contrast stays AA on slate walls.
   ========================================================================== */

html.evening {
  --hairline: rgba(233, 227, 211, 0.18);

  /* Slightly brighter pigments so washes glow out of the dark. */
  --accent-game: #e3a0b3;
  --accent-game-deep: #c97f95;
  --accent-tool: #9fc2e0;
  --accent-tool-deep: #6f9bc4;
  --accent-experiment: #bcaede;
  --accent-experiment-deep: #9a87c7;
  --accent-intro: #ddc98a;
  --accent-intro-deep: #c2ac68;
}

html.evening .dab {
  background: rgba(43, 49, 64, 0.55);
  border-color: var(--hairline);
}

html.evening .dab.is-active {
  background: rgba(43, 49, 64, 0.92);
  box-shadow: 0 6px 18px -12px rgba(0, 0, 0, 0.7);
}

html.evening .pool-skin {
  background:
    radial-gradient(125% 120% at 30% 22%,
      color-mix(in srgb, var(--accent) 30%, transparent) 0%,
      color-mix(in srgb, var(--accent) 12%, transparent) 46%,
      rgba(0, 0, 0, 0) 78%),
    radial-gradient(95% 100% at 78% 84%,
      color-mix(in srgb, var(--accent-deep) 22%, transparent) 0%,
      rgba(0, 0, 0, 0) 62%),
    linear-gradient(180deg,
      rgba(43, 49, 64, 0.9) 0%,
      rgba(36, 41, 54, 0.82) 100%);
  border-color: var(--hairline);
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.35),
    0 18px 34px -22px rgba(0, 0, 0, 0.6);
}

html.evening .pool-link:hover .pool-skin,
html.evening .pool:focus-within .pool-skin,
html.evening .pool--intro:hover .pool-skin,
html.evening .pool[data-status="idea"]:hover .pool-skin,
html.evening .pool[data-status="building"]:hover .pool-skin {
  background:
    radial-gradient(135% 130% at 30% 22%,
      color-mix(in srgb, var(--accent) 44%, transparent) 0%,
      color-mix(in srgb, var(--accent) 18%, transparent) 50%,
      rgba(0, 0, 0, 0) 80%),
    radial-gradient(105% 110% at 78% 84%,
      color-mix(in srgb, var(--accent-deep) 30%, transparent) 0%,
      rgba(0, 0, 0, 0) 64%),
    linear-gradient(180deg,
      rgba(51, 58, 75, 0.94) 0%,
      rgba(43, 49, 64, 0.84) 100%);
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.4),
    0 26px 46px -22px rgba(0, 0, 0, 0.7);
}

html.evening .pool-tags li {
  background: rgba(43, 49, 64, 0.5);
  border-color: var(--hairline);
}

html.evening .status--live {
  color: #bfe0b4;
  background: rgba(147, 180, 139, 0.2);
  border-color: rgba(147, 180, 139, 0.45);
}

html.evening .status--building {
  color: #e6d49a;
  background: rgba(205, 184, 120, 0.2);
  border-color: rgba(205, 184, 120, 0.5);
}

html.evening .status--idea {
  color: var(--ink-soft);
  background: rgba(233, 227, 211, 0.08);
  border-color: rgba(233, 227, 211, 0.25);
}
