/* Archivo (SIL OFL 1.1, see assets/fonts/OFL-Archivo.txt), pinned at its widest
   setting (wdth 125) and subset to Latin. Weight stays variable from 400 to 800. */
@font-face {
  font-family: "Archivo Expanded";
  src: url("../assets/fonts/archivo-expanded.woff2") format("woff2");
  font-style: normal; font-weight: 400 800; font-display: swap;
}

:root {
  --ink: #07090B;
  --bone: #E3E6E0;
  --haze: rgba(227, 230, 224, .70);
  --faint: rgba(227, 230, 224, .44);
  --dim: rgba(227, 230, 224, .26);
  --hair: rgba(227, 230, 224, .14);
  --hair2: rgba(227, 230, 224, .30);
  --slate: #6E8299;   /* desaturated slate blue */
  --teal: #5E8783;    /* teal-grey */
  --sage: #8D9C86;    /* sage */
  --well: rgba(7, 9, 11, .52);
  --sans: "Archivo Expanded", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --edge-l: max(22px, calc(env(safe-area-inset-left) + 16px));
  --edge-r: max(22px, calc(env(safe-area-inset-right) + 16px));
  --edge-t: max(22px, calc(env(safe-area-inset-top) + 14px));
  --edge-b: max(16px, calc(env(safe-area-inset-bottom) + 8px));
  --ease: cubic-bezier(.22, .8, .18, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0; height: 100%; overflow: hidden;
  overscroll-behavior: none;
  background: var(--ink);
  /* Fallback art if no canvas can render at all */
  background-image: linear-gradient(160deg, #13202B 0%, #07090B 60%);
  color: var(--bone);
  font-family: var(--sans);
  font-weight: 500;
  text-transform: uppercase;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
body { position: fixed; inset: 0; }

button { font: inherit; text-transform: inherit; color: inherit; background: none; border: 0; border-radius: 0; padding: 0; margin: 0; cursor: pointer; -webkit-appearance: none; appearance: none; touch-action: manipulation; }
a { color: inherit; text-decoration: none; }
:focus { outline: none; }
:focus-visible { outline: 1px solid var(--bone); outline-offset: 3px; }

#gl {
  position: fixed; inset: 0; width: 100%; height: 100%;
  display: block; z-index: 0;
}
/* the smoke creature's layer: only shown while it is out */
.creature {
  position: fixed; inset: 0; width: 100%; height: 100%; z-index: 2;
  display: none; pointer-events: none;
}

/* Ben's eyes lit with the eye motif, now and then, when the picture is heavily bent (see stepGlyphs) */
.eyeglyph {
  position: fixed; inset: 0; width: 100%; height: 100%; z-index: 1;
  display: none; pointer-events: none;
}

.surface {
  position: fixed; inset: 0; z-index: 1;
  touch-action: none;
}
.is-entered .surface { cursor: ew-resize; }
.is-dragging .surface { cursor: grabbing; }

/* Shade only where type and controls sit, so the footage stays clear everywhere else. */
.scrim {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(to top, rgba(7, 9, 11, .66), rgba(7, 9, 11, .30) 32%, transparent 52%),
    radial-gradient(48% 22% at 0% 0%, rgba(7, 9, 11, .5), transparent 100%);
  opacity: 0; transition: opacity 1.6s var(--ease) .3s;
}
.is-entered .scrim { opacity: 1; }

/* ---------- identity ---------- */
.ident {
  position: fixed; z-index: 3;
  left: var(--edge-l); top: var(--edge-t);
  margin: 0; pointer-events: none;
  transform-origin: 50% 50%;
  opacity: 0;
}
.is-ready .ident { opacity: 1; transition: opacity 2s ease .1s; }
.ident.is-gliding { transition: transform 1.8s var(--ease), opacity .6s ease; }

.name {
  margin: 0;
  font-weight: 760;
  font-size: clamp(19px, 1.75vw, 26px);
  line-height: 1;
  letter-spacing: .13em;
  margin-right: -.13em;
  white-space: nowrap;
  color: var(--bone);
  text-shadow: 0 0 22px rgba(7, 9, 11, .35);
  transition: opacity .6s ease;
}
.is-entered .name { pointer-events: auto; }
/* while the pointer stirs it (see nameSmoke) the canvas stands in for the type, exactly over it: the heading
   keeps its place in the page (and its soft shadow), only its ink is hidden */
.name.is-ink { color: transparent; }
.namesmoke { position: fixed; left: 0; top: 0; z-index: 3; pointer-events: none; display: none; }

/* ---------- enter ---------- */
.enter {
  position: fixed; z-index: 4;
  left: 50%; top: 64%;
  width: 148px; height: 50px; margin: -25px 0 0 -74px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  border: 1px solid var(--hair2);
  background: rgba(7, 9, 11, .28);
  opacity: 0;
  transition: opacity 1.4s ease .9s, border-color .4s ease, background-color .4s ease;
}
.is-ready .enter { opacity: 1; }
.enter::before, .enter::after {   /* registration corners */
  content: ""; position: absolute; width: 7px; height: 7px; border: 0 solid var(--bone);
}
.enter::before { left: -1px; top: -1px; border-left-width: 1px; border-top-width: 1px; }
.enter::after { right: -1px; bottom: -1px; border-right-width: 1px; border-bottom-width: 1px; }
.enter-label { font-size: 12px; font-weight: 700; letter-spacing: .24em; margin-right: -.24em; line-height: 1; }
.enter:hover { border-color: rgba(227, 230, 224, .6); background: rgba(7, 9, 11, .42); }
.enter:focus-visible { outline-offset: 5px; }
.is-entered .enter { opacity: 0; pointer-events: none; visibility: hidden; transition: opacity .6s ease, visibility 0s linear .6s; }

/* ---------- hint ---------- */
.hint {
  position: fixed; z-index: 3; left: 50%; top: 36%;
  width: min(440px, calc(100% - 48px));
  transform: translate(-50%, 6px);
  margin: 0; text-align: center;
  font-size: 9.5px; font-weight: 560; letter-spacing: .14em; line-height: 2.1;
  color: var(--bone);
  text-shadow: 0 0 16px rgba(7, 9, 11, .8), 0 0 4px rgba(7, 9, 11, .6);
  opacity: 0; pointer-events: none;
  transition: opacity 1.2s ease, transform 1.2s var(--ease);
}
.show-hint .hint { opacity: 1; transform: translate(-50%, 0); }

/* ---------- deck ---------- */
.deck {
  position: fixed; z-index: 3;
  left: 50%; bottom: calc(var(--edge-b) + 50px);
  width: min(720px, calc(100% - 44px));
  transform: translate(-50%, 12px);
  opacity: 0; visibility: hidden;
  touch-action: none;
  transition: opacity 1.4s var(--ease) .55s, transform 1.6s var(--ease) .45s, visibility 0s linear 2s;
}
.is-entered .deck { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition: opacity 1.4s var(--ease) .55s, transform 1.6s var(--ease) .45s, visibility 0s; }
.is-entered.is-idle .deck { opacity: .32; transition: opacity 2.4s ease; }
.is-entered.is-idle .deck:focus-within { opacity: 1; }

.deck-top { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.ctl {
  flex: 0 0 auto; width: 40px; height: 40px;
  display: grid; place-items: center;
  border: 1px solid var(--hair2);
  background: var(--well);
  transition: border-color .3s ease, background-color .3s ease;
}
.ctl:hover { border-color: rgba(227, 230, 224, .62); }
.ctl svg { width: 14px; height: 14px; fill: var(--bone); }
.play .i-pause { display: none; }
.play[aria-pressed="true"] .i-pause { display: block; }
.play[aria-pressed="true"] .i-play { display: none; }
.reseed svg { width: 15px; height: 15px; }
.reseed .o { fill: none; stroke: var(--bone); stroke-width: 1; opacity: .7; }
.clear svg { width: 17px; height: 17px; }
.clear .o { fill: none; stroke: var(--bone); stroke-width: 1.5; stroke-linejoin: round; }

/* time strip */
.time {
  flex: 1 1 auto; position: relative; height: 44px;
  cursor: ew-resize; touch-action: none;
  --f: .6667;
}
.time:focus-visible { outline-offset: 0; }
.time-heat {
  position: absolute; left: 12px; right: 12px; top: calc(54% - 4px); height: 9px; pointer-events: none;
}
.time-heat .z {
  position: absolute; top: 0; bottom: 0; opacity: .5;
  -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 5px, transparent 5px 7px);
  mask-image: repeating-linear-gradient(90deg, #000 0 5px, transparent 5px 7px);
  transition: opacity .5s ease, filter .5s ease;
}
/* reverse: deep cyan, hottest at full reverse */
.z-rev { left: 0; width: 31%; background: linear-gradient(90deg, rgba(34, 199, 216, .78), rgba(34, 199, 216, .3) 45%, rgba(11, 76, 94, .12)); }
/* still: a narrow crystalline band */
.z-frz { left: 31.4%; width: 3.9%; background: rgba(233, 255, 247, .5); }
/* normal: near nothing */
.z-one { left: 35.7%; width: 34%; background: linear-gradient(90deg, rgba(20, 162, 122, .08), rgba(20, 162, 122, .14) 88%, rgba(20, 162, 122, .02)); }
/* speed-up: jade into acid green at full speed */
.z-fast { left: 70.1%; width: 29.9%; background: linear-gradient(90deg, rgba(20, 162, 122, .12), rgba(20, 162, 122, .35) 50%, rgba(179, 240, 60, .8)); }
/* the two secret stretches, barely there: a slow crystalline shimmer across the still zone (-0.2x to
   0.13x) and a faint breathing sunset glow over the ambient zone (0.13x to 0.65x), where the mountains
   come. A curious eye finds them. */
.time-heat .zh { position: absolute; top: -3px; bottom: -3px; pointer-events: none; border-radius: 4px; }
.zh-frz {
  left: 26.667%; width: 11%;
  background: linear-gradient(100deg, transparent 0 30%, rgba(233, 255, 247, .16) 46%, rgba(34, 199, 216, .1) 54%, transparent 70%) 0 0 / 300% 100%,
    linear-gradient(90deg, transparent, rgba(34, 199, 216, .05) 20%, rgba(34, 199, 216, .05) 80%, transparent);
  animation: zhShimmer 7.5s linear infinite;
}
.zh-amb {
  left: 37.667%; width: 17.333%;
  background: radial-gradient(60% 120% at 50% 50%, rgba(255, 176, 120, .34), rgba(236, 128, 92, .18) 45%, rgba(141, 156, 134, .07) 75%, transparent 100%);
  animation: zhBreathe 9s ease-in-out infinite;
}
@keyframes zhShimmer { from { background-position: 100% 0, 0 0; } to { background-position: -50% 0, 0 0; } }
@keyframes zhBreathe { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }
.time-heat .cap { position: absolute; top: -3px; width: 3px; height: 15px; opacity: .8; }
.cap-l { left: -1px; background: #22C7D8; }
.cap-r { right: -1px; background: #B3F03C; }
.is-reverse .z-rev, .is-still .z-frz, .is-fast .z-fast { opacity: 1; filter: brightness(1.25); }
.is-reverse .cap-l, .is-fast .cap-r { opacity: 1; }
.time-line { position: absolute; left: 12px; right: 12px; top: 54%; height: 1px; background: var(--hair2); }
.time-fill {
  position: absolute; top: -1px; height: 3px;
  left: 33.333%; width: calc((var(--f) - .33333) * 100%);
  background: var(--teal);
}
.is-reverse .time-fill { left: calc(var(--f) * 100%); width: calc((.33333 - var(--f)) * 100%); background: #22C7D8; }
.is-fast .time-fill { background: linear-gradient(90deg, var(--teal) 50%, #B3F03C); }
.tick { position: absolute; top: -3px; width: 1px; height: 7px; background: var(--faint); }
.tick i {
  position: absolute; top: 11px; left: 0; transform: translateX(-50%);
  font-style: normal; font-size: 7px; font-weight: 600; letter-spacing: .1em; margin-left: .05em;
  color: var(--faint); line-height: 1;
}
.t-rev { left: 0; }
.t-rev i { transform: none; left: -1px; }
.t-still { left: 33.333%; top: -3px; width: 7px; height: 7px; margin-left: -3px; background: none; border: 1px solid var(--faint); }
.t-still i { left: 3px; }
.t-one { left: 66.667%; top: -6px; height: 13px; background: var(--haze); }
.t-one i { top: 14px; }
.t-two { left: 100%; }
.t-two i { transform: translateX(-100%); left: 1px; }
.knob-track { position: absolute; inset: 0; pointer-events: none; }
.knob { position: absolute; left: 0; top: 0; width: 100%; height: 0; will-change: transform; transform: translateX(66.667%); }
.knob-bar {
  position: absolute; left: 0; top: 0;
  width: 3px; height: 17px; margin: -8px 0 0 -1.5px;
  background: var(--bone);
  box-shadow: 0 0 0 1px rgba(7, 9, 11, .35);
}
.time-read {
  position: absolute; left: 0; bottom: 13px; transform: translateX(-50%);
  font-size: 10px; font-weight: 640; letter-spacing: .12em; font-variant-numeric: tabular-nums;
  color: var(--bone); white-space: nowrap; line-height: 1;
  text-shadow: 0 0 10px rgba(7, 9, 11, .9), 0 0 3px rgba(7, 9, 11, .8);
}
.time-x { margin-left: .14em; opacity: .75; font-weight: 500; }

/* grid: hairlines are the gaps showing the frame behind the cells */
.grid {
  display: flex; flex-direction: column; gap: 1px;
  background: var(--hair);
  border: 1px solid var(--hair);
}
.row {
  display: grid; align-items: stretch;
  grid-template-columns: 40px repeat(16, minmax(0, 1fr));
  column-gap: 1px;
  --c: var(--teal);
}
.row[data-tone="slate"] { --c: var(--slate); }
.row[data-tone="sage"] { --c: var(--sage); }
.row.is-muted .cell.on::before { opacity: .22; filter: saturate(.3); }
.rowhead { display: contents; }
.mute {
  height: 22px; position: relative;
  display: flex; align-items: center; justify-content: center;
  background: var(--well);
  color: var(--haze);
  transition: color .4s ease;
}
.mute svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.mute svg .f { fill: currentColor; stroke: none; }
.mute::after {   /* level tab: a sliver of the track tone at the right edge */
  content: ""; position: absolute; right: 0; top: 0; bottom: 0; width: 2px;
  background: var(--c); opacity: .55;
}
.mute::before {  /* muted: a hairline struck through the glyph */
  content: ""; position: absolute; left: 50%; top: 50%; width: 18px; height: 1px; margin: 0 0 0 -9px;
  background: var(--bone); transform: rotate(-35deg) scaleX(0); transition: transform .25s var(--ease);
}
.mute:hover { color: var(--bone); }
.mute[aria-pressed="true"] { color: var(--dim); }
.mute[aria-pressed="true"]::before { transform: rotate(-35deg) scaleX(1); }
.mute[aria-pressed="true"]::after { opacity: .12; }
.mute.hit { color: var(--bone); transition: color 0s; }

/* steps: soft glowing circles over the hairline grid. --e (0 to 1) follows the speed, --pulse the beat. */
.grid { --e: .5; --pulse: 0; }
.cell {
  position: relative; height: 22px; width: 100%;
  background: var(--well);
  transition: background-color .18s ease;
  overflow: hidden;
}
.cell.beat:not([data-s="0"]) { margin-left: 2px; }
.cell::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  border: 1px solid var(--dim);
  transition: border-radius .9s var(--ease), transform .5s var(--ease), width .3s ease, height .3s ease, margin .3s ease, opacity .9s var(--ease);
}
.cell.beat::before { border-color: var(--faint); }
.cell:hover { background: rgba(30, 38, 44, .62); }
.cell.on::before {
  --g: calc(.5 + .22 * var(--e) + .4 * var(--pulse));
  width: 15px; height: 15px; margin: -7.5px 0 0 -7.5px;
  border: 0;
  background: radial-gradient(circle, rgba(233, 255, 247, var(--g)) 0, var(--c) 34%, color-mix(in srgb, var(--c) 40%, transparent) 58%, transparent 72%);
  transform: scale(calc(1 + .1 * var(--e) + .22 * var(--pulse)));
  opacity: calc(.65 + .2 * var(--e) + .2 * var(--pulse));
}
.cell.now { background: rgba(58, 66, 70, .62); }
.cell.on.now::before { --g: 1; transform: scale(calc(1.18 + .15 * var(--e))); }
.cell.on.hit::before { animation: hitc .45s ease-out; }
.cell.on.hit2::before { animation: hitc2 .45s ease-out; }
.cell:focus-visible { outline: 1px solid var(--bone); outline-offset: -2px; }
@keyframes hitc { 0% { filter: brightness(1.6); } 100% { filter: none; } }
@keyframes hitc2 { 0% { filter: brightness(1.6); } 100% { filter: none; } }

/* fast: the circles become eyes, a small almond set on the diagonal with a ringed iris, and now and then
   one blinks. From about 1.2x a scattered few turn, more and more as the speed rises, all of them by full
   speed; each one morphs on its own: the outline bends into an almond, the glow folds and fades as the
   eye opens over it. The turn is on the element, so the blink (a clip) closes along the eye's own axis. */
.cell .eye {   /* the eye (vector, see EYE_DEFS in main.js): closed to a slit until its cell turns */
  position: absolute; left: 50%; top: 50%; pointer-events: none;
  width: 20px; height: 12.3px; overflow: visible;
  color: color-mix(in srgb, var(--c) 50%, #E9FFF7);
  opacity: 0; transform: translate(-50%, -50%) rotate(-30deg) scale(.5, .06);
  transition: opacity .8s var(--ease), transform 1.1s var(--ease);
}
.cell .eye .ir { transform-box: fill-box; transform-origin: center; transform: scale(0); transition: transform .9s var(--ease) .35s; }
.cell.is-eye::before { border-radius: 0 100% 0 100%; transform: rotate(-45deg) scale(.95, .62); }
.cell.on.is-eye::before { transform: rotate(-45deg) scale(1.05, .5); opacity: 0; }
.cell.on.is-eye .eye { opacity: 1; transform: translate(-50%, -50%) rotate(-30deg); }
.cell.on.is-eye .eye .ir { transform: scale(1); }
/* the beat's swell rides on the separate scale property, which is not transitioned: tied into the morph's
   transform it restarted the iris's delayed transition on every beat, so many irises never finished opening */
.cell.on.is-eye .eye { scale: calc(1 + .1 * var(--pulse)); }
.cell.on.is-eye .eye .ir { scale: calc(1 + .06 * var(--pulse)); }
/* the solid variant (about two in five cells, seeded): the almond alone, no iris or pupil */
.cell .eye.solid .ir { display: none; }
.cell.on.is-eye.blink .eye { animation: blink .22s ease-in-out; }
.cell.on.is-eye.blink2 .eye { animation: blink2 .22s ease-in-out; }
@keyframes blink { 0%, 100% { clip-path: inset(0 0 0 0); } 50% { clip-path: inset(47% 0 47% 0); } }
@keyframes blink2 { 0%, 100% { clip-path: inset(0 0 0 0); } 50% { clip-path: inset(47% 0 47% 0); } }

.pages { display: none; }

/* ---------- footer ---------- */
.foot {
  position: fixed; z-index: 3; left: var(--edge-l); right: var(--edge-r); bottom: var(--edge-b);
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  height: 36px;
  opacity: 0; transition: opacity 2s ease 1.2s;
}
.is-ready .foot { opacity: 1; }
.is-entered.is-idle .foot { opacity: .45; transition: opacity 2.4s ease; }
.links { display: flex; align-items: center; gap: 4px; margin-left: -9px; }
.links a {
  width: 34px; height: 34px; display: grid; place-items: center;
  color: var(--haze); transition: color .3s ease;
  font-size: 9px; letter-spacing: .1em;
}
.links a svg { width: 15px; height: 15px; display: block; fill: currentColor; }
.links a:hover { color: var(--bone); }
.ask { position: relative; }
.ask-btn {
  height: 34px; padding: 0 2px 0 10px;
  font-size: 10px; font-weight: 700; letter-spacing: .1em; margin-right: -.1em;
  color: var(--haze); transition: color .3s ease;
}
.ask-btn:hover, .ask-btn[aria-expanded="true"] { color: var(--bone); }
.ask-pop {
  position: absolute; right: 0; bottom: calc(100% + 8px);
  padding: 14px 16px 13px;
  width: max-content; max-width: calc(100vw - 32px);
  display: flex; flex-direction: column; gap: 10px; align-items: flex-end;
  background: rgba(7, 9, 11, .86);
  border: 1px solid var(--hair2);
  animation: rise .45s var(--ease);
  -webkit-user-select: text; user-select: text;
}
.ask-pop[hidden] { display: none; }
.ask-pop a {
  font-size: 10.5px; font-weight: 640; letter-spacing: .07em;
  color: var(--bone); border-bottom: 1px solid var(--hair2); padding-bottom: 3px;
}
.ask-pop a:hover { border-color: var(--bone); }
.ask-pop span { font-size: 7.5px; font-weight: 560; letter-spacing: .12em; color: var(--faint); }
.ask-pop span[hidden] { display: none; }
@keyframes rise { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* ---------- phone ---------- */
@media (max-width: 700px) {
  .name { font-size: 17px; letter-spacing: .12em; }
  .deck { width: calc(100% - 28px); bottom: calc(var(--edge-b) + 48px); }
  .deck-top { gap: 10px; margin-bottom: 10px; }
  .ctl { width: 44px; height: 44px; }
  .ctl svg { width: 15px; height: 15px; }
  .time { height: 44px; }
  .row { grid-template-columns: 34px repeat(8, minmax(0, 1fr)); }
  .mute { height: 35px; }
  .mute svg { width: 16px; height: 16px; }
  .cell.on::before { width: 19px; height: 19px; margin: -9.5px 0 0 -9.5px; }
  .cell .eye { width: 27px; height: 16.6px; }
  .cell { height: 35px; }
  .cell.beat:not([data-s="0"]) { margin-left: 0; }
  .cell[data-s="4"], .cell[data-s="12"] { margin-left: 2px; }
  .grid[data-page="0"] .cell[data-half="1"], .grid[data-page="1"] .cell[data-half="0"] { display: none; }
  .pages { display: flex; justify-content: center; margin-top: 8px; }
  .page {
    width: 84px; height: 34px; position: relative;
    font-size: 8.5px; font-weight: 640; letter-spacing: .1em;
    color: var(--faint);
    border: 1px solid var(--hair2); background: var(--well);
  }
  .page + .page { border-left: 0; }
  .page[aria-pressed="true"] { color: var(--bone); background: rgba(94, 135, 131, .32); }
  .page.has-head::after { content: ""; position: absolute; top: 5px; right: 5px; width: 4px; height: 4px; background: var(--bone); }
  .foot { height: 44px; }
  .links { gap: 0; margin-left: -12px; }
  .links a { width: 44px; height: 44px; }
  .links a svg { width: 16px; height: 16px; }
  .ask-btn { height: 44px; padding-left: 14px; }
  .hint { top: 30%; }
  .enter { top: 62%; }
}
@media (max-width: 700px) and (max-height: 720px) {
  .cell, .mute { height: 34px; }
  .deck-top .ctl, .deck-top .time { height: 40px; }
  .deck-top .ctl { width: 40px; }
  .deck-top { margin-bottom: 6px; }
  .pages { margin-top: 6px; }
}
@media (max-height: 600px) and (min-width: 701px) {
  .cell, .mute { height: 15px; }
  .cell .eye { width: 14px; height: 8.6px; }
  .deck-top { margin-bottom: 6px; }
}

/* ---------- motion preferences ---------- */
@media (prefers-reduced-motion: reduce) {
  .ident.is-gliding { transition: opacity .6s ease; }
  .name { transition: opacity .6s ease; }
  .cell.on.hit::before, .cell.on.hit2::before, .cell.on.is-eye.blink .eye, .cell.on.is-eye.blink2 .eye { animation: none; }
  .cell .eye, .cell .eye .ir, .cell::before { transition-duration: .4s; transition-delay: 0s; }
  .deck, .is-entered .deck, .scrim, .hint { transition-duration: .4s; transition-delay: 0s; }
  .zh-frz, .zh-amb { animation: none; opacity: .5; }
}

/* =========================================================================
   PHONE LAYER: only under html.phone (a coarse pointer on a small screen, set in main.js).
   The sequencer becomes a bottom sheet that folds away after a few quiet seconds, and the
   time slider stands up along the right edge while it is folded. Nothing here reaches desktop.
   ========================================================================= */
html.phone {
  --rowh: clamp(44px, 6svh, 56px);   /* one sequencer row */
  --vis: 3.35;                        /* rows in view: three and a sliver of the next */
  --foot-h: 44px;
  --vx: calc(var(--edge-r) + 12px);   /* the slider's line, in from the right edge */
}
html.phone, html.phone body { height: 100%; height: 100dvh; overflow: hidden; overscroll-behavior: none; }
html.phone body { overflow-x: hidden; }

/* the sheet */
html.phone .deck {
  left: 0; right: 0; bottom: 0; width: auto;
  display: flex; flex-direction: column;
  padding: 8px max(10px, calc(env(safe-area-inset-right) + 6px)) calc(var(--edge-b) + var(--foot-h) + 2px) max(6px, env(safe-area-inset-left));
  background: rgba(7, 9, 11, .8);
  border-top: 1px solid var(--hair);
  transform: translateY(24px);
  touch-action: pan-y;
}
html.phone body.is-entered .deck { transform: none; }
html.phone body.is-entered.bb-ready .deck { transition: opacity .4s ease, transform .45s var(--ease), visibility 0s; }
html.phone body.is-entered.bb-folded .deck { transform: translateY(100%); visibility: hidden; transition: transform .45s ease, visibility 0s linear .45s; }
html.phone body.is-entered.is-idle .deck { opacity: 1; }
html.phone .deck > * { width: 100%; max-width: 620px; margin-left: auto; margin-right: auto; }

/* header row: play, the page toggle, clear (the eye) and a new pattern */
html.phone .deck-top { gap: 8px; margin-bottom: 8px; touch-action: none; }
html.phone .deck-top .ctl { width: 40px; height: 40px; }
html.phone .deck-top .ctl svg { width: 14px; height: 14px; }
html.phone .deck-top .clear svg { width: 17px; height: 17px; }
html.phone .deck-top .clear { margin-left: auto; }
html.phone .pages { display: flex; margin: 0; }
html.phone .page {
  width: 64px; height: 40px; position: relative;
  font-size: 8.5px; font-weight: 640; letter-spacing: .1em;
  color: var(--faint);
  border: 1px solid var(--hair2); background: var(--well);
}
html.phone .page + .page { border-left: 0; }
html.phone .page[aria-pressed="true"] { color: var(--bone); background: rgba(94, 135, 131, .32); }
html.phone .page.has-head::after { content: ""; position: absolute; top: 5px; right: 5px; width: 4px; height: 4px; background: var(--bone); }

/* the rows: a short scroller that snaps row by row */
html.phone .pgrid { position: relative; flex: 0 0 auto; }
html.phone .grid {
  height: calc(var(--vis) * (var(--rowh) + 1px) + 1px);
  overflow-x: hidden; overflow-y: auto;
  overscroll-behavior: contain;
  scroll-snap-type: y mandatory;
  scrollbar-width: none;
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
}
html.phone .grid::-webkit-scrollbar { display: none; }
html.phone .pgrid.is-nudging .grid { scroll-snap-type: none; }
html.phone .row { flex: 0 0 auto; scroll-snap-align: start; grid-template-columns: 40px repeat(8, minmax(0, 1fr)); }
html.phone .mute { height: var(--rowh); }
html.phone .mute svg { width: 16px; height: 16px; }
html.phone .cell { height: var(--rowh); }
html.phone .cell.beat:not([data-s="0"]) { margin-left: 0; }
html.phone .cell[data-s="4"], html.phone .cell[data-s="12"] { margin-left: 2px; }
html.phone .grid[data-page="0"] .cell[data-half="1"], html.phone .grid[data-page="1"] .cell[data-half="0"] { display: none; }
html.phone .cell.on::before { width: 21px; height: 21px; margin: -10.5px 0 0 -10.5px; }
html.phone .cell .eye { width: 28px; height: 17.2px; }
html.phone .cell:hover { background: var(--well); }
html.phone .cell.now { background: rgba(58, 66, 70, .62); }

/* scroll cues: soft fades at the edges, a thin position rail and, the first time, a small chevron */
html.phone .pfade { position: absolute; left: 1px; right: 1px; height: 26px; pointer-events: none; opacity: 0; transition: opacity .35s ease; }
html.phone .pfade-t { top: 1px; background: linear-gradient(to bottom, rgba(7, 9, 11, .9), rgba(7, 9, 11, 0)); }
html.phone .pfade-b { bottom: 1px; background: linear-gradient(to top, rgba(7, 9, 11, .92), rgba(7, 9, 11, 0)); }
html.phone .pgrid.can-up .pfade-t, html.phone .pgrid.can-down .pfade-b { opacity: 1; }
html.phone .prail { position: absolute; right: -7px; top: 3px; bottom: 3px; width: 2px; border-radius: 1px; background: var(--hair); pointer-events: none; }
html.phone .prail span { display: block; width: 100%; border-radius: 1px; background: var(--haze); will-change: transform; }
html.phone .pchev {
  position: absolute; left: 50%; bottom: 3px; width: 16px; height: 9px; margin-left: -8px;
  pointer-events: none; opacity: 0; transition: opacity .6s ease;
}
html.phone .pchev svg { display: block; width: 100%; height: 100%; fill: none; stroke: var(--bone); stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; animation: pchev 1.8s ease-in-out infinite; }
html.phone .pgrid.has-chev.can-down .pchev { opacity: .75; }
@keyframes pchev { 0%, 100% { transform: translateY(-1px); } 50% { transform: translateY(2px); } }

/* the grid tab: brings the sheet back */
html.phone .ptab {
  position: fixed; z-index: 4; left: 50%; bottom: var(--edge-b);
  width: 44px; height: 44px; margin-left: -22px;
  display: grid; place-items: center;
  border: 1px solid var(--hair2); background: var(--well);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .3s ease, transform .4s var(--ease), visibility 0s linear .3s;
}
html.phone .ptab svg { width: 15px; height: 15px; fill: var(--bone); }
html.phone .ptab .o { fill: none; stroke: var(--bone); stroke-width: 1; opacity: .7; }
html.phone body.is-entered.bb-folded .ptab { opacity: 1; visibility: visible; transform: none; transition: opacity .5s ease .25s, transform .5s var(--ease) .2s, visibility 0s; }

/* the vertical time slider: 2x at the top, still and then reverse at the foot */
html.phone .vslide {
  position: fixed; z-index: 3; right: 0;
  top: calc(var(--edge-t) + 38px); bottom: calc(var(--edge-b) + var(--foot-h) + 14px);
  width: calc(var(--vx) + 46px);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .35s ease, visibility 0s linear .35s;
}
html.phone body.is-entered.bb-folded .vslide { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity .6s ease .2s, visibility 0s; }
html.phone .vslide .time { position: absolute; inset: 0; height: auto; cursor: ns-resize; touch-action: none; }
html.phone .vslide .time-line { left: auto; right: var(--vx); top: 12px; bottom: 12px; width: 1px; height: auto; }
html.phone .vslide .time-heat { left: auto; right: calc(var(--vx) - 4px); top: 12px; bottom: 12px; width: 9px; height: auto; }
html.phone .vslide .time-heat .z {
  top: auto; bottom: auto; left: 0; right: 0;
  -webkit-mask-image: repeating-linear-gradient(0deg, #000 0 5px, transparent 5px 7px);
  mask-image: repeating-linear-gradient(0deg, #000 0 5px, transparent 5px 7px);
}
html.phone .vslide .z-rev { bottom: 0; height: 31%; width: auto; background: linear-gradient(0deg, rgba(34, 199, 216, .78), rgba(34, 199, 216, .3) 45%, rgba(11, 76, 94, .12)); }
html.phone .vslide .z-frz { bottom: 31.4%; height: 3.9%; width: auto; }
html.phone .vslide .z-one { bottom: 35.7%; height: 34%; width: auto; background: linear-gradient(0deg, rgba(20, 162, 122, .08), rgba(20, 162, 122, .14) 88%, rgba(20, 162, 122, .02)); }
html.phone .vslide .z-fast { bottom: 70.1%; height: 29.9%; width: auto; background: linear-gradient(0deg, rgba(20, 162, 122, .12), rgba(20, 162, 122, .35) 50%, rgba(179, 240, 60, .8)); }
html.phone .vslide .time-heat .zh { top: auto; bottom: auto; left: -3px; right: -3px; width: auto; }
html.phone .vslide .zh-frz {
  bottom: 26.667%; height: 11%;
  background: linear-gradient(10deg, transparent 0 30%, rgba(233, 255, 247, .16) 46%, rgba(34, 199, 216, .1) 54%, transparent 70%) 0 0 / 100% 300%,
    linear-gradient(0deg, transparent, rgba(34, 199, 216, .05) 20%, rgba(34, 199, 216, .05) 80%, transparent);
  animation: zhShimmerV 7.5s linear infinite;
}
html.phone .vslide .zh-amb {
  bottom: 37.667%; height: 17.333%;
  background: radial-gradient(120% 60% at 50% 50%, rgba(255, 176, 120, .34), rgba(236, 128, 92, .18) 45%, rgba(141, 156, 134, .07) 75%, transparent 100%);
}
@keyframes zhShimmerV { from { background-position: 0 100%, 0 0; } to { background-position: 0 -50%, 0 0; } }
html.phone .vslide .time-heat .cap { left: -3px; right: auto; width: 15px; height: 3px; }
html.phone .vslide .cap-l { top: auto; bottom: -1px; }
html.phone .vslide .cap-r { top: -1px; }
html.phone .vslide .time-fill { top: auto; left: -1px; width: 3px; bottom: 33.333%; height: calc((var(--f) - .33333) * 100%); }
html.phone .vslide.is-reverse .time-fill, html.phone .is-reverse .vslide .time-fill { left: -1px; width: 3px; bottom: calc(var(--f) * 100%); height: calc((.33333 - var(--f)) * 100%); }
html.phone .is-fast .vslide .time-fill { background: linear-gradient(0deg, var(--teal) 50%, #B3F03C); }
html.phone .vslide .tick { top: auto; left: -3px; width: 7px; height: 1px; margin: 0; }
html.phone .vslide .tick i { top: 50%; left: 14px; margin: 0; transform: translateY(-50%); }
html.phone .vslide .t-rev { bottom: 0; }
html.phone .vslide .t-still { bottom: 33.333%; left: -3px; width: 7px; height: 7px; margin: 0 0 -3px; }
html.phone .vslide .t-still i { left: 14px; }
html.phone .vslide .t-one { bottom: 66.667%; left: -6px; width: 13px; height: 1px; }
html.phone .vslide .t-one i { top: 50%; left: 17px; }
html.phone .vslide .t-two { bottom: 100%; margin-bottom: -1px; }
html.phone .vslide .t-two i { left: 14px; transform: translateY(-50%); }
html.phone .vslide .knob { left: 0; top: 0; width: 0; height: 100%; transform: translateY(33.333%); }
html.phone .vslide .knob-bar { width: 19px; height: 5px; margin: -2.5px 0 0 -9px; border-radius: 3px; }
html.phone .vslide .time-read { left: auto; right: 18px; top: 0; bottom: auto; transform: translateY(-50%); }

/* quiet: once the slider has been left alone, it and the name and footer fade to a ghost; any touch brings them back */
html.phone body.is-entered .name { transition: opacity .35s ease; }
html.phone body.is-entered .foot, html.phone body.is-entered.is-idle .foot { opacity: 1; transition: opacity .35s ease; }
html.phone body.is-entered.bb-ghost .name,
html.phone body.is-entered.bb-ghost .foot,
html.phone body.is-entered.bb-folded.bb-ghost .vslide { opacity: .18; transition: opacity 1.4s ease; }
html.phone body.is-entered.bb-folded.bb-ghost .ptab { opacity: .35; transition: opacity 1.4s ease; }
html.phone .foot { height: var(--foot-h); }
html.phone .links { gap: 0; margin-left: -12px; }
html.phone .links a { width: 44px; height: 44px; }
html.phone .links a svg { width: 16px; height: 16px; }
html.phone .ask-btn { height: 44px; padding-left: 14px; }

/* a phone on its side: fewer rows in view so the picture keeps most of the screen */
@media (orientation: landscape) {
  html.phone { --rowh: 42px; --vis: 2.3; }
  html.phone .deck { padding-top: 6px; }
  html.phone .deck-top { margin-bottom: 6px; }
  html.phone .hint { top: 17%; }
}

@media (prefers-reduced-motion: reduce) {
  html.phone .vslide .zh-frz { animation: none; }
  html.phone .pchev svg { animation: none; }
  html.phone body.is-entered.bb-folded .deck, html.phone body.is-entered.bb-ready .deck { transition-duration: .2s; }
}

/* =========================================================================
   DISCOVERY NUDGES (see nudge in main.js): a quiet visitor's unfound feature breathes a soft warm glow
   twice, then it is gone. The gold is the warm fleck of the eyes (#E7A65A), kin to the sunset glow.
   ========================================================================= */
.grid.nudge-halo, .pages.nudge-halo { position: relative; }
.nudge-halo { animation: bbNudgeLift 4.5s ease-in-out both; }
.nudge-halo::after {
  content: ""; position: absolute; inset: -6px; z-index: 1; pointer-events: none;
  border-radius: 7px;
  box-shadow: 0 0 0 1px rgba(231, 166, 90, .55), 0 0 18px 4px rgba(231, 166, 90, .45),
    0 0 44px 12px rgba(231, 166, 90, .18), inset 0 0 16px rgba(231, 166, 90, .2);
  opacity: 0; animation: bbNudgeHalo 4.5s ease-in-out both;
}
.time.nudge-halo::after { inset: -2px 4px; }
@keyframes bbNudgeHalo { 0% { opacity: 0; } 25% { opacity: .55; } 50% { opacity: .1; } 75% { opacity: .55; } 100% { opacity: 0; } }
@keyframes bbNudgeLift { 0%, 100% { filter: none; } 25%, 75% { filter: brightness(1.1); } 50% { filter: brightness(1.02); } }
@keyframes bbNudgeFade { 0%, 100% { opacity: 0; } 50% { opacity: .45; } }
@keyframes bbNudgeBreath { 0%, 100% { opacity: 0; } 50% { opacity: .55; } }
/* the sequencer is dimmed while nobody touches it; it comes partly back up for the nudge */
.is-entered.is-idle.bb-nudging .deck { opacity: .78; transition: opacity 1.2s ease; }
html.phone body.is-entered.is-idle.bb-nudging .deck { opacity: 1; }

/* phone, sheet folded: light runs slowly up the upright slider, then the thumb breathes once */
html.phone .vslide.nudge-track .time-line::after {
  content: ""; position: absolute; left: -11.5px; width: 24px; height: 120px; bottom: 0; margin-bottom: -60px;
  pointer-events: none; border-radius: 12px;
  background: radial-gradient(50% 50% at 50% 50%, rgba(231, 166, 90, .62), rgba(231, 166, 90, .24) 45%, rgba(231, 166, 90, 0) 72%);
  opacity: 0; animation: bbNudgeTravel 2.2s ease-in-out both;
}
@keyframes bbNudgeTravel { 0% { bottom: 0; opacity: 0; } 14% { opacity: 1; } 86% { opacity: 1; } 100% { bottom: 100%; opacity: 0; } }
html.phone .vslide.nudge-track .knob-bar::after {
  content: ""; position: absolute; inset: -7px -8px; border-radius: 9px; pointer-events: none;
  box-shadow: 0 0 0 1px rgba(231, 166, 90, .5), 0 0 14px 3px rgba(231, 166, 90, .4), 0 0 30px 8px rgba(231, 166, 90, .14);
  opacity: 0; animation: bbNudgeBreath 2.3s ease-in-out 2.2s both;
}
/* a ghosted slider or tab comes partly back up while it is being pointed out, then sinks again */
html.phone body.is-entered.bb-folded.bb-ghost .vslide.nudge-track { opacity: .6; transition: opacity .8s ease; }
html.phone body.is-entered.bb-folded.bb-ghost .ptab.nudge-halo { opacity: .85; transition: opacity .8s ease; }

@media (prefers-reduced-motion: reduce) {
  .nudge-halo { animation: none; }
  .nudge-halo::after { animation: bbNudgeFade 4.5s ease-in-out both; }
  html.phone .vslide.nudge-track .time-line::after { top: 0; bottom: 0; height: auto; margin: 0; left: -4px; width: 9px; animation: bbNudgeFade 4.5s ease-in-out both; }
  html.phone .vslide.nudge-track .knob-bar::after { animation: bbNudgeBreath 4.5s ease-in-out both; }
}
