/* The landing. Four plates in a case, one per product; only Canvas is open. Under the pointer the background shows
   its grain (lamp.js). Double-clicking the page (or pressing L) files the plates into a ledger: one plate beside a
   list, where moving the pointer shivers the page. */
:root {
  --grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  1.4 0 0 0 -.62'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  --grain-blend: multiply;
  --grain-a: 0.18;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --grain-blend: normal; --grain-a: 0.22; }
}
:root[data-theme="dark"] { --grain-blend: normal; --grain-a: 0.22; }

body { min-height: 100svh; display: flex; flex-direction: column; }
main { flex: 1; width: 100%; } /* a centred .wrap in a flex column would otherwise shrink to its content */

/* the lamp sits behind everything, so it only ever falls on the background */
.lamp { position: fixed; inset: 0; z-index: -1; pointer-events: none; }
.lamp canvas { position: absolute; left: 0; top: 0; }
/* the ledger's shiver: the inks slip out of register along the pointer's motion (--sx, --sy) and settle */
.shivering :is(h1, h2, .st, .desc, .mark, .foot p, .brand) {
  text-shadow: calc(var(--sx) * -1px) calc(var(--sy) * -1px) 0 rgb(255 40 70 / 0.6), calc(var(--sx) * 1px) calc(var(--sy) * 1px) 0 rgb(30 150 255 / 0.6);
}
.shivering :is(.frame canvas, .brand svg, .emulsion) {
  filter: drop-shadow(calc(var(--sx) * -1px) calc(var(--sy) * -1px) 0 rgb(255 40 70 / 0.6)) drop-shadow(calc(var(--sx) * 1px) calc(var(--sy) * 1px) 0 rgb(30 150 255 / 0.6));
}
.shivering .frame { box-shadow: calc(var(--sx) * -1px) calc(var(--sy) * -1px) 0 rgb(255 40 70 / 0.35), calc(var(--sx) * 1px) calc(var(--sy) * 1px) 0 rgb(30 150 255 / 0.35); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.top .wrap { height: 64px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.foot .wrap { padding-block: clamp(64px, 9vw, 112px) 32px; }
.foot p { font: 400 12px var(--mono); color: var(--ink-3); letter-spacing: 0.02em; }

/* ───────── the case (default) ───────── */
.desk { padding-block: clamp(64px, 11vw, 140px) 0; }
.intro { margin-bottom: clamp(40px, 6vw, 64px); view-transition-name: intro; }
.intro h1 { font-size: clamp(26px, 3.4vw, 40px); line-height: 1.08; letter-spacing: -0.035em; max-width: 30ch; text-wrap: balance; }
.intro h1 .soft { color: var(--ink-3); }

.plates { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.plate { position: relative; }
.frame {
  position: relative; aspect-ratio: 4 / 5;
  background: var(--surface); border-radius: var(--r-plate); overflow: hidden; isolation: isolate;
  view-transition-class: frame;
}
.frame canvas { position: absolute; inset: 0; width: 100%; height: 100%; transition: opacity 0.3s ease; }
.frame canvas[data-embed="developed"] { opacity: 0; }
.frame::before { /* grain, as if the emulsion were still on glass; it shows only while the plate is under the pointer */
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: var(--grain); opacity: 0; mix-blend-mode: var(--grain-blend); transition: opacity 0.3s ease;
}
@media (hover: hover) { .live:is(:hover, :focus-within) .frame::before { opacity: var(--grain-a); } }
.frame::after { /* light falling across the plate as it's picked up */
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(120% 90% at 20% 0%, color-mix(in srgb, var(--bg) 60%, transparent), transparent 62%);
  opacity: 0; transition: opacity 0.3s ease;
}
.mark { position: absolute; z-index: 3; font: 400 11px var(--mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); transition: color 0.15s ease; }
.mark.no { left: 18px; top: 16px; }
.mark.trace { left: 18px; right: 18px; bottom: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0; transition: opacity 0.3s ease; }
.mark.trace .more { display: none; }
.idle .frame { background: color-mix(in srgb, var(--surface) 70%, var(--bg)); }
.idle .frame .emulsion { position: absolute; inset: 14%; border-radius: 6px; box-shadow: inset 0 0 0 1px var(--line); }

.cap { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 4px 12px; padding: 14px 4px 0; }
.cap .no { display: none; font: 400 12px var(--mono); color: var(--ink-3); letter-spacing: 0.04em; }
.cap h2 { font-size: 16px; letter-spacing: -0.02em; line-height: 1.3; }
.cap .st { font: 400 11.5px var(--mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; transition: color 0.15s ease; }
.cap .desc {
  grid-column: 1 / -1; font-size: 14px; line-height: 1.45; color: var(--ink-2); max-width: 32ch; text-wrap: pretty;
  opacity: 0; transform: translateY(-3px); transition: opacity 0.3s ease, transform 0.3s ease;
}
.idle h2 { color: var(--ink-3); }
.go::after { content: ""; position: absolute; inset: 0 0 -8px; border-radius: var(--r-plate); } /* the whole plate is the link */
.go:focus-visible { outline: none; }
.go:focus-visible::after { outline: 2px solid var(--accent); outline-offset: 3px; }
.arrow { display: inline-block; transition: transform 0.2s ease; }

.live:is(:hover, :focus-within) canvas[data-embed="developed"] { opacity: 1; }
.live:is(:hover, :focus-within) canvas[data-embed="latent"] { opacity: 0; }
.live:is(:hover, :focus-within) .frame::after { opacity: 1; }
.live:is(:hover, :focus-within) .mark { color: var(--ink-2); }
.live:is(:hover, :focus-within) .trace { opacity: 1; }
.live:is(:hover, :focus-within) .st { color: var(--ink); }
.live:is(:hover, :focus-within) .desc { opacity: 1; transform: none; }
.live:hover .arrow { transform: translateX(3px); }

/* ───────── the ledger (the easter egg) ───────── */
.desk[data-layout="ledger"] {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: clamp(32px, 6vw, 88px);
  grid-template-rows: 1fr repeat(5, auto) 1fr; /* the plate sets the height; the list centres beside it */
  padding-top: clamp(32px, 5vw, 64px);
}
.desk[data-layout="ledger"] .intro { grid-column: 2; grid-row: 2; margin-bottom: 28px; }
.desk[data-layout="ledger"] .intro h1 { font-size: clamp(19px, 1.8vw, 22px); line-height: 1.3; letter-spacing: -0.02em; max-width: 30ch; }
.desk[data-layout="ledger"] :is(.plates, .plate) { display: contents; }
.desk[data-layout="ledger"] .frame { grid-column: 1; grid-row: 1 / -1; align-self: center; width: 100%; aspect-ratio: 1; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; }
.desk[data-layout="ledger"] .live .frame { opacity: 1; }
.desk[data-layout="ledger"] .plates:has(.idle:hover) .live .frame { opacity: 0; }
.desk[data-layout="ledger"] .idle:hover .frame { opacity: 1; }
.desk[data-layout="ledger"] .cap {
  grid-column: 2; position: relative; grid-template-columns: 48px minmax(0, 1fr) auto;
  padding: 22px 4px; border-bottom: 1px solid var(--line);
}
.desk[data-layout="ledger"] .plate:nth-child(1) .cap { grid-row: 3; border-top: 1px solid var(--line); }
.desk[data-layout="ledger"] .plate:nth-child(2) .cap { grid-row: 4; }
.desk[data-layout="ledger"] .plate:nth-child(3) .cap { grid-row: 5; }
.desk[data-layout="ledger"] .plate:nth-child(4) .cap { grid-row: 6; }
.desk[data-layout="ledger"] .cap .no { display: block; }
.desk[data-layout="ledger"] .cap h2 { font-size: clamp(22px, 2.4vw, 30px); letter-spacing: -0.03em; line-height: 1.1; }
.desk[data-layout="ledger"] .cap .desc { grid-column: 2 / -1; max-width: 40ch; }
.desk[data-layout="ledger"] .trace .more { display: inline; }
.desk[data-layout="ledger"] .go::after { inset: 0; border-radius: 0; }

/* each plate and caption keeps its name across the switch, so the view transition moves them into place */
.plate:nth-child(1) .frame { view-transition-name: frame-1; } .plate:nth-child(1) .cap { view-transition-name: cap-1; }
.plate:nth-child(2) .frame { view-transition-name: frame-2; } .plate:nth-child(2) .cap { view-transition-name: cap-2; }
.plate:nth-child(3) .frame { view-transition-name: frame-3; } .plate:nth-child(3) .cap { view-transition-name: cap-3; }
.plate:nth-child(4) .frame { view-transition-name: frame-4; } .plate:nth-child(4) .cap { view-transition-name: cap-4; }
::view-transition-group(*) { animation-duration: 0.42s; animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1); }
::view-transition-old(*.frame), ::view-transition-new(*.frame) { height: 100%; object-fit: cover; }

/* ───────── smaller screens, touch, reduced motion ───────── */
@media (max-width: 900px) {
  .plates { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 28px; }
  .desk[data-layout="ledger"] { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; }
  .desk[data-layout="ledger"] .intro { grid-column: 1; grid-row: 1; }
  .desk[data-layout="ledger"] .frame { grid-column: 1; grid-row: 2; aspect-ratio: 4 / 3; margin-bottom: 24px; }
  .desk[data-layout="ledger"] .cap { grid-column: 1; }
}
@media (max-width: 520px) {
  .plates { grid-template-columns: minmax(0, 1fr); }
  .idle .frame { aspect-ratio: 16 / 7; }
  .desk[data-layout="ledger"] .idle .frame { aspect-ratio: 4 / 3; }
}
@media (hover: none) {
  .live canvas[data-embed="developed"] { opacity: 1; }
  .live canvas[data-embed="latent"] { opacity: 0; }
  .live .trace, .live .desc { opacity: 1; transform: none; }
  .live .st { color: var(--ink); }
  .lamp { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}
