/* Neutral everywhere, one accent that is allowed to pop. The accent tokens are
   written by palette.js; these are only first-paint fallbacks. */
:root {
  --accent: #b07a8f; --accent-ink: #7d4b5f; --accent-soft: #f1e6ea; --accent-deep: #5a2c3c;
  /* light mode is CREAM, not white: a warm off-white page, a slightly lighter sheet, cards a breath
     lighter again, and the lines and muted text pulled warm to sit in it */
  --bg: #f3e4c6; --sheet: #f8ecd3; --ink: #2e251a; --muted: #7a684e; --line: #e2cfab; --card: #fdf4e0;
  --globe-ink: #8a8782;
  --ui: 'Inter Tight', system-ui, -apple-system, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, monospace;
  --band: 54svh;   /* the stage above every section. On a phone held upright it is TALL (54svh), so Colin
                     is big; footage fills it by cropping its sides. Wide screens: a 3:2 band (below). */
  --gut: clamp(16px, 4vw, 40px);
  --r: 14px;
}
:root[data-theme="dark"] {
  --bg: #0e0e0f; --sheet: #141415; --ink: #eeece8; --muted: #9a978f; --line: #2a2a2c; --card: #1b1b1d;
  --globe-ink: #77746e;
}

* { box-sizing: border-box; }
/* `clip`, not just `hidden`: iOS still lets a thumb pan a body that is merely `hidden`, and the
   stage floor runs 40px past both edges on purpose -- clip makes the page exactly screen-wide. */
html { background: var(--bg); color: var(--ink); -webkit-text-size-adjust: 100%; overflow-x: hidden; overflow-x: clip; }
body { margin: 0; font: 400 16px/1.5 var(--ui); background: var(--bg); overflow-x: hidden; overflow-x: clip; }
a { color: inherit; }
img, video { display: block; max-width: 100%; }
button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---- the stage -------------------------------------------------------- */
#stage { position: fixed; inset: 0; z-index: 0; }
#globe { width: 100%; height: 100%; display: block; touch-action: pan-y; cursor: grab; }
body:not(.at-home) #globe { cursor: default; }
#labels { position: absolute; inset: 0; pointer-events: none; }
.glabel {
  position: absolute; left: 0; top: 0; text-decoration: none; white-space: nowrap;
  display: flex; align-items: baseline; gap: .45em; padding: 6px 10px 6px 14px;
  margin: -14px 0 0 0; font: 600 13px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink); will-change: transform, opacity; transition: color .2s, font-size .3s;
}
.glabel::before {           /* the leader tick back to the pin */
  content: ''; position: absolute; left: 0; top: 50%; width: 10px; height: 1px; background: var(--ink); opacity: .5;
}
.glabel i { font-style: normal; font-weight: 400; font-size: .75em; color: var(--muted); }
.glabel.tier1 { font-size: 15px; }
.glabel.tier3 { font-size: 11px; color: var(--muted); }
.glabel:hover, .glabel.on { color: var(--accent-ink); }
.glabel.on span { background: var(--accent); color: #fff; padding: 3px 6px; margin: -3px -6px; border-radius: 4px; }
#labels.compact .glabel { font-size: 10px; }
#labels.compact .glabel:not(.on) span { opacity: .7; }

/* ---- HUD -------------------------------------------------------------- */
#hud {
  position: fixed; top: 0; left: 0; right: 0; z-index: 20; display: flex; justify-content: space-between;
  align-items: center; padding: calc(10px + env(safe-area-inset-top)) var(--gut) 10px; pointer-events: none;
}
#hud > * { pointer-events: auto; }
.mark { font: 700 14px/1 var(--ui); letter-spacing: .22em; text-decoration: none; }
.mark b { font-weight: 400; margin-left: .35em; color: var(--muted); }
.tools { display: flex; gap: 8px; }
.tool {
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--line); background: color-mix(in srgb, var(--sheet) 80%, transparent);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); cursor: pointer; display: grid; place-items: center;
  font-size: 15px; line-height: 1; padding: 0; touch-action: manipulation;
}
.tool[aria-pressed="true"] { border-color: var(--accent); color: var(--accent-ink); }
.swatch { background: var(--accent); border-color: transparent; box-shadow: inset 0 0 0 3px var(--sheet); }

/* ---- home: the hero sits over the globe -------------------------------- */
#hero {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 5; pointer-events: none;
  padding: 0 var(--gut) calc(22px + env(safe-area-inset-bottom)); text-align: center;
  transition: opacity .4s, transform .6s cubic-bezier(.2,.8,.2,1);
}
#hero h1 { margin: 0; font: 700 clamp(34px, 7vw, 76px)/.95 var(--ui); letter-spacing: -.035em; }
#hero p { margin: .5em 0 1em; color: var(--muted); font-size: clamp(14px, 1.6vw, 17px); }
.scroll-cue { pointer-events: auto; font: 500 12px var(--mono); letter-spacing: .12em; text-transform: uppercase;
  text-decoration: none; color: var(--accent-ink); }
body:not(.at-home) #hero { opacity: 0; transform: translateY(30px); }
body.scrolled #hero { opacity: 0; }

/* ---- the content sheet ------------------------------------------------- */
#view {
  position: relative; z-index: 10; min-height: calc(100svh - var(--band));
  margin-top: var(--band); background: var(--sheet); border-top: 1px solid var(--line);
  border-radius: 22px 22px 0 0; padding: 28px var(--gut) 80px; outline: none;
  box-shadow: 0 -30px 60px -40px rgba(0,0,0,.25);
}
body.at-home #view { margin-top: 100svh; }
/* Glorb takes the top half on a phone, a bit more on a wide screen, so the
   shelves start on the first screen instead of below a whole screen of him */
body.has-glorb.at-home #view { margin-top: var(--band); }
#view.enter { animation: rise .6s cubic-bezier(.2,.8,.2,1) both; }
@keyframes rise { from { transform: translateY(60px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { #view.enter { animation: none; } }

.wrap { max-width: 1180px; margin: 0 auto; }
.crumbs { font: 500 12px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; }
.crumbs a { text-decoration: none; }
.crumbs a:hover { color: var(--accent-ink); }
h2.title { font: 700 clamp(30px, 5vw, 54px)/1 var(--ui); letter-spacing: -.03em; margin: 0 0 .3em; }
.lede { color: var(--muted); max-width: 60ch; margin: 0 0 28px; font-size: 17px; }
h3.sub { font: 500 12px var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin: 40px 0 14px;
  padding-top: 14px; border-top: 1px solid var(--line); }
/* a page that OPENS on a sub-heading (Games, since its crumbs and lede went) has the deck right
   above it already: no rule and no gap to separate it from nothing */
.wrap > h3.sub:first-child { margin-top: -10px; padding-top: 0; border-top: 0; }

/* home index: every section as a row */
.index { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.index li a { display: grid; grid-template-columns: 3em 1fr auto; gap: 12px; align-items: baseline; padding: 18px 4px;
  border-bottom: 1px solid var(--line); text-decoration: none; transition: background .2s, padding .2s; }
.index li a:hover { background: var(--accent-soft); padding-left: 12px; }
.index i { font: 400 12px var(--mono); color: var(--muted); font-style: normal; }
.index b { font: 600 clamp(20px, 3vw, 30px)/1.1 var(--ui); letter-spacing: -.02em; }
.index span { color: var(--muted); font-size: 14px; text-align: right; }
@media (max-width: 640px) { .index li a { grid-template-columns: 2.4em 1fr; } .index span { grid-column: 2; text-align: left; } }

/* cards */
.grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.card { position: relative; display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r); padding: 16px; text-decoration: none; transition: border-color .2s, transform .2s; }
a.card:hover { border-color: var(--accent); transform: translateY(-2px); }
.card .thumb { width: 64px; height: 64px; border-radius: 14px; object-fit: cover; margin-bottom: 14px; background: var(--accent-soft); }
.card .mono { width: 64px; height: 64px; border-radius: 14px; margin-bottom: 14px; display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent-ink); font: 700 26px var(--ui); }
.card h4 { margin: 0 0 4px; font: 600 19px/1.2 var(--ui); letter-spacing: -.01em; }
.card p { margin: 0; color: var(--muted); font-size: 14.5px; }
.card .meta { margin-top: auto; padding-top: 14px; display: flex; flex-wrap: wrap; gap: 6px; }
.pill { font: 500 11px var(--mono); letter-spacing: .06em; text-transform: uppercase; border: 1px solid var(--line);
  border-radius: 99px; padding: 3px 8px; color: var(--muted); }
.pill.hot { border-color: var(--accent); color: var(--accent-ink); }

/* spec sheet */
.specs { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 12px 0 0; font-size: 13.5px; }
.specs dt { font: 500 11px/1.9 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.specs dd { margin: 0; }

.btn { display: inline-flex; align-items: center; gap: 8px; padding: 11px 18px; border-radius: 99px; text-decoration: none;
  background: var(--ink); color: var(--sheet); font-weight: 600; border: 0; cursor: pointer; }
.btn.accent { background: var(--accent); color: #fff; }
.btn.ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); }
.btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 20px 0; }

/* the motion wall: three columns of autoplaying loops, like the old site */
.wall { columns: 3 220px; column-gap: 10px; }
.wall figure { margin: 0 0 10px; break-inside: avoid; border-radius: 10px; overflow: hidden; background: #000; position: relative; }
.wall video, .wall img { width: 100%; height: auto; }
.wall figcaption { position: absolute; left: 8px; bottom: 6px; font: 500 10px var(--mono); letter-spacing: .1em;
  text-transform: uppercase; color: #fff; opacity: 0; transition: opacity .2s; text-shadow: 0 1px 3px #000; }
.wall figure:hover figcaption { opacity: 1; }
.wall.light figure { background: var(--card); }

.soon { color: var(--muted); font-size: 14px; }
.soon li { margin: 4px 0; }
footer.foot { margin-top: 60px; padding-top: 18px; border-top: 1px solid var(--line); display: flex; justify-content: space-between;
  flex-wrap: wrap; gap: 10px; font: 400 12px var(--mono); color: var(--muted); }
footer.foot a { color: var(--muted); }
body.no-globe.at-home #view { margin-top: 60svh; }

/* ---- asset viewer ------------------------------------------------------- */
.viewer { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 16px; margin: 8px 0 10px; }
.viewer-stage { position: relative; height: min(68svh, 620px); border-radius: var(--r); border: 1px solid var(--line);
  background: radial-gradient(ellipse at 50% 35%, var(--card), var(--bg)); overflow: hidden; }
.viewer-stage canvas { width: 100%; height: 100%; display: block; touch-action: none; cursor: grab; }
.viewer-status, .viewer-hint { position: absolute; left: 14px; font: 500 11px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.viewer-status { top: 14px; } .viewer-hint { bottom: 12px; opacity: .7; }
.viewer-side .sub { margin-top: 18px; }
.specs.live { margin-top: 0; }
.clips { display: flex; flex-direction: column; gap: 2px; max-height: calc(min(68svh, 620px) - 180px); overflow: auto; }
.clips button { display: flex; justify-content: space-between; gap: 8px; text-align: left; border: 0; background: none; cursor: pointer;
  padding: 7px 10px; border-radius: 8px; font-size: 13.5px; }
.clips button i { font: 400 11px var(--mono); color: var(--muted); font-style: normal; }
.clips button:hover { background: var(--accent-soft); }
.clips button[aria-selected="true"] { background: var(--accent); color: #fff; }
.clips button[aria-selected="true"] i { color: #fff; }
@media (max-width: 760px) {
  .viewer { grid-template-columns: 1fr; }
  .viewer-stage { height: 56svh; }
  .clips { flex-direction: row; flex-wrap: wrap; max-height: 150px; }
  .clips button { border: 1px solid var(--line); border-radius: 99px; padding: 5px 10px; }
}

/* ---- writing ------------------------------------------------------------ */
.wrap.narrow { max-width: 720px; }
.essay-meta { font: 500 12px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 18px; }
.essay { font: 400 clamp(17px, 2vw, 19px)/1.7 Georgia, 'Iowan Old Style', serif; }
.essay p { margin: 0 0 1.1em; }
.essay h2, .essay h3 { font-family: var(--ui); letter-spacing: -.01em; margin: 1.6em 0 .5em; }
.essay blockquote { margin: 1.2em 0; padding-left: 1em; border-left: 3px solid var(--accent); color: var(--muted); }
.player { position: sticky; top: calc(56px + env(safe-area-inset-top)); z-index: 3; display: flex; gap: 14px; align-items: flex-start;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 12px 14px; margin-bottom: 26px; }
.player .play { flex: none; width: 46px; height: 46px; border-radius: 50%; border: 0; background: var(--accent); color: #fff; cursor: pointer; font-size: 15px; }
.pbody { flex: 1; min-width: 0; }
.pline { display: flex; justify-content: space-between; font-size: 14px; }
.ptime { font: 400 12px var(--mono); color: var(--muted); }
.pbar { height: 3px; background: var(--line); border-radius: 3px; margin: 8px 0; overflow: hidden; }
.pbar i { display: block; height: 100%; width: 0; background: var(--accent); }
.caption { font-size: 14px; color: var(--muted); line-height: 1.5; max-height: 4.5em; overflow: hidden; }
.caption:empty { display: none; }
.caption .now { color: var(--ink); background: var(--accent-soft); border-radius: 3px; }

/* ---- intro: the portal ---------------------------------------------------- */
#intro { position: fixed; inset: 0; z-index: 100; background: var(--bg); cursor: pointer; }
#intro.out .intro-word, #intro.out .intro-role { transition: opacity .5s, transform .6s; }
#intro canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.intro-word { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); white-space: nowrap;
  font: 400 clamp(22px, 5vw, 46px)/1 var(--ui); letter-spacing: .28em; color: var(--muted); padding-left: .28em; transition: opacity .4s, letter-spacing .8s; }
.intro-word b { font-weight: 700; color: var(--ink); }
.intro-word .logo { height: auto; width: min(62vw, 340px); padding: 0; }
.intro-word:has(.logo) { padding-left: 0; }
.intro-enter { position: absolute; left: 50%; bottom: calc(40px + env(safe-area-inset-bottom)); transform: translateX(-50%);
  border: 0; background: none; padding: 0; cursor: pointer; -webkit-tap-highlight-color: transparent;
  font: 600 12px var(--mono); letter-spacing: .26em; text-transform: uppercase; color: var(--ink); }
/* THE ENTER KEY. Idle: a pill whose rim is the logo's violet-to-green, turning, with a soft glow that
   breathes and an arrow that keeps nudging forward. Pressed (.go): the letters scatter, the pill
   folds down into an orb that spins up, four corner shards fly off and a shockwave rings out --
   all of it on the children, so the button's own centring transform is never touched. */
.ie-body { position: relative; display: grid; place-items: center; width: 156px; height: 46px; border-radius: 99px; overflow: hidden;
  box-shadow: 0 0 18px -4px color-mix(in srgb, var(--logo-c) 55%, transparent), 0 6px 18px -10px rgb(0 0 0 / .5);
  animation: ie-breathe 2.6s ease-in-out infinite; transition: width .38s cubic-bezier(.6,-0.3,.3,1.3), transform .18s; }
.ie-ring { position: absolute; left: 50%; top: 50%; width: 220px; height: 220px; margin: -110px 0 0 -110px;
  background: conic-gradient(from 0deg, var(--logo-c), var(--logo-o), #ffd84a, var(--logo-c) 60%, var(--logo-o), var(--logo-c));
  animation: ie-spin 3.2s linear infinite; }
.ie-face { position: absolute; inset: 2px; border-radius: inherit; display: flex; align-items: center; justify-content: center; gap: 10px;
  background: radial-gradient(120% 140% at 50% 0%, color-mix(in srgb, var(--card) 92%, var(--logo-c)), var(--card)); padding-left: .26em; }
.ie-label { display: flex; }
.ie-label b { font-weight: 600; display: inline-block; transition: transform .45s cubic-bezier(.2,.7,.3,1), opacity .3s; transition-delay: calc(var(--i) * 25ms); }
.ie-arrow { width: 16px; height: 16px; fill: none; stroke: var(--logo-c); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  animation: ie-nudge 1.3s ease-in-out infinite; transition: opacity .2s; }
.intro-enter:hover .ie-body { transform: scale(1.05); }
.intro-enter:hover .ie-ring { animation-duration: 1.2s; }
.intro-enter:active .ie-body { transform: scale(.94); }
.ie-shard { position: absolute; left: 50%; top: 50%; width: 12px; height: 12px; margin: -6px 0 0 -6px; opacity: 0; pointer-events: none;
  border: solid var(--logo-o); border-width: 3px 3px 0 0; border-radius: 0 4px 0 0; transform: rotate(var(--a)) translate(0, 0); }
.ie-wave { position: absolute; left: 50%; top: 50%; width: 46px; height: 46px; margin: -23px 0 0 -23px; border-radius: 50%; opacity: 0; pointer-events: none;
  border: 2px solid var(--logo-c); }
@keyframes ie-spin { to { transform: rotate(360deg); } }
@keyframes ie-breathe { 50% { box-shadow: 0 0 30px -2px color-mix(in srgb, var(--logo-o) 55%, transparent), 0 6px 18px -10px rgb(0 0 0 / .5); } }
@keyframes ie-nudge { 50% { transform: translateX(4px); } }
/* pressed */
.intro-enter.go .ie-label b { opacity: 0; transform: translate(calc((var(--i) - 2) * 9px), -22px) rotate(calc((var(--i) - 2) * 25deg)); }
.intro-enter.go .ie-arrow { opacity: 0; }
.intro-enter.go .ie-body { width: 46px; animation: ie-pop .6s .3s ease-out forwards; }
.intro-enter.go .ie-ring { animation-duration: .35s; }
.intro-enter.go .ie-face { background: radial-gradient(circle, color-mix(in srgb, var(--logo-o) 70%, #fff), var(--logo-c)); transition: background .3s .2s; }
.intro-enter.go .ie-shard { animation: ie-shard .55s .32s cubic-bezier(.2,.8,.3,1) forwards; }
.intro-enter.go .ie-wave { animation: ie-wave .7s .34s ease-out forwards; }
@keyframes ie-pop { 0% { transform: scale(1); } 30% { transform: scale(1.25); } 100% { transform: scale(0); opacity: 0; } }
@keyframes ie-shard { 0% { opacity: 1; transform: rotate(var(--a)) translate(0, -10px); } 100% { opacity: 0; transform: rotate(var(--a)) translate(0, -70px) scale(.6); } }
@keyframes ie-wave { 0% { opacity: .9; transform: scale(.6); } 100% { opacity: 0; transform: scale(4.2); border-width: 1px; } }
@media (prefers-reduced-motion: reduce) { .ie-ring, .ie-body, .ie-arrow { animation: none !important; } }
#intro.out { pointer-events: none; }
#intro.out .intro-word { opacity: 0; transform: translate(-50%, -50%) scale(.92); }
#intro.out .intro-enter { opacity: 0; transition: opacity .3s .8s; }

/* ---- mini-Colin ----------------------------------------------------------- */
#mini { position: fixed; right: calc(8px + env(safe-area-inset-right)); bottom: calc(6px + env(safe-area-inset-bottom)); z-index: 30;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px; pointer-events: none; transition: opacity .6s; }
#mini.loading { opacity: 0; }
#mini > * { pointer-events: auto; }
.mini-body { position: relative; width: 120px; height: 170px; border: 0; padding: 0; background: none; cursor: pointer; }
.mini-body canvas { width: 100%; height: 100%; display: block; }
.mini-tag { position: absolute; left: 50%; bottom: 2px; transform: translateX(-50%); font: 500 10px var(--mono); letter-spacing: .14em;
  text-transform: uppercase; background: var(--sheet); border: 1px solid var(--line); border-radius: 99px; padding: 3px 8px; white-space: nowrap; }
#mini.open .mini-tag { background: var(--accent); color: #fff; border-color: transparent; }
.mini-panel { width: min(340px, calc(100vw - 20px)); background: var(--card); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 20px 50px -20px rgba(0,0,0,.35); overflow: hidden; }
.mini-log { max-height: 34svh; overflow: auto; padding: 12px 14px 4px; font-size: 14.5px; }
.mini-log p { margin: 0 0 10px; }
.mini-log .you { text-align: right; color: var(--muted); }
.mini-log .him::before { content: 'Colin  '; font: 600 11px var(--mono); color: var(--accent-ink); letter-spacing: .08em; }
.mini-log .thinking { opacity: .6; }
.mini-ask { display: flex; gap: 6px; padding: 8px; border-top: 1px solid var(--line); }
.mini-ask input { flex: 1; min-width: 0; border: 1px solid var(--line); border-radius: 99px; padding: 9px 13px; background: var(--sheet);
  color: var(--ink); font: inherit; font-size: 16px; }
.mini-ask button { flex: none; width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--line); background: var(--sheet); cursor: pointer;
  touch-action: none; user-select: none; -webkit-user-select: none; }
.mini-mic { color: var(--accent); }
.mini-mic.on { background: var(--accent); color: #fff; animation: breathe 1s ease-in-out infinite; }
@keyframes breathe { 50% { transform: scale(1.1); } }
@media (min-width: 900px) { .mini-body { width: 160px; height: 230px; } }
@media (max-width: 640px) { body.at-home #hero { padding-bottom: calc(150px + env(safe-area-inset-bottom)); } }
#mini { transition: opacity .6s, transform .45s cubic-bezier(.2,.8,.2,1); }
body.reading #mini:not(.on) { transform: translateY(calc(100% + 20px)); }
@media (min-width: 900px) { body:not(.at-home) #view { padding-right: max(var(--gut), 190px); } }
@media (max-width: 640px) { body:not(.at-home) .mini-body { width: 84px; height: 120px; } }

/* ---- covers ----------------------------------------------------------------- */
.card.media { padding: 0; overflow: hidden; }
.card.media > :not(.cover) { margin-left: 16px; margin-right: 16px; }
.card.media > .meta { margin-bottom: 16px; }
.card.media > p:last-child { margin-bottom: 16px; }
.card .cover { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; background: var(--accent-soft); margin-bottom: 14px;
  transition: transform .5s cubic-bezier(.2,.8,.2,1); }
a.card.media:hover .cover { transform: scale(1.03); }
.card .cover.logo { display: grid; place-items: center; background: var(--bg); }
.card .cover.logo img { width: 42%; border-radius: 12px; }
.card .cover.blank { display: grid; place-items: center; font: 700 64px var(--ui); color: var(--accent-ink); }
.card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.card-head .thumb, .card-head .mono { width: 34px; height: 34px; border-radius: 9px; margin: 0; font-size: 15px; flex: none; }
.card-head h4 { margin: 0; }
.gallery { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); margin: 22px 0; }
.gallery img { width: 100%; border-radius: var(--r); border: 1px solid var(--line); }

/* ---- mini-Colin as a hands-free agent -------------------------------------- */
.mini-cap { max-width: min(300px, calc(100vw - 150px)); background: var(--card); border: 1px solid var(--line); border-radius: 14px 14px 4px 14px;
  padding: 9px 12px; font-size: 14px; line-height: 1.4; box-shadow: 0 12px 30px -16px rgba(0,0,0,.35); }
.mini-tools { display: flex; gap: 6px; }
.mini-tools button { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line); background: var(--sheet); cursor: pointer;
  font: 600 11px var(--mono); color: var(--muted); }
.mini-tools button[aria-pressed="true"] { border-color: var(--accent); color: var(--accent-ink); }
.mini-ask button[type="submit"] { color: var(--accent-ink); font-weight: 700; }
#mini[data-state="listening"] .mini-tag { background: var(--accent); color: #fff; border-color: transparent; }
#mini[data-state="listening"] .mini-tag::before { content: ''; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: #fff; margin-right: 6px; vertical-align: 1px; animation: breathe 1.2s ease-in-out infinite; }
#mini[data-state="thinking"] .mini-tag { opacity: .75; }
#mini[data-state="speaking"] .mini-tag { background: var(--ink); color: var(--sheet); border-color: transparent; }
/* (the pink glow under him while talking is gone: he stands on a real floor now, and it spilled over the keys) */

/* ---- the aisle: every section on display, no digging -------------------------- */
.aisle { margin: 0 calc(-1 * var(--gut)); }
.shelf { padding: 34px 0 10px; border-top: 1px solid var(--line); }
.shelf:first-child { border-top: 0; padding-top: 8px; }
.shelf-head { display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: 4px 16px; padding: 0 var(--gut) 16px; max-width: 1260px; }
.shelf-head > a:first-child { display: flex; align-items: baseline; gap: 10px; text-decoration: none; }
.shelf-head i { font: 400 12px var(--mono); color: var(--muted); font-style: normal; }
.shelf-head h3 { margin: 0; font: 700 clamp(26px, 4.5vw, 44px)/1 var(--ui); letter-spacing: -.03em; }
.shelf-head p { margin: 0; color: var(--muted); font-size: 15px; }
.shelf-more { font: 500 12px var(--mono); letter-spacing: .08em; text-transform: uppercase; text-decoration: none; color: var(--accent-ink); white-space: nowrap; }
@media (max-width: 640px) { .shelf-head { grid-template-columns: 1fr auto; } .shelf-head p { grid-column: 1 / -1; grid-row: 2; } }

/* a rail: one row you swipe along, the next item always peeking in from the edge */
.rail { display: flex; gap: 14px; overflow-x: auto; scroll-snap-type: x mandatory; padding: 4px var(--gut) 18px;
  scroll-padding: 0 var(--gut); scrollbar-width: none; overscroll-behavior-x: contain; }
.rail::-webkit-scrollbar { display: none; }
.rail > * { scroll-snap-align: start; flex: none; }
.tile { width: min(78vw, 400px); text-decoration: none; display: block; }
.tile .cover { width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; border-radius: var(--r); display: block;
  border: 1px solid var(--line); transition: transform .5s cubic-bezier(.2,.8,.2,1); background: var(--accent-soft); }
.tile:hover .cover { transform: translateY(-4px); }
.tile .cover.logo, .tile .cover.blank { display: grid; place-items: center; }
.tile .cover.logo img { width: 38%; border-radius: 12px; }
.tile .cover.blank { font: 700 64px var(--ui); color: var(--accent-ink); }
.tile-meta { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 10px 2px 0; }
.tile-meta b { font: 600 17px var(--ui); letter-spacing: -.01em; }
.tile-meta span { font: 400 12px var(--mono); color: var(--muted); text-align: right; }
.tile.game:first-child { width: min(88vw, 560px); }

/* the character shelf: figures standing on a floor, like a display case */
.shelf-figures { background: linear-gradient(to bottom, transparent 55%, color-mix(in srgb, var(--accent-soft) 70%, transparent)); }
.rail.figures { gap: 4px; }
.figure { width: min(44vw, 210px); text-decoration: none; display: flex; flex-direction: column; align-items: center; }
.figure img { width: 100%; aspect-ratio: 552 / 561; object-fit: contain; transition: transform .45s cubic-bezier(.2,.8,.2,1); }
.figure:hover img { transform: translateY(-8px) scale(1.04); }
.figure .tile-meta { flex-direction: column; align-items: center; gap: 2px; padding-top: 0; }
.figure .tile-meta span { text-align: center; }

.shelf .wall { padding: 0 var(--gut); max-width: 1260px; }
.essay-card { width: min(84vw, 520px); display: flex; flex-direction: column; gap: 10px; text-decoration: none; padding: 22px;
  border-radius: var(--r); background: var(--card); border: 1px solid var(--line); }
.essay-card .kicker { font: 500 11px var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--accent-ink); }
.essay-card b { font: 700 clamp(24px, 3.4vw, 34px)/1.05 var(--ui); letter-spacing: -.02em; }
.essay-card q { font: 400 18px/1.5 Georgia, serif; color: var(--muted); }
.tile.script { width: min(70vw, 300px); }
.tile.script .glyph { aspect-ratio: 16 / 10; display: grid; place-items: center; border-radius: var(--r); background: var(--ink); color: var(--accent);
  font: 500 52px var(--mono); }

.rail.strip img { height: min(46vw, 260px); width: auto; border-radius: 10px; }
.marquee { overflow: hidden; padding: 6px 0 22px; mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.marquee > div { display: flex; gap: 16px; width: max-content; animation: marquee 60s linear infinite; }
.marquee img { height: 72px; width: 72px; border-radius: 14px; object-fit: cover; }
@keyframes marquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .marquee > div { animation: none; } }
.about-shelf { padding: 34px var(--gut) 0; max-width: 1260px; }
.about-shelf a { text-decoration: none; }
.about-shelf h3 { margin: 0 0 8px; font: 700 clamp(26px, 4.5vw, 44px)/1 var(--ui); letter-spacing: -.03em; }
.about-shelf p { max-width: 58ch; color: var(--muted); font-size: 17px; }

/* ---- the swarm stage: the aisle floats over it --------------------------------- */
body.swarm #labels { display: none; }
body.swarm #globe { cursor: default; }
body.swarm.at-home #view { background: transparent; border-top-color: transparent; box-shadow: none; }
body.swarm.at-home .shelf-figures { background: linear-gradient(to bottom, transparent 55%, color-mix(in srgb, var(--accent-soft) 45%, transparent)); }
@media (min-aspect-ratio: 6/5) { body.swarm.at-home .aisle { margin-right: 26vw; } body.swarm.at-home .shelf .wall { max-width: none; } }

/* ---- about ------------------------------------------------------------------ */
#about-hero { position: relative; height: min(78svh, 720px); margin: 0 calc(-1 * var(--gut)) 10px; overflow: hidden; }
.about-slot { position: absolute; inset: 0; display: flex; justify-content: center; align-items: flex-end; z-index: 2; pointer-events: none; }
.about-orbit { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.about-orbit.back { z-index: 1; }
.about-web { position: absolute; inset: 0; width: 100%; height: 100%; }
.about-web line { stroke: var(--accent); stroke-width: 1; }
.orb-chip { position: absolute; left: 0; top: 0; pointer-events: auto; white-space: nowrap; text-decoration: none; will-change: transform, opacity;
  font: 500 12px var(--mono); letter-spacing: .08em; text-transform: uppercase; padding: 7px 12px; border-radius: 99px;
  background: color-mix(in srgb, var(--card) 88%, transparent); border: 1px solid var(--line); backdrop-filter: blur(4px); }
.orb-chip:hover { border-color: var(--accent); color: var(--accent-ink); }
.about-talk { position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 4; }
#mini.hero { position: static; width: 100%; height: 100%; pointer-events: none; align-items: center; justify-content: flex-end; }
#mini.hero .mini-body { width: min(100%, 460px); height: 100%; pointer-events: auto; }
#mini.hero .mini-tag { bottom: 70px; }
/* on the stage his captions are a speech bubble above his head, in the Talk bubble's style (colin.js places it) */
#mini.hero .mini-cap { position: absolute; top: 0; left: 0; transform: none; z-index: 5; pointer-events: none; max-width: min(300px, 78vw);
  padding: 10px 14px 11px; border-radius: 18px; border: 2px solid var(--accent); background: var(--card); color: var(--ink);
  font: 600 14px/1.35 var(--ui); box-shadow: 0 5px 0 -1px color-mix(in srgb, var(--accent) 45%, transparent), 0 14px 28px -12px rgb(0 0 0 / .5); }
#mini.hero .mini-cap::after { content: ''; position: absolute; left: 42%; bottom: -11px; width: 16px; height: 14px; background: var(--card);
  border-right: 2px solid var(--accent); border-bottom: 2px solid var(--accent); transform: skewX(-30deg) rotate(10deg); border-bottom-right-radius: 4px; }
#mini.hero .mini-cap.you { font-weight: 500; font-style: italic; color: var(--muted); border-style: dashed; }
#mini.hero .mini-panel, #mini.hero .mini-tools { position: absolute; right: var(--gut); bottom: 70px; z-index: 5; pointer-events: auto; }
#mini.hero .mini-tools { bottom: 18px; }
.about .about-more { max-width: 60ch; color: var(--muted); font-size: 17px; }
.thoughts { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.thought { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 20px; }
.thought b { font: 700 24px/1.1 var(--ui); letter-spacing: -.02em; display: block; margin-bottom: 8px; }
.thought q { font: 400 17px/1.5 Georgia, serif; color: var(--muted); }

/* ---- audio ------------------------------------------------------------------- */
.player-big { display: flex; gap: 16px; align-items: center; background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 16px; }
.pb-play { flex: none; width: 64px; height: 64px; border-radius: 50%; border: 0; background: var(--accent); color: #fff; font-size: 20px; cursor: pointer; }
.pb-body { flex: 1; min-width: 0; }
.pb-now { display: flex; gap: 10px; align-items: baseline; } .pb-now b { font: 600 18px var(--ui); } .pb-now span { font: 400 12px var(--mono); color: var(--muted); }
.pb-bars { width: 100%; height: 64px; display: block; margin: 8px 0 4px; }
.tracks { list-style: none; padding: 0; margin: 14px 0 0; border-top: 1px solid var(--line); }
.tracks button { width: 100%; display: grid; grid-template-columns: 2.4em 1fr auto; gap: 10px; align-items: baseline; text-align: left;
  background: none; border: 0; border-bottom: 1px solid var(--line); padding: 12px 4px; cursor: pointer; }
.tracks i { font: 400 12px var(--mono); color: var(--muted); font-style: normal; } .tracks b { font-weight: 600; } .tracks span { font: 400 12px var(--mono); color: var(--muted); }
.tracks button.on { color: var(--accent-ink); } .tracks button:hover { background: var(--accent-soft); }
.sfx-filters .pill { cursor: pointer; background: none; }
.sfx-grid { display: grid; gap: 8px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.pad { position: relative; display: flex; border: 1px solid var(--line); border-radius: 12px; background: var(--card); overflow: hidden; }
.pad-play { flex: 1; min-width: 0; text-align: left; background: none; border: 0; padding: 14px 12px; cursor: pointer; display: flex; flex-direction: column; gap: 3px; }
.pad-play b { font-weight: 600; font-size: 14px; text-transform: capitalize; } .pad-play span { font: 400 10px var(--mono); color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
.pad-dl { flex: none; width: 38px; display: grid; place-items: center; border-left: 1px solid var(--line); text-decoration: none; color: var(--accent-ink); font-weight: 700; }
.pad.hit { animation: padhit .35s ease-out; } @keyframes padhit { 0% { background: var(--accent); } 100% { background: var(--card); } }
.tile.song { border: 0; background: none; padding: 0; text-align: left; cursor: pointer; width: min(56vw, 240px); font: inherit; color: inherit; }
.song-art { aspect-ratio: 1; border-radius: var(--r); background: radial-gradient(circle at 30% 30%, var(--accent), var(--accent-deep)); display: grid; place-items: center; }
.song-art span { width: 52px; height: 52px; border-radius: 50%; background: rgba(255,255,255,.9); color: var(--accent-deep); display: grid; place-items: center; font-size: 18px; }
#mini.hero { transform: none !important; right: auto; bottom: auto; }
#mini.hero[data-state="off"] .mini-tag { display: none; }
#mini [hidden] { display: none !important; }

/* ---- the logo (his SVG, recoloured by the theme) ---------------------------- */
.logo { display: block; height: 30px; width: auto; color: var(--ink); }
.logo .frame { display: none; }
.logo.big { height: auto; width: min(78vw, 460px); margin: 0 auto; }
.logo.big .frame { display: inline; }
#hero h1 { line-height: 0; }

/* ---- the hero is Glorb: the real one, embedded, and swiping him is the nav --- */
#glorb { display: none; }
body.has-glorb #glorb { display: block; position: fixed; left: 0; right: 0; top: 0; bottom: calc(64px + env(safe-area-inset-bottom)); z-index: 1; transition: opacity .5s; }
body.has-glorb.at-home { background: var(--bg); }
body.has-glorb.scrolled #glorb { opacity: .3; }
#glorb { background: var(--bg); overflow: hidden; }
#glorb canvas.glorb-c { display: block; width: 100%; height: 100%; touch-action: pan-y; }
#glorb canvas.glorb-gl { position: fixed; left: 0; top: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
/* the intro is HIS field at full screen; Enter lets the frame fall to the top of the page */
body.has-glorb #glorb { transition: height .95s cubic-bezier(.65, 0, .25, 1), opacity .5s; }
body.intro-on { overflow: hidden; }
body.has-glorb.at-home #stage { display: none; }
/* the aisle is a solid sheet: content floating over particles was the mess */
body.has-glorb.at-home #view { background: var(--sheet); border-top-color: var(--line); box-shadow: 0 -30px 60px -40px rgba(0,0,0,.25); }
@media (min-aspect-ratio: 6/5) { body.has-glorb.at-home .aisle { margin-right: 0; } }
body.has-glorb.at-home .shelf-figures { background: none; }
body.has-glorb #hero { padding-bottom: calc(18px + env(safe-area-inset-bottom)); }
@media (max-width: 640px) { body.has-glorb.at-home #hero { padding-bottom: calc(18px + env(safe-area-inset-bottom)); } }

/* ---- the deck: cassette push keys on a bar, Colin walks on top of it -------- */
:root { --deck: 58px; }
#deck { position: fixed; left: 0; right: 0; bottom: 0; z-index: 25; height: calc(var(--deck) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: color-mix(in srgb, var(--sheet) 92%, transparent); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-top: 1px solid var(--line); box-shadow: 0 -1px 0 color-mix(in srgb, #fff 6%, transparent) inset; }
#deck::before { /* the ledge he stands on: a lit top edge, the one hint of depth in a flat bar */
  content: ''; position: absolute; left: 0; right: 0; top: -1px; height: 4px; pointer-events: none;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--ink) 10%, transparent), transparent); }
.deck-keys { height: 100%; display: flex; align-items: center; gap: 6px; padding: 0 var(--gut); overflow-x: auto;
  scrollbar-width: none; justify-content: safe center;
  -webkit-mask: linear-gradient(90deg, transparent, #000 var(--gut), #000 calc(100% - var(--gut)), transparent); }
.deck-keys::-webkit-scrollbar { display: none; }
.key { --kc: var(--card); flex: none; position: relative; min-width: 58px; height: 40px; border-radius: 7px; text-decoration: none;
  display: flex; flex-direction: column; justify-content: space-between; padding: 6px 9px 5px; box-sizing: border-box;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--kc) 100%, #fff 6%), var(--kc));
  border: 1px solid var(--line); color: var(--muted);
  box-shadow: 0 4px 0 color-mix(in srgb, var(--line) 80%, #000 20%), 0 5px 6px -2px rgba(0,0,0,.25);
  transform: translateY(-3px); transition: transform .09s ease-out, box-shadow .09s ease-out, color .2s;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none; }
.key i { font: 500 8px/1 var(--mono); letter-spacing: .08em; font-style: normal; opacity: .7; }
.key b { font: 600 9.5px/1 var(--mono); letter-spacing: .06em; padding-right: 8px; text-transform: uppercase; color: var(--ink); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.key::after { /* the latch lamp */ content: ''; position: absolute; right: 7px; top: 7px; width: 5px; height: 5px; border-radius: 50%;
  background: var(--line); transition: background .15s, box-shadow .15s; }
.key.down { transform: translateY(1px); box-shadow: 0 0 0 color-mix(in srgb, var(--line) 80%, #000 20%), 0 1px 2px rgba(0,0,0,.2); }
.key.in { transform: translateY(0); box-shadow: 0 1px 0 color-mix(in srgb, var(--line) 80%, #000 20%), inset 0 2px 4px rgba(0,0,0,.18);
  --kc: color-mix(in srgb, var(--card) 88%, var(--accent)); }
.key.in::after { background: var(--accent); box-shadow: 0 0 6px var(--accent); }
.key.in.down { transform: translateY(1px); }
@media (min-width: 720px) { .key { min-width: 84px; height: 44px; } .key b { font-size: 10.5px; } }

/* content clears the bar; Glorb stops above it */
#view { padding-bottom: calc(80px + var(--deck) + env(safe-area-inset-bottom)); }
body.has-glorb #glorb { bottom: calc(var(--deck) + env(safe-area-inset-bottom)); }

/* Colin stands ON the bar. Horizontal position is his, set in JS. */
#mini:not(.hero) { left: 0; right: auto; bottom: calc(var(--deck) + env(safe-area-inset-bottom) - 12px); align-items: flex-start;
  transition: opacity .6s; }
body.reading #mini:not(.on) { transform: none; }
#mini:not(.hero) .mini-body { width: 96px; height: 136px; }
@media (min-width: 900px) { #mini:not(.hero) .mini-body { width: 120px; height: 170px; } }
#mini[data-state="off"] .mini-tag { display: none; }
#mini.away { pointer-events: none; }
.mini-bubble { position: relative; margin: 0 0 4px 30px; max-width: 220px; background: var(--card); border: 1px solid var(--line);
  border-radius: 14px 14px 14px 4px; padding: 10px 12px; font-size: 13.5px; line-height: 1.35;
  box-shadow: 0 8px 24px -12px rgba(0,0,0,.35); animation: bub .35s cubic-bezier(.2,1.4,.3,1); transform-origin: 0 100%; }
.mini-bubble p { margin: 0 0 8px; }
.mini-bubble div { display: flex; gap: 6px; }
.mini-bubble button { border: 1px solid var(--line); background: var(--sheet); border-radius: 7px; padding: 5px 12px; cursor: pointer;
  font: 600 11px var(--mono); letter-spacing: .1em; text-transform: uppercase; }
.mini-bubble .mini-yes { background: var(--accent); color: #fff; border-color: transparent; }
@keyframes bub { from { transform: scale(.6); opacity: 0; } to { transform: none; opacity: 1; } }
#mini.rside:not(.hero) { align-items: flex-end; }
#mini.rside .mini-bubble { margin: 0 30px 4px 0; border-radius: 14px 14px 4px 14px; transform-origin: 100% 100%; }

/* what he is, said plainly: top of the home page, under the header */
#hero .role { display: none; }
body.has-glorb #hero { top: calc(62px + env(safe-area-inset-top)); bottom: auto; padding: 0; }
body.has-glorb #hero .role { display: block; margin: 0; font: 600 11px/1 var(--mono); letter-spacing: .26em; text-transform: uppercase;
  color: var(--muted); }
.intro-role { position: absolute; left: 50%; top: calc(50% + min(15vw, 84px)); transform: translateX(-50%); white-space: nowrap;
  font: 600 clamp(10px, 2.6vw, 13px)/1 var(--mono); letter-spacing: .3em; text-transform: uppercase; color: var(--muted);
  transition: opacity .4s; }
#intro.out .intro-role { opacity: 0; }
.intro-me { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 101; pointer-events: none; opacity: 0; }
.intro-me.on { opacity: 1; }
#intro.walk .intro-word, #intro.walk .intro-role { opacity: 0; transition: opacity .5s .35s; }
#intro.walk .intro-enter { opacity: 0; transition: opacity .3s .85s; }

/* ---- physical page travel (View Transitions) ---------------------------------- */
#hud { view-transition-name: hud; }
::view-transition-group(hud) { animation: none; z-index: 5; }
::view-transition-old(hud) { display: none; }
::view-transition-new(hud) { animation: none; }
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: .56s; animation-timing-function: cubic-bezier(.65, 0, .25, 1); animation-fill-mode: both; mix-blend-mode: normal; }
html[data-vt="right"]::view-transition-old(root) { animation-name: vt-out-l; }
html[data-vt="right"]::view-transition-new(root) { animation-name: vt-in-r; }
html[data-vt="left"]::view-transition-old(root)  { animation-name: vt-out-r; }
html[data-vt="left"]::view-transition-new(root)  { animation-name: vt-in-l; }
html[data-vt="in"]::view-transition-old(root)    { animation-name: vt-past; }
html[data-vt="in"]::view-transition-new(root)    { animation-name: vt-arrive; }
html[data-vt="out"]::view-transition-old(root)   { animation-name: vt-shrink; }
html[data-vt="out"]::view-transition-new(root)   { animation-name: vt-return; }
@keyframes vt-out-l { to { transform: translateX(-38%) scale(.9); opacity: 0; } }
@keyframes vt-out-r { to { transform: translateX(38%) scale(.9); opacity: 0; } }
@keyframes vt-in-r { from { transform: translateX(38%) scale(.9); opacity: 0; } }
@keyframes vt-in-l { from { transform: translateX(-38%) scale(.9); opacity: 0; } }
@keyframes vt-past { to { transform: scale(1.14); opacity: 0; } }
@keyframes vt-arrive { from { transform: scale(.86); opacity: 0; } }
@keyframes vt-shrink { to { transform: scale(.86); opacity: 0; } }
@keyframes vt-return { from { transform: scale(1.14); opacity: 0; } }
body.has-glorb #glorb { bottom: auto; height: calc(var(--band) + 24px); }
.intro-front { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 102; pointer-events: none; }

/* ---- the strip lives IN the page: the seam between Glorb and the content ----------
   It is the top edge of the content sheet, Colin stands on it, and on the home
   page it is Glorb's floor (see GLORB_FLOOR in app.js). */
body #deck { position: relative; left: auto; right: auto; bottom: auto; z-index: 12; height: var(--deck); padding-bottom: 0;
  margin-top: var(--band); border-radius: 22px 22px 0 0; background: var(--sheet); border-top: 1px solid var(--line);
  box-shadow: 0 -30px 60px -40px rgba(0,0,0,.25); backdrop-filter: none; -webkit-backdrop-filter: none; }
body.at-home #deck { margin-top: 100svh; }
body.has-glorb.at-home #deck { margin-top: var(--band); }
body.no-globe.at-home #deck { margin-top: 60svh; }
html body #view, html body.at-home #view, html body.has-glorb.at-home #view, html body.no-globe.at-home #view {
  margin-top: 0; border-top: 0; border-radius: 0; box-shadow: none; padding-bottom: calc(80px + env(safe-area-inset-bottom)); }
/* Glorb holds the whole screen behind the page; the strip is what pushes him off it */
body.has-glorb #glorb, body.has-glorb.scrolled #glorb { top: 0; bottom: auto; height: 100svh; opacity: 1; }
#mini:not(.hero) { position: absolute; left: 0; bottom: calc(100% - 12px); }

/* the home page's head: the strip is fixed under Glorb and the shelves scroll beneath both */
body.home-head #deck { position: fixed; left: 0; right: 0; margin-top: 0 !important; top: var(--band); }
body.home-head #glorb { z-index: 11; }
body.home-head #view { margin-top: calc(var(--band) + var(--deck)) !important; }
/* Glorb is the stage on every page now; the old particle band stays only as the ?noglorb fallback */
body.has-glorb #stage { display: none; }
/* his bubble floats above him and never pushes him about */
#mini .mini-bubble { position: absolute; bottom: calc(100% + 4px); left: 0; width: 220px; margin: 0; }
#mini.rside .mini-bubble { left: auto; right: 0; }

/* ---- games wear their app icons ------------------------------------------------ */
.tile.game { width: min(38vw, 180px); }
.tile .cover.app, .card .cover.app { aspect-ratio: 1; object-fit: cover; border-radius: 22.5%; width: 100%; height: auto;
  box-shadow: 0 10px 24px -14px rgba(0,0,0,.55), inset 0 0 0 1px rgba(255,255,255,.06); }
.cover.app.blank { display: grid; place-items: center; font: 700 56px var(--ui); color: var(--accent-ink); background: var(--accent-soft); }
.card.media .cover.app { width: 46%; margin: 16px 16px 12px; }
.grid:has(.cover.app) { grid-template-columns: repeat(auto-fill, minmax(min(46%, 260px), 1fr)); }

/* ---- a STAGE page (About): the first screen is the whole show ------------------
   The strip sits at the foot of the screen, Colin stands on it centre stage, and
   Glorb fills everything behind him. The page itself starts below the strip. */
/* the strip lands about three-quarters down, not at the very foot: the page below peeks in,
   so it is plain there is more to read */
body.stage-page { --stage-h: 76svh; }
body.stage-page #deck { margin-top: calc(var(--stage-h) - var(--deck)); }
body.stage-page #about-hero { position: absolute; left: 0; right: 0; margin: 0; bottom: calc(100% + var(--deck));
  height: calc(var(--stage-h) - var(--deck)); overflow: visible; z-index: 13; pointer-events: none; }
body.stage-page .about-slot { transform: translateY(6px); }
body.stage-page #mini.hero .mini-body { width: min(100%, 560px); }
/* TALK TO ME is a speech bubble beside his head, following it (mountAbout places it each frame) */
body.stage-page .about-talk { left: 0; top: 0; bottom: auto; right: auto; transform: none; pointer-events: auto; visibility: hidden; }
.about-talk.bubble { all: unset; position: absolute; z-index: 4; cursor: pointer; padding: 10px 16px 11px; border-radius: 20px;
  font: 650 15px/1 var(--ui); letter-spacing: .01em; color: var(--ink); white-space: nowrap;
  background: var(--card); border: 2px solid var(--accent); box-shadow: 0 6px 0 -1px color-mix(in srgb, var(--accent) 45%, transparent), 0 14px 28px -12px rgb(0 0 0 / .5);
  animation: talkbob 2.6s ease-in-out infinite; transform-origin: 0% 100%; }
.about-talk.bubble::after { content: ''; position: absolute; left: 14px; bottom: -11px; width: 16px; height: 14px; background: var(--card);
  border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent); transform: skewY(-35deg) rotate(-12deg); border-bottom-left-radius: 4px; }
.about-talk.bubble.on { background: var(--accent); color: var(--on-accent, #fff); }
.about-talk.bubble.on::after { background: var(--accent); }
.about-talk.bubble.on::before { content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 8px; vertical-align: 1px;
  background: currentColor; animation: talkdot 1s ease-in-out infinite; }
.about-talk.bubble:active { scale: .94; }
@keyframes talkbob { 0%, 100% { translate: 0 0; rotate: -2deg; } 50% { translate: 0 -5px; rotate: 1deg; } }
@keyframes talkdot { 50% { opacity: .3; } }
.tile.game:first-child { width: min(38vw, 180px); }

/* ---- the weave: woven bands behind Glorb (site/weave.js) --------------------------
   Laid OVER his canvas with lighten, so any particle brighter than the cloth
   wins; in the light theme it darkens instead. */
#glorb canvas.weave { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; mix-blend-mode: lighten; }
#glorb canvas.weave.light { mix-blend-mode: multiply; }
.key { justify-content: center; }   /* just the name now, no number above it */
.tile.game .tile-meta { flex-direction: column; align-items: flex-start; gap: 3px; } .tile.game .tile-meta b { font-size: 15px; line-height: 1.15; } .tile.game .tile-meta span { text-align: left; font-size: 11px; }

/* ---- a page change moves the CONTENT, never the stage ------------------------------
   Glorb, the strip (with Colin standing on it) and the header each get their own
   transition layer, shown live and not animated, so they stay exactly where they
   are while Glorb re-forms; if the strip sits at a different height on the new
   page it glides there. Only #view -- the content sheet -- pans or zooms. */
#glorb { view-transition-name: glorb; }
#deck { view-transition-name: deck; }
#view { view-transition-name: view; }
::view-transition-old(glorb), ::view-transition-old(deck) { display: none; }
::view-transition-new(glorb), ::view-transition-new(deck) { animation: none; }
::view-transition-group(glorb) { animation: none; z-index: 1; }
::view-transition-group(deck) { z-index: 4; animation-duration: .5s; animation-timing-function: cubic-bezier(.3,.8,.2,1); }
::view-transition-group(view) { z-index: 2; animation: none; }
html[data-vt]::view-transition-old(root), html[data-vt]::view-transition-new(root) { animation: none; }
::view-transition-old(view), ::view-transition-new(view) { animation-duration: .5s; animation-timing-function: cubic-bezier(.3,.8,.2,1); }
html[data-vt="right"]::view-transition-old(view) { animation-name: vt-out-l; }
html[data-vt="right"]::view-transition-new(view) { animation-name: vt-in-r; }
html[data-vt="left"]::view-transition-old(view)  { animation-name: vt-out-r; }
html[data-vt="left"]::view-transition-new(view)  { animation-name: vt-in-l; }
html[data-vt="in"]::view-transition-old(view)    { animation-name: vt-past; }
html[data-vt="in"]::view-transition-new(view)    { animation-name: vt-arrive; }
html[data-vt="out"]::view-transition-old(view)   { animation-name: vt-shrink; }
html[data-vt="out"]::view-transition-new(view)   { animation-name: vt-return; }
#mini { view-transition-name: colin; }
::view-transition-old(colin) { display: none; }
::view-transition-new(colin) { animation: none; }
::view-transition-group(colin) { z-index: 5; animation-duration: .6s; animation-timing-function: cubic-bezier(.3,.8,.2,1); }

/* ---- graffiti keys: his lettering on the key face -------------------------------- */
:root { --deck: 68px; }
.key.art { height: 52px; padding: 3px 7px; justify-content: center; align-items: center; }
.key.art img { height: 44px; width: auto; display: block; pointer-events: none; user-select: none; -webkit-user-drag: none;
  filter: saturate(.9) brightness(.9); transition: filter .2s, transform .12s; }
.key.art.in img { filter: none; transform: scale(1.04); }
.key.art::after { top: 5px; right: 5px; }
.key:not(.art) { height: 52px; }

/* ---- lettered keys: his words as stencils (replaces the graffiti art) ---------------- */
:root { --deck: 58px; }
.key.art, .key:not(.art) { height: 40px; }
.key.art { padding: 0 13px; justify-content: center; align-items: center; }
.key.art .gw { display: block; transition: filter .25s; }
.key.art .glyph { display: block; height: 17px; aspect-ratio: var(--ar); background: color-mix(in srgb, var(--ink) 58%, transparent);
  -webkit-mask: var(--art) center / contain no-repeat; mask: var(--art) center / contain no-repeat; transition: background .25s, transform .15s; }
.key.art:hover .glyph { background: color-mix(in srgb, var(--ink) 85%, transparent); }
.key.art.in .glyph { background: var(--accent); transform: scale(1.05); }
.key.art.in .gw { filter: drop-shadow(0 0 5px color-mix(in srgb, var(--accent) 70%, transparent)); }
/* assets: each card shows the character itself */
.card .char-shot { display: block; width: 100%; aspect-ratio: 552 / 561; object-fit: contain; margin: -6px 0 8px;
  background: radial-gradient(ellipse at 50% 60%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 70%); border-radius: 12px; }
.grid:has(.char-shot) { grid-template-columns: repeat(auto-fill, minmax(min(46%, 260px), 1fr)); }

/* ---- the floor he stands on (About stage) -----------------------------------------
   A neon disc, not a box: a pool of Glorb's violet light on the ground, two glowing
   elliptical rings (a ground plane seen from just above), and a dark contact
   shadow right under his feet, which is what actually makes him stand ON it. */
.about-floor { display: none; }
body.stage-page .about-floor { display: block; position: absolute; left: 50%; bottom: 0; width: min(78vw, 440px);
  aspect-ratio: 4 / 1; transform: translate(-50%, 42%); z-index: 1; pointer-events: none; }
.about-floor i { position: absolute; inset: 0; border-radius: 50%; }
.about-floor .pool { background: radial-gradient(closest-side, rgba(170, 60, 255, .42), rgba(170, 60, 255, .14) 55%, transparent 100%);
  filter: blur(6px); animation: floor-breathe 5s ease-in-out infinite; }
.about-floor .ring { inset: 6% 3%; border: 1.5px solid #c27bff;
  box-shadow: 0 0 10px #a94dff, 0 0 26px rgba(169, 77, 255, .55), inset 0 0 12px rgba(169, 77, 255, .5); }
.about-floor .ring.r2 { inset: 26% 22%; border-color: #8dff72; opacity: .75;
  box-shadow: 0 0 8px #6ee05a, 0 0 18px rgba(110, 224, 90, .45); animation: floor-breathe 5s ease-in-out infinite reverse; }
.about-floor .shadow { inset: 30% 30% 34%; background: radial-gradient(closest-side, rgba(0,0,0,.75), rgba(0,0,0,0)); }
@keyframes floor-breathe { 50% { opacity: .65; transform: scale(1.03); } }
@media (prefers-reduced-motion: reduce) { .about-floor i { animation: none !important; } }
/* he stands on the disc, so the stage leaves room under his feet for all of it */
body.stage-page .about-slot { inset: 0 0 44px 0; transform: none; }
body.stage-page .about-floor { bottom: 44px; transform: translate(-50%, 50%); }
body.stage-page .about-floor { bottom: calc(44px + 0.085 * (100% - 44px)); }
/* About: Colin back at his original size and spot; the floor fitted under his feet there */
body.stage-page .about-slot { inset: 0; transform: translateY(6px); }
body.stage-page .about-floor { bottom: calc(0.085 * 100% - 6px); aspect-ratio: 5 / 1; transform: translate(-50%, 50%); }
/* backdrops behind Glorb fade between sections */
#glorb canvas.weave { transition: opacity .7s ease; }
#glorb canvas.weave.off { opacity: 0; }

/* ---- About: a GROUND PLANE, not rings ----------------------------------------------
   A flat floor he stands on: it starts at a soft horizon a little above his feet and
   runs to the strip, opaque enough that the pattern stops where the floor begins (so
   nothing intersects him), lit by a faint violet pool under him, with a dark contact
   shadow at his soles. */
body.stage-page .about-floor { left: 0; right: 0; width: auto; aspect-ratio: auto; transform: none; bottom: 0;
  height: calc(0.085 * 100% + 34px); }
.about-floor .plane { inset: 0; border-radius: 0;
  background: linear-gradient(to bottom, transparent 0, color-mix(in srgb, var(--bg) 70%, transparent) 26%, var(--bg) 70%);
  border-top: 0; }
.about-floor .plane::before { content: ''; position: absolute; left: 6%; right: 6%; top: 26%; height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, #a94dff 55%, transparent), transparent); }
.about-floor .pool { inset: 18% 14% -10%; border-radius: 50%; filter: blur(14px); animation: none;
  background: radial-gradient(closest-side, rgba(169, 77, 255, .28), rgba(169, 77, 255, .08) 60%, transparent); }
.about-floor .shadow { inset: auto 34% calc(0.085 * 100% * 0 + 22px); height: 18px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(0,0,0,.7), transparent); }
/* and he stands a little smaller on the stage */
body.stage-page .about-slot { inset: 22% 0 0 0; }
/* while the little Colin on the strip is a bit bigger */
#mini:not(.hero) .mini-body { width: 118px; height: 168px; }
@media (min-width: 900px) { #mini:not(.hero) .mini-body { width: 146px; height: 208px; } }

/* ---- Characters: the line-up behind, thumbnails and the picked one below ------------ */
#glorb canvas.lineup { position: absolute; left: 0; top: 0; width: 100%; height: 55%; z-index: 2; touch-action: pan-y; transition: opacity .7s ease; }
#glorb canvas.lineup.off { opacity: 0; pointer-events: none; }
#glorb canvas.weave.dim { opacity: .4; }
.char-thumbs { display: flex; gap: 8px; overflow-x: auto; padding: 4px 2px 10px; margin: 6px calc(-1 * var(--gut)) 0; padding-inline: var(--gut);
  scrollbar-width: none; }
.char-thumbs::-webkit-scrollbar { display: none; }
.char-thumbs button { flex: none; width: 74px; border: 1px solid var(--line); background: var(--card); border-radius: 14px; padding: 4px 4px 6px;
  color: var(--muted); font: 600 10px/1.15 var(--ui); cursor: pointer; transition: border-color .2s, transform .15s, color .2s; }
.char-thumbs button img { display: block; width: 100%; aspect-ratio: 1; object-fit: contain; }
.char-thumbs button span { display: block; margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.char-thumbs button.on { border-color: var(--accent); color: var(--ink); transform: translateY(-2px);
  box-shadow: 0 0 0 1px var(--accent), 0 8px 22px -12px var(--accent); }
.char-detail { display: grid; grid-template-columns: minmax(110px, 38%) 1fr; gap: 14px; align-items: center; margin: 6px 0 18px; }
.char-detail:not(.on) { display: block; }
.char-detail .char-shot { width: 100%; margin: 0; }
.char-detail h3 { margin: 0; font: 700 24px/1.1 var(--ui); }
.char-detail .from { margin: 2px 0 8px; color: var(--muted); font-size: 13px; }
.char-detail .notes { color: var(--muted); font-size: 13px; }
.char-detail .row { flex-wrap: wrap; gap: 8px; }

/* ---- the strip is a SLAB: its top face ---------------------------------------------
   A flat edge gives the eye nothing to stand a foot on, so everyone stood ON a line
   and read as floating. The strip gets a top surface -- a trapezoid narrowing to the
   back, a slab seen from just above -- and the line-up, little Colin and the About
   stage all stand in the middle of it. --ledge is how deep that face looks. */
:root { --ledge: 26px; }
#deck::after { content: ''; position: absolute; left: 0; right: 0; bottom: 100%; height: var(--ledge); pointer-events: none;
  clip-path: polygon(5% 0, 95% 0, 100% 100%, 0 100%);
  background:
    linear-gradient(to bottom, color-mix(in srgb, #a94dff 55%, transparent) 0 1px, transparent 1px),     /* the lit back edge */
    linear-gradient(to bottom, color-mix(in srgb, var(--sheet) 55%, #000) 0%, color-mix(in srgb, var(--sheet) 88%, #2a1640) 100%); }
#deck { border-radius: 0; }
#mini:not(.hero) { bottom: calc(100% - 12px + var(--ledge) * .5); }
/* About: he stands on the slab too; the ground plane and its glow are gone, the contact shadow stays */
body.stage-page .about-slot { inset: 22% 0 0 0; transform: translateY(calc(10.5% - var(--ledge) * .5)); }
body.stage-page .about-floor { height: var(--ledge); bottom: 0; }
body.stage-page .about-floor .plane, body.stage-page .about-floor .pool { display: none; }
body.stage-page .about-floor .shadow { inset: auto 36% calc(var(--ledge) * .5 - 8px); height: 16px; }

/* ---- support: the buy-me-a-coffee card ---------------------------------------------- */
.support { display: flex; align-items: center; gap: 14px 18px; flex-wrap: wrap; justify-content: space-between; margin: 34px 0 6px;
  padding: 14px 16px; border: 1px solid var(--line); border-radius: 16px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 10%, var(--card)), var(--card)); }
.support b { font: 700 15px var(--ui); }
.support p { margin: 4px 0 0; color: var(--muted); font-size: 13px; max-width: 60ch; }
.support.big { padding: 20px; margin-top: 28px; }
.support.big b { font-size: 18px; }
.support.big + .foot, .wrap > .support.big + .support { display: block; }
.vidwrap { position: relative; aspect-ratio: 16 / 9; border-radius: 14px; overflow: hidden; background: #000; }
.vidwrap iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* the line-up sits ABOVE the strip (its own fixed layer), so their feet stand on the slab's top face */
canvas.lineup { position: fixed !important; left: 0; top: 0; width: 100% !important; z-index: 13; touch-action: pan-y; transition: opacity .7s ease; }
canvas.lineup.off { opacity: 0; pointer-events: none; }
/* on Characters, Colin is IN the line-up, so the little one on the strip steps out */
body.colin-in-line #mini:not(.hero) { opacity: 0; pointer-events: none; transition: none; }

/* ---- THE STAGE: a box Glorb sits in ------------------------------------------------
   The strip's top face alone was a floor with no walls, ending in mid-air. Now the
   whole space above the strip is a recessed box: a floor (the face they stand on),
   two side walls and a ceiling, each a trapezoid running from the screen's edge in
   to one inner rectangle, with a violet line where they meet it. Glorb, the weave and
   the backdrops are the back wall. --ledge is the depth; --stage is the box's height,
   set every frame from where the strip actually is. */
#deck::after { display: none; }
.stage-frame { position: absolute; left: 0; right: 0; bottom: 100%; height: var(--stage, 50vh); pointer-events: none; z-index: 0;
  --d: var(--ledge); --edge: color-mix(in srgb, #a94dff 60%, transparent); }
.stage-frame i { position: absolute; inset: 0; }
/* just the GROUND now: a full-width band, no walls, no ceiling, no violet frame. It runs past
   both screen edges (inset -40px) so no corner or end of it is ever in view, and its far edge
   fades into the back wall rather than drawing a line. */
.stage-frame .floor { inset: auto -40px 0; height: var(--d);
  background: linear-gradient(to top, color-mix(in srgb, var(--sheet) 88%, #2a1640), color-mix(in srgb, var(--sheet) 55%, #000) 75%, transparent); }
.stage-frame .wl, .stage-frame .wr, .stage-frame .ceil { display: none; }
#mini { z-index: 2; }
/* About: Colin stands IN the box, on its floor -- his layer goes above the strip so the floor cannot cover his feet.
   His canvas frames him so his soles sit 9.7% up from its bottom (camera at 0.62h looking at 0.5h); that comes off,
   then half the floor's depth, so he stands in the middle of it */
body.stage-page #view { z-index: 13; }
body.stage-page .about-slot { transform: translateY(calc(9.7% - var(--ledge) * .5)); }
.support { flex-direction: column; align-items: stretch; }
.support .ways { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.support .lbl { font: 600 10px var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--muted); width: 3.4em; }
.btn.sm { padding: 7px 12px; font-size: 13px; }
/* the picked character: big, in 3D, above what they are */
.char-detail.on { display: block; }
.char-detail #char-viewer { margin: 0 0 14px; }
/* home shelf: the same small faces as the Characters page, not a second set of big ones */
.shelf-figures .figure { width: 84px; }
.shelf-figures .figure img { aspect-ratio: 1; }
.shelf-figures .tile-meta b { font-size: 12px; text-align: center; }
.shelf-figures .tile-meta span { display: none; }

/* ---- home hero: Colin big in the middle, presenting ----------------------------------- */
#home-stage { position: fixed; left: 0; right: 0; z-index: 13; pointer-events: none; display: none; }
body.at-home #home-stage { display: flex; justify-content: center; align-items: flex-end; }
#home-stage #mini.hero .mini-body { width: auto; aspect-ratio: 0.7; height: 100%; }
/* His canvas reaches below his feet (to frame him); that strip must never sit over the menu
   and take its taps -- so the BOX lets taps through and only the part above his soles takes them
   (a ::before), which keeps the menu live without clipping his feet off. */
#mini.hero .mini-body { pointer-events: none; }
#mini.hero .mini-body canvas { pointer-events: none; }
#mini.hero .mini-body::before { content: ''; position: absolute; inset: 0 0 9.7% 0; pointer-events: auto; }
#mini.hero .mini-panel, #mini.hero .mini-tools { bottom: calc(9.7% + 64px); }
#mini.hero .mini-tools { bottom: calc(9.7% + 14px); }
/* on the stage the Stop bubble is the only control: no CC / keyboard / close row */
#mini.hero .mini-tools { display: none !important; }
#mini.hero .mini-tag { bottom: calc(9.7% + 66px); }
/* the line-up brings its own Colin: the hero one steps aside so there is only ever one of him */
body.colin-in-line #home-stage { visibility: visible; display: flex; justify-content: center; align-items: flex-end; z-index: 14; }
#home-stage { transform-origin: 50% 90.32%; }
/* ONE look for the characters: the Characters page keeps the home page's head height, so
   the line-up does not shrink on the way in, and its picker is the home shelf's plain
   figures (no boxes) -- the picked one lifted, lit and underlined */
body[data-sec="characters"] #deck { margin-top: var(--band); }
.char-thumbs { gap: 4px; }
.char-thumbs button { width: 84px; border: 0; background: none; border-radius: 0; padding: 0 0 8px; box-shadow: none;
  color: var(--muted); font: 600 12px/1.2 var(--ui); position: relative; }
.char-thumbs button img { transition: transform .3s cubic-bezier(.2,.8,.2,1), opacity .2s; }
.char-thumbs:has(.on) button:not(.on) img { opacity: .62; }
.char-thumbs button.on { border: 0; box-shadow: none; transform: none; color: var(--ink); }
.char-thumbs button.on img { transform: translateY(-6px) scale(1.06); }
.char-thumbs button.on::after { content: ''; position: absolute; left: 30%; right: 30%; bottom: 2px; height: 3px; border-radius: 3px;
  background: var(--accent); box-shadow: 0 0 10px var(--accent); }
/* the picked character opens right on the home shelf, inside the page's gutters */
.shelf .char-detail.on { padding: 8px var(--gut) 4px; }
.shelf-figures .figure img { transition: transform .3s cubic-bezier(.2,.8,.2,1), opacity .2s; }
.shelf-figures:has(.figure.on) .figure:not(.on) img { opacity: .62; }
.shelf-figures .figure { position: relative; padding-bottom: 8px; }
.shelf-figures .figure.on img { transform: translateY(-6px) scale(1.06); }
.shelf-figures .figure.on b { color: var(--ink); }
.shelf-figures .figure.on::after { content: ''; position: absolute; left: 30%; right: 30%; bottom: 2px; height: 3px; border-radius: 3px;
  background: var(--accent); box-shadow: 0 0 10px var(--accent); }
/* a game page leads with its app icon, rounded like a home screen, then its current art */
.gallery img.app { width: min(62%, 280px); justify-self: center; border: 0; border-radius: 22.5%;
  box-shadow: 0 14px 30px -18px rgba(0,0,0,.6), inset 0 0 0 1px rgba(255,255,255,.06); }
/* the cast, a row per game -- the same faces on the home shelf and the Characters page */
.char-group + .char-group { margin-top: 6px; }
.char-game { margin: 14px 0 2px; padding: 0 var(--gut); font: 600 10px var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--muted); }
.char-page .char-game { padding: 0; }
.char-page .rail { margin-inline: calc(-1 * var(--gut)); padding-inline: var(--gut); }
.char-page .char-detail.on { padding: 8px 0 4px; }
.game-cast, .char-page { background: none !important; }

/* ONE stage height everywhere: every section's head is home's height, so nothing jumps between pages */
/* ONE Colin everywhere: the big one, on the stage above whichever key is down (About places him itself) */
body:not(.stage-page) #home-stage { display: flex; justify-content: center; align-items: flex-end; }
/* coming into view (see reveal() in app.js) */
.rv { opacity: 0; transform: translateY(24px) scale(.985); transition: opacity .5s ease var(--rv, 0ms), transform .7s cubic-bezier(.2,.8,.2,1) var(--rv, 0ms); }
.rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .rv { opacity: 1; transform: none; transition: none; } }
/* which build this is, on the very first screen: "it is still doing it" and "that build has not reached me yet" look the same otherwise */
.intro-build { position: absolute; left: 14px; bottom: calc(12px + env(safe-area-inset-bottom)); font: 600 10px var(--mono); letter-spacing: .12em;
  color: var(--muted); opacity: .75; pointer-events: none; }
#intro.walk .intro-build, #intro.out .intro-build { opacity: 0; transition: opacity .4s; }
/* a row of things scrolls SIDEWAYS only, and what comes into it arrives from the side --
   rising from below as it is swiped in read as the whole row bobbing up and down */
.rail { overflow-y: hidden; overscroll-behavior-y: auto; }
.rail > .rv { transform: translateX(28px); }
.rail > .rv.in { transform: none; }
/* hover lifts are for a mouse: on a phone a touch IS a hover, so cards bobbed up as a finger swiped past */
@media (hover: none) { .tile:hover .cover, .figure:hover img { transform: none; } }
/* no vertical travel in a row of faces either: the picked one is marked by its underline and light, not a lift */
.shelf-figures .figure.on img, .char-thumbs button.on img { transform: none; }
@media (min-aspect-ratio: 1/1) { :root { --band: min(66.667vw, 72svh); } }
/* intro, walking toward you: the name is centre stage, and the whole stage is lowered (--lift)
   so he walks out through it; once the page has him, the stage rises to its place (app.js) */
#intro.depth .intro-word { top: 50%; }
#intro.depth .intro-role { top: calc(50% + min(15vw, 84px)); }
#glorb, #home-stage { translate: 0 var(--lift, 0px); }
/* --rlift: the same elevator between pages, when the strip has a long way to go (into and out of
   About); only the strip and the page ride it -- Glorb follows the strip on his own */
#deck, #view { translate: 0 calc(var(--lift, 0px) + var(--rlift, 0px)); }
/* a game's page: its wide art is the stage behind Colin; its icon sits beside its name */
#glorb .game-bg { position: absolute; left: 0; right: 0; top: 0; height: 50%; overflow: hidden; opacity: 0; transition: opacity .6s; pointer-events: none; }
#glorb .game-bg.on { opacity: 1; }
#glorb .game-bg .fill { position: absolute; inset: -30px; background: center / cover no-repeat; filter: blur(22px) brightness(.55) saturate(1.2); }
#glorb .game-bg img, #glorb .game-bg video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.game-head { display: flex; align-items: center; gap: 18px; margin-bottom: 6px; }
.game-head img.app { width: clamp(84px, 24vw, 132px); aspect-ratio: 1; flex: none; border-radius: 22.5%; object-fit: cover;
  box-shadow: 0 8px 24px -10px rgb(0 0 0 / .5); }
.game-head > div { min-width: 0; }
.game-head .title { margin-top: 0; }
/* THE NAME IN HIS COLOURS: the big C is Glorb's violet, the two Os his green, the rest of the
   letters the page's ink -- soft on cream, neon on the dark page, the same as he is */
:root { --logo-c: #8a64c2; --logo-o: #6f9f5e; }
:root[data-theme="dark"] { --logo-c: #a855f7; --logo-o: #72ec5c; }
.logo > path { color: var(--logo-c); }
.logo > g > path { color: var(--logo-o); }
/* walking toward you, the name sits higher, so Enter comes up under the role line rather than
   being left at the foot of the screen */
#intro.depth .intro-enter { bottom: auto; top: calc(50% + min(15vw, 84px) + 64px); }
#glorb .game-bg video.off { visibility: hidden; }
/* the section's name, in the stage (secTitle) */
.sec-title { position: absolute; z-index: 3; pointer-events: none; opacity: 0; transform: scale(.9);
  transition: opacity .45s, transform .55s cubic-bezier(.2,.8,.2,1); }
.sec-title.on { opacity: 1; transform: none; }
.sec-title i { display: block; width: 100%; height: 100%;
  background: linear-gradient(100deg, var(--logo-c), var(--logo-o));
  -webkit-mask: var(--art) center / contain no-repeat; mask: var(--art) center / contain no-repeat;
  filter: drop-shadow(0 2px 6px rgb(0 0 0 / .35)); }
.sec-title b { display: grid; place-items: center; width: 100%; height: 100%; font: 700 clamp(24px, 6vw, 44px)/1 var(--ui);
  background: linear-gradient(100deg, var(--logo-c), var(--logo-o)); -webkit-background-clip: text; background-clip: text; color: transparent; }
body.stage-page .sec-title { display: none; }
/* LIGHT MODE: the soft logo pair under a dark drop shadow read as muddy grey on cream. The title
   takes the logo's FULL-strength violet and green, and sits on a cream halo with a coloured
   under-shadow instead of a grey one, so it reads as colour, not as a smudge */
:root:not([data-theme="dark"]) .sec-title { --logo-c: #8a2cf2; --logo-o: #22b14c; }
:root:not([data-theme="dark"]) .sec-title i { background: linear-gradient(100deg, #8a2cf2, #d0329a 52%, #22b14c);
  filter: drop-shadow(0 0 1.5px var(--bg)) drop-shadow(0 0 3px var(--bg)) drop-shadow(0 3px 5px color-mix(in srgb, #8a2cf2 40%, transparent)); }

/* THE STAGE EQ (colin.js): bars along the floor at his feet, rising up behind him while he listens
   or talks -- part of the stage rather than a label on it. The 'Listening' pill steps aside for it. */
.mini-eq { display: none; }
#mini.hero .mini-eq { display: flex; position: absolute; left: 50%; bottom: calc(9.7% + 2px); translate: -50% 0; z-index: 0;
  width: min(88%, 400px); height: min(26%, 140px); align-items: flex-end; justify-content: space-between; pointer-events: none; }
#mini.hero .mini-eq i { flex: 0 0 auto; width: 7px; height: 100%; border-radius: 3px 3px 1px 1px; transform: scaleY(0); transform-origin: 50% 100%;
  background: linear-gradient(to top, var(--accent-ink), var(--accent)); box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 45%, transparent); }
:root[data-theme="dark"] #mini.hero .mini-eq i { background: linear-gradient(to top, var(--accent), color-mix(in srgb, var(--accent) 55%, #fff)); }
#mini.hero[data-state="speaking"] .mini-eq i, :root[data-theme="dark"] #mini.hero[data-state="speaking"] .mini-eq i { background: linear-gradient(to top, color-mix(in srgb, var(--logo-o) 70%, #000), var(--logo-o));
  box-shadow: 0 0 10px color-mix(in srgb, var(--logo-o) 55%, transparent); }
#mini.hero .mini-body { position: relative; z-index: 1; }
#mini.hero .mini-tag { display: none; }

/* ON A STAGE, TALKING: one pill beside his head -- Stop, and typing tucked behind the keyboard key.
   (The About page's Talk bubble steps aside while it is up: they would be two Stops.) */
.mini-pill { display: none; }
#mini.hero .mini-pill:not([hidden]) { display: flex; position: absolute; left: 0; top: 0; z-index: 6; pointer-events: auto; gap: 0;
  border-radius: 20px; border: 2px solid var(--accent); background: var(--accent); overflow: hidden;
  box-shadow: 0 6px 0 -1px color-mix(in srgb, var(--accent) 45%, transparent), 0 14px 28px -12px rgb(0 0 0 / .5); }
#mini.hero .mini-pill button { all: unset; cursor: pointer; padding: 9px 14px 10px; font: 650 15px/1 var(--ui); color: var(--on-accent, #fff); }
#mini.hero .mini-pill .mini-pk, #mini.hero .mini-pill .mini-pc { background: var(--card); color: var(--ink); font-size: 14px; }
#mini.hero .mini-pill .mini-pc { font: 700 11px/1 var(--mono); letter-spacing: .06em; padding: 11px 11px 11px 14px; color: var(--muted); }
#mini.hero .mini-pill .mini-pc[aria-pressed="true"] { color: var(--ink); background: color-mix(in srgb, var(--accent) 25%, var(--card)); }
#mini.hero .mini-pill .mini-pk[aria-pressed="true"] { background: color-mix(in srgb, var(--accent) 25%, var(--card)); }
#mini.hero .mini-pill .mini-ps::before { content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 7px; vertical-align: 1px;
  background: currentColor; animation: talkdot 1s ease-in-out infinite; }
body.stage-page .about-talk.on { display: none; }

/* SCAN TO PLAY (game pages): the games are built for two thumbs, so on a laptop the page offers
   them to a phone. Only where there is a mouse -- on a phone the Open button already is the way in. */
.play-phone { display: none; }
@media (hover: hover) and (pointer: fine) {
  .play-phone { display: flex; align-items: center; gap: 20px; margin: 22px 0 6px; padding: 16px 20px 16px 16px; max-width: 520px;
    border: 1px solid var(--line); border-radius: var(--r); background: var(--card); }
  .play-phone .qr { flex: none; width: 132px; height: 132px; padding: 10px; border-radius: 12px; background: #fff;
    box-shadow: 0 0 0 1px rgb(0 0 0 / .06), 0 8px 20px -12px rgb(0 0 0 / .45); }
  .play-phone b { display: block; font: 700 17px/1.2 var(--ui); margin-bottom: 4px; }
  .play-phone span { display: block; color: var(--muted); font-size: 14px; line-height: 1.4; margin-bottom: 8px; }
  .play-phone a { font: 500 12px var(--mono); color: var(--accent-ink); text-decoration: none; }
  .play-phone a:hover { text-decoration: underline; }
}
