:root {
  color-scheme: dark;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #030406;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

#stage {
  display: block;
  width: 100%;
  height: 100%;
  background: #030406;
}

.boot {
  position: fixed;
  inset: 0;
  z-index: 24;
  display: grid;
  place-items: center;
  pointer-events: none;
}

html.embedded .boot {
  display: none;
}

.boot-title {
  font-size: clamp(28px, 4.6vw, 44px);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: lowercase;
  color: rgba(236, 242, 248, 0.92);
  text-shadow: 0 2px 28px rgba(3, 4, 6, 0.55);
  transition:
    transform 1.15s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1) 0.18s;
}

.boot.is-phrase {
  background: #030406;
  transition: opacity 0.85s cubic-bezier(0.22, 1, 0.36, 1) 0.12s;
}

/* KSG hoodie lettering: Bookman-ish soft serif, warped, puff-printed. */
.boot.is-phrase .boot-title {
  position: relative;
  padding: 0 8px;
  font-family: "Fraunces", "Bookman Old Style", "ITC Bookman", Bookman, Georgia, serif;
  font-size: clamp(18px, 6.6vw, 56px);
  font-weight: 700;
  font-variation-settings: "SOFT" 100, "WONK" 1;
  letter-spacing: 0.01em;
  line-height: 1.2;
  white-space: nowrap;
  text-align: center;
  text-transform: none;
  color: #eef1ea;
  text-shadow:
    0 2px 0 rgba(150, 158, 150, 0.5),
    0 4px 10px rgba(0, 0, 0, 0.6),
    0 0 30px rgba(190, 230, 255, 0.16);
  filter: url(#boot-warp);
  animation: boot-in 0.9s cubic-bezier(0.22, 1, 0.36, 1) backwards;
}

.boot.is-fallback .boot-title {
  font-family: "Bookman Old Style", "ITC Bookman", Bookman, Georgia, serif;
}

/* Low-end devices: keep the wobble, skip the puff lighting. */
.boot.is-lite .boot-title {
  filter: url(#boot-warp-lite);
}

.boot.is-lite .boot-char.is-rising {
  filter: none;
}

/* Hidden until the hoodie font lands (index.html gives up after 2s). */
.boot.is-phrase:not(.is-ready) .boot-title {
  opacity: 0;
  animation: none;
}

.boot-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.boot-char {
  display: inline-block;
  white-space: pre;
}

/* While the phrase waits for the page, a slow shimmer ripples through the letters (a small lift and a
   brighter glint, one letter after the next) so it reads as alive, not stuck. Uses translate, not
   transform, so the exits (eaten, rising) still own transform; they switch it off when they start. */
.boot.is-phrase .boot-char {
  animation: boot-shimmer 2.2s ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * 0.06s);
}

@keyframes boot-shimmer {
  0%,
  100% {
    translate: 0 0;
    filter: brightness(1);
  }
  45% {
    translate: 0 -2px;
    filter: brightness(1.4) drop-shadow(0 0 6px rgba(190, 230, 255, 0.55));
  }
}

html.boot-leave .boot-char,
.boot-char.is-eaten,
.boot-char.is-rising,
.boot-title.is-haunting .boot-char {
  animation: none;
}

@keyframes boot-in {
  from {
    opacity: 0;
    transform: translate3d(0, 10px, 0) scale(0.98);
  }
}

html.boot-leave .boot.is-phrase {
  opacity: 0;
}

html.boot-leave .boot-title {
  transform: translate3d(0, -34vh, 0);
  opacity: 0;
}

/* pacman: letters are already eaten, so the phrase does not slide. */
html.boot-leave .boot[data-anim="pacman"] .boot-title,
html.boot-leave .boot[data-anim="rise"] .boot-title {
  transform: none;
}

.boot-char.is-eaten {
  opacity: 0;
  transform: scale(0.2);
  transition:
    opacity 0.08s linear,
    transform 0.08s linear;
}

.boot-pac {
  position: fixed;
  width: 0.92em;
  height: 0.92em;
  margin-top: -0.46em;
  border-radius: 50%;
  background: #ffd21f;
  animation: boot-chomp 0.16s linear infinite alternate;
  will-change: transform;
}

.boot-pac::after {
  content: "";
  position: absolute;
  left: 46%;
  top: 18%;
  width: 11%;
  height: 11%;
  border-radius: 50%;
  background: #030406;
}

@keyframes boot-chomp {
  from {
    clip-path: polygon(50% 50%, 100% 8%, 100% 0, 0 0, 0 100%, 100% 100%, 100% 92%);
  }
  to {
    clip-path: polygon(50% 50%, 100% 50%, 100% 0, 0 0, 0 100%, 100% 100%, 100% 50%);
  }
}

/* haunt: a ghost's shiver before the slide up. */
.boot.is-phrase .boot-title.is-haunting {
  animation: boot-haunt 0.9s steps(1, end);
}

@keyframes boot-haunt {
  0% { transform: translate3d(0, 0, 0); opacity: 1; }
  10% { transform: translate3d(-2px, 1px, 0) skewX(-2deg); opacity: 0.85; }
  20% { transform: translate3d(3px, -1px, 0) skewX(2deg); opacity: 1; }
  30% { transform: translate3d(-3px, 0, 0) skewX(-3deg); opacity: 0.6; }
  40% { transform: translate3d(2px, 2px, 0) skewX(1deg); opacity: 0.95; }
  50% { transform: translate3d(-4px, -1px, 0) skewX(-4deg); opacity: 0.5; }
  60% { transform: translate3d(4px, 1px, 0) skewX(3deg); opacity: 0.9; }
  70% { transform: translate3d(-3px, -2px, 0) skewX(-2deg); opacity: 0.45; }
  80% { transform: translate3d(3px, 0, 0) skewX(4deg); opacity: 0.85; }
  90% { transform: translate3d(-2px, 1px, 0) skewX(-1deg); opacity: 0.7; }
  100% { transform: translate3d(0, 0, 0); opacity: 1; }
}

/* rise: letters leave one at a time, like spirits. */
.boot-char.is-rising {
  opacity: 0;
  transform: translate3d(0, -1.4em, 0) scale(1.08);
  filter: blur(6px);
  transition:
    opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.8s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.7s ease-out;
}

.hud {
  position: fixed;
  left: 20px;
  bottom: 20px;
  z-index: 2;
  opacity: 1;
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  /* One fixed width so switching tabs never moves the tab row. A column, like an editor's
     inspector, so the picture stays visible beside it while you try filters. */
  width: min(460px, calc(100vw - 40px));
  padding: 16px 18px 14px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 14px;
  background: rgba(8, 10, 14, 0.78);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.38);
  backdrop-filter: blur(18px) saturate(1.1);
  -webkit-backdrop-filter: blur(18px) saturate(1.1);
  color: rgba(236, 242, 248, 0.9);
  letter-spacing: 0.08em;
  text-transform: lowercase;
  pointer-events: auto;
}

.title {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.1em;
}

/* Label and arrows stay on the first line; only the names wrap. */
.looks-strip {
  margin-top: 8px;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.4em 0.7em;
  font-size: 10px;
  letter-spacing: 0.12em;
}

.looks-strip[hidden] {
  display: none;
}

.looks-label {
  color: rgba(210, 222, 232, 0.4);
}

.looks-picks {
  display: flex;
  flex: 0 1 auto;
  min-width: 0;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4em 0.7em;
}

.looks-strip > .looks-label,
.looks-strip > #look-prev,
.looks-strip > #look-next {
  flex: none;
  align-self: flex-start;
}

.looks-strip button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: rgba(210, 222, 232, 0.4);
  cursor: pointer;
}

.looks-strip button[aria-pressed="true"] {
  color: #7be7ff;
}

.looks-strip #look-prev,
.looks-strip #look-next {
  color: rgba(210, 222, 232, 0.42);
}

.looks-strip #look-prev[hidden],
.looks-strip #look-next[hidden] {
  display: none;
}

.layers {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4em 0.7em;
  font-size: 10px;
  letter-spacing: 0.12em;
  color: rgba(210, 222, 232, 0.42);
}

.layers-label {
  margin-right: 0.55em;
  color: rgba(210, 222, 232, 0.4);
}

.layers button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: #7be7ff;
  cursor: pointer;
}

.layers button[aria-pressed="false"] {
  color: rgba(210, 222, 232, 0.34);
}

.hint {
  margin-top: 8px;
  font-size: 11px;
  max-width: none;
  line-height: 1.45;
  color: rgba(214, 226, 236, 0.7);
}

.controls {
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  align-items: center;
}

.controls label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 10px;
  color: rgba(220, 230, 238, 0.82);
}

.controls input[type="range"] {
  width: 88px;
  accent-color: #7be7ff;
}

.controls .check {
  margin-left: 4px;
}

/* The fill's colour: the track is the wheel; the swatch shows the held hue and dims while it drifts. */
.controls .tint {
  --tint: #7be7ff;
}
.controls .tint::before {
  content: "";
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  margin-right: 5px;
  vertical-align: -1px;
  background: var(--tint);
  opacity: 0.35;
}
.controls .tint.held::before {
  opacity: 1;
}
.controls .tint input[type="range"] {
  background: linear-gradient(to right, hsl(0 70% 55%), hsl(60 70% 55%), hsl(120 70% 55%), hsl(180 70% 55%), hsl(240 70% 55%), hsl(300 70% 55%), hsl(360 70% 55%));
  border-radius: 999px;
  height: 6px;
  -webkit-appearance: none;
  appearance: none;
}
.controls .tint input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--tint);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
}

#music-wrap[hidden],
#music-param[hidden],
.source-file[hidden],
#scrub-wrap[hidden] {
  display: none;
}

.source-file {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 0.55em;
  font-size: 10px;
  letter-spacing: 0.12em;
}

/* Party: camera or a sample clip, then the clip's own ‹ name › cycle. */
.source-pick {
  display: inline-flex;
  gap: 6px;
}

.source-file .source-pick button {
  min-height: 34px;
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 12px;
  letter-spacing: 0.035em;
  color: rgba(210, 222, 232, 0.72);
}

.source-file .source-pick button[aria-pressed="true"] {
  color: #7be7ff;
  background: rgba(123, 231, 255, 0.1);
}

html.party .source-file .clip-cycle {
  font-size: 12px;
  letter-spacing: 0.035em;
}

.clip-cycle {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
}

.source-file .clip-cycle button:first-child,
.source-file .clip-cycle button:last-child {
  color: rgba(210, 222, 232, 0.42);
}

.source-file [hidden] {
  display: none;
}

.clip-scrub {
  flex: 1 0 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  color: rgba(220, 230, 238, 0.82);
}

.clip-scrub input[type="range"] {
  width: min(220px, 52vw);
  accent-color: #7be7ff;
}

.source-file input[type="file"] {
  display: none;
}

.source-file button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: rgba(220, 230, 238, 0.82);
  cursor: pointer;
}

.source-file #clip-record[aria-pressed="true"] {
  color: #7be7ff;
}

html.record-on #clip-pick,
html.record-on .clip-cycle,
html.record-on .clip-scrub {
  opacity: 0.34;
  pointer-events: none;
}

.controls input[type="checkbox"] {
  accent-color: #7be7ff;
}

.filters {
  pointer-events: auto;
  margin-top: 7px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4em 0.7em;
  font-size: 10px;
  letter-spacing: 0.12em;
}

.filters-label {
  color: rgba(210, 222, 232, 0.4);
}

.filters button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: rgba(210, 222, 232, 0.4);
  cursor: pointer;
}

.filters button[aria-pressed="true"] {
  color: #7be7ff;
}

/* Active filter amounts sit side by side and wrap, instead of a line each. */
.filter-tray {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
}

.filter-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45em 0.7em;
  font-size: 10px;
  letter-spacing: 0.08em;
}

.filter-strip-name {
  min-width: 3.6em;
  color: #7be7ff;
}

/* With music on, a dot beside each amount breathes with what the sound is doing to it. */
.filter-strip label {
  position: relative;
}

.filter-strip label::after {
  content: "";
  position: absolute;
  right: -11px;
  top: 50%;
  width: 6px;
  height: 6px;
  margin-top: -3px;
  border-radius: 50%;
  background: #7be7ff;
  opacity: var(--live, 0);
  transform: scale(calc(0.5 + var(--live, 0) * 0.9));
  transition: opacity 0.08s linear, transform 0.08s linear;
  pointer-events: none;
}

#key-colour-wrap[hidden] {
  display: none;
}

.filter-strip label {
  display: flex;
  align-items: center;
  gap: 8px;
  color: rgba(220, 230, 238, 0.82);
}

.filter-strip input[type="range"] {
  width: 88px;
  accent-color: #7be7ff;
}

.filter-strip button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: rgba(210, 222, 232, 0.4);
  cursor: pointer;
}

.filter-strip button[aria-pressed="true"] {
  color: #7be7ff;
}

.filter-tune {
  flex: 1 0 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45em 0.7em;
}

.filter-thresh {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  color: rgba(220, 230, 238, 0.82);
  letter-spacing: 0.08em;
}

.save-look {
  pointer-events: auto;
  margin-top: 14px;
  font-size: 11px;
  text-transform: none;
  letter-spacing: 0.04em;
}

.save-look button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: 0.12em;
  text-transform: lowercase;
  color: rgba(220, 230, 238, 0.82);
  cursor: pointer;
}

.save-look button[type="submit"],
.save-look #save-update {
  color: #7be7ff;
}

.save-dot {
  color: rgba(210, 222, 232, 0.34);
  margin: 0 0.65em;
}

.save-fields {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 14px;
  align-items: center;
}

.save-fields[hidden],
.save-status[hidden],
.hud [hidden] {
  display: none !important;
}

.save-look input[type="text"] {
  width: 148px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(180, 210, 230, 0.28);
  padding: 2px 0;
  color: rgba(220, 236, 255, 0.88);
  font: inherit;
  letter-spacing: 0.06em;
  outline: none;
}

.save-look input[type="text"]::placeholder {
  color: rgba(180, 210, 230, 0.32);
  text-transform: lowercase;
}

.save-status {
  margin-top: 8px;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: lowercase;
  color: rgba(180, 210, 230, 0.55);
}

.save-status a {
  color: #7be7ff;
}

.photo {
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45em 0.7em;
  font-size: 10px;
  letter-spacing: 0.12em;
}

.photo button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: rgba(220, 230, 238, 0.82);
  cursor: pointer;
}

.photo #photo-go {
  color: rgba(228, 238, 246, 0.92);
}

.photo #record-go[aria-pressed="true"] {
  color: #7be7ff;
}

.photo-elapsed {
  color: #7be7ff;
}

.photo-elapsed[hidden] {
  display: none;
}

.photo-picks {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
}

.photo-picks button[aria-pressed="true"] {
  color: #7be7ff;
}

.photo-dot {
  color: rgba(210, 222, 232, 0.34);
}

.photo-flash {
  position: fixed;
  inset: 0;
  z-index: 48;
  background: #f4fbff;
  opacity: 0;
  pointer-events: none;
}

.photo-flash.is-on {
  animation: photo-pop 0.22s ease-out;
}

.photo-count {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  place-content: center;
  gap: 18px;
  pointer-events: auto;
  cursor: pointer;
  user-select: none;
}

.photo-count-num {
  font-size: clamp(140px, 32vw, 420px);
  font-weight: 500;
  line-height: 0.85;
  letter-spacing: 0.08em;
  color: rgba(236, 242, 248, 0.94);
  text-shadow:
    -0.08em 0 0 rgba(123, 231, 255, 0.35),
    0.1em 0.02em 0 rgba(255, 196, 120, 0.22),
    0 8px 48px rgba(3, 4, 6, 0.55);
}

.photo-count-num.is-tick {
  animation: photo-tick 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.photo-count-cancel {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: lowercase;
  color: rgba(214, 226, 236, 0.55);
  cursor: pointer;
}

.photo-count-cancel:hover {
  color: #fff;
}

.photo-sheet {
  position: fixed;
  inset: 0;
  z-index: 52;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  background: rgba(3, 4, 6, 0.82);
}

.photo-hero {
  display: grid;
  place-items: center;
  min-height: 0;
  overflow: hidden;
  padding: 28px 28px 12px;
}

.photo-hero img,
.photo-hero video {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.photo-hero img[hidden],
.photo-hero video[hidden] {
  display: none;
}

.photo-bar {
  position: relative;
  z-index: 1;
  margin: 0 20px 20px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 18px;
  padding: 14px 16px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 14px;
  background: rgba(8, 10, 14, 0.78);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.38);
  backdrop-filter: blur(18px) saturate(1.1);
  -webkit-backdrop-filter: blur(18px) saturate(1.1);
  letter-spacing: 0.12em;
  text-transform: lowercase;
}

.photo-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.photo-thumbs button {
  appearance: none;
  width: 56px;
  height: 36px;
  padding: 0;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  background: #030406;
  cursor: pointer;
}

.photo-thumbs button[aria-pressed="true"] {
  border-color: #7be7ff;
}

.photo-thumbs img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-actions {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7em 1.1em;
}

.photo-actions button {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 11px;
  letter-spacing: inherit;
  text-transform: inherit;
  color: rgba(220, 230, 238, 0.82);
  cursor: pointer;
}

.photo-actions button:hover {
  color: #fff;
}

.photo-actions #photo-save,
.photo-actions #photo-share {
  color: #7be7ff;
}

.photo-sheet[hidden],
.photo-count[hidden],
.photo-thumbs[hidden],
.photo-actions [hidden],
.record-pip[hidden] {
  display: none !important;
}

html.walkup .hud,
html.walkup .looks-dock,
html.walkup .sketch-nav,
html.photo-hold .hud,
html.photo-hold .looks-dock,
html.photo-hold .sketch-nav {
  opacity: 0;
  pointer-events: none;
}

html.photo-hold .hud,
html.photo-hold .looks-dock,
html.photo-hold .sketch-nav {
  transition-duration: 0.18s;
}

html.walkup.cursor-idle,
html.walkup.cursor-idle * {
  cursor: none !important;
}

html.walkup .party-gate:not([hidden]),
html.walkup .walkup-board {
  cursor: pointer;
}

.walkup-board {
  position: fixed;
  right: 18px;
  top: 18px;
  z-index: 8;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  pointer-events: auto;
}

.walkup-board[hidden] {
  display: none;
}

/* Threshold is the slider people actually reach for, so it sits low where a hand rests: bottom right,
   above the looks strip. Fixed on its own; the board still owns when it shows and fades. */
.walkup-thresh {
  position: fixed;
  right: 18px;
  bottom: calc(76px + env(safe-area-inset-bottom, 0px));
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.42);
  color: rgba(236, 242, 248, 0.78);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: lowercase;
  padding: 8px 14px;
  opacity: 0.5;
  cursor: pointer;
  transition:
    opacity 1.2s cubic-bezier(0.22, 1, 0.36, 1),
    color 0.2s ease,
    border-color 0.2s ease,
    background 0.2s ease;
}

.walkup-thresh input {
  width: 120px;
  accent-color: rgba(236, 242, 248, 0.88);
  cursor: pointer;
}

.walkup-mix {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.42);
  color: rgba(236, 242, 248, 0.78);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: lowercase;
  padding: 10px 14px;
  cursor: pointer;
  opacity: 0.5;
  transition:
    opacity 1.2s cubic-bezier(0.22, 1, 0.36, 1),
    color 0.2s ease,
    border-color 0.2s ease,
    background 0.2s ease;
}

.walkup-board.is-arrive .walkup-mix,
.walkup-board.is-arrive .walkup-thresh {
  opacity: 0.92;
}

.walkup-mix:hover,
.walkup-mix:focus-visible,
.walkup-thresh:hover,
.walkup-thresh:focus-within {
  opacity: 1;
  color: #fff;
  border-color: rgba(255, 255, 255, 0.4);
  background: rgba(8, 10, 14, 0.72);
}

/* Edit is the way into the mixer, so it reads as a control, not a quiet corner mark. */
.walkup-edit {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  opacity: 0.82;
  color: #fff;
  border-color: rgba(123, 231, 255, 0.45);
  background: rgba(123, 231, 255, 0.1);
}

.walkup-edit-icon {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.walkup-edit.is-open {
  border-color: rgba(255, 255, 255, 0.4);
  background: rgba(8, 10, 14, 0.72);
}

.walkup-edit.is-nudge {
  opacity: 1;
  animation: walkup-nudge 1.6s ease-in-out infinite;
}

@keyframes walkup-nudge {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(123, 231, 255, 0.5);
  }
  50% {
    box-shadow: 0 0 0 9px rgba(123, 231, 255, 0);
  }
}

/* One line at a time: how to change looks, then where to edit one. */
.walkup-tip {
  position: fixed;
  z-index: 8;
  margin: 0;
  padding: 9px 14px;
  border-radius: 10px;
  background: rgba(8, 10, 14, 0.78);
  color: #fff;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: 0 2px 16px rgba(0, 0, 0, 0.5);
  animation: walkup-tip-in 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.walkup-tip[hidden] {
  display: none;
}

.walkup-tip.is-looks {
  left: 50%;
  bottom: calc(184px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
}

.walkup-tip.is-edit {
  right: 18px;
  top: 70px;
  border: 1px solid rgba(123, 231, 255, 0.45);
}

/* Caret up at the edit button, which is the last thing in the corner. */
.walkup-tip.is-edit::before {
  content: "";
  position: absolute;
  right: 26px;
  top: -6px;
  width: 10px;
  height: 10px;
  background: rgba(8, 10, 14, 0.78);
  border-left: 1px solid rgba(123, 231, 255, 0.45);
  border-top: 1px solid rgba(123, 231, 255, 0.45);
  transform: rotate(45deg);
}

@keyframes walkup-tip-in {
  from {
    opacity: 0;
    translate: 0 6px;
  }
}

/* Walk-up shutter: the one obvious thing to do besides dance. Sits above the looks strip. */
/* Capture: photo / video above the shutter, the timer to its left. Sits above the looks strip. */
.walkup-capture {
  position: fixed;
  left: 50%;
  bottom: calc(64px + env(safe-area-inset-bottom, 0px));
  z-index: 8;
  display: grid;
  justify-items: center;
  gap: 8px;
  transform: translateX(-50%);
  pointer-events: auto;
  transition: opacity 0.4s ease;
}

.walkup-capture[hidden] {
  display: none;
}

.capture-modes {
  display: flex;
  gap: 4px;
}

.capture-modes[hidden] {
  display: none;
}

.capture-modes button,
.capture-timer {
  appearance: none;
  border: 0;
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.42);
  color: rgba(236, 242, 248, 0.6);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: lowercase;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.8);
  padding: 7px 12px;
  min-height: 32px;
  cursor: pointer;
}

.capture-modes button[aria-pressed="true"] {
  color: #fff;
  background: rgba(8, 10, 14, 0.72);
}

.capture-modes button[hidden] {
  display: none;
}

.capture-modes button:disabled,
.capture-timer:disabled {
  opacity: 0.35;
  cursor: default;
}

.capture-row {
  display: grid;
  grid-template-columns: minmax(64px, 1fr) auto minmax(64px, 1fr);
  align-items: center;
  gap: 14px;
}

.capture-row .capture-timer {
  justify-self: end;
}

.capture-row .capture-mic {
  justify-self: start;
}

.capture-timer {
  min-width: 52px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: rgba(236, 242, 248, 0.88);
  font-variant-numeric: tabular-nums;
}

.capture-toast {
  position: absolute;
  bottom: calc(100% + 10px);
  margin: 0;
  padding: 7px 12px;
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.78);
  color: #fff;
  font-size: 12px;
  letter-spacing: 0.06em;
  white-space: nowrap;
  pointer-events: none;
}

.capture-toast[hidden] {
  display: none;
}

.walkup-snap {
  display: grid;
  place-items: center;
  width: 58px;
  height: 58px;
  padding: 0;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  border: 3px solid rgba(236, 242, 248, 0.85);
  border-radius: 50%;
  background: rgba(8, 10, 14, 0.28);
  box-shadow: 0 2px 16px rgba(0, 0, 0, 0.5);
  cursor: pointer;
  opacity: 0.85;
  transition:
    opacity 0.4s ease,
    transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}

.walkup-snap-dot {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(236, 242, 248, 0.9);
  transition: transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}

.walkup-snap:hover,
.walkup-snap:focus-visible {
  opacity: 1;
}

.walkup-snap:active .walkup-snap-dot {
  transform: scale(0.86);
}

/* Video: a red dot; recording turns it into a stop square. */
.walkup-snap.is-video .walkup-snap-dot {
  background: #ff3b4e;
}

.walkup-snap.is-rec .walkup-snap-dot {
  width: 24px;
  height: 24px;
  border-radius: 5px;
  background: #ff3b4e;
}

.walkup-snap[hidden] {
  display: none;
}

/* The walk-up hides the pointer over the picture; the sheet still needs one. */
html.walkup .photo-sheet {
  cursor: auto;
}

/* Walk-up: a thumb on the screen while posing must not cancel the count; only "cancel" does. */
html.walkup .photo-count {
  pointer-events: none;
}

html.walkup .photo-count-cancel {
  pointer-events: auto;
  padding: 14px 18px;
}

/* Walk-up sheet: phone-sized targets, share and save as the obvious pills. */
html.walkup .photo-bar {
  justify-content: center;
}

html.walkup .photo-actions {
  margin-left: 0;
  justify-content: center;
  gap: 8px;
}

html.walkup .photo-actions button {
  min-height: 44px;
  padding: 0 16px;
  border-radius: 999px;
  font-size: 13px;
}

html.walkup .photo-actions #photo-save,
html.walkup .photo-actions #photo-share {
  border: 1px solid rgba(123, 231, 255, 0.45);
  background: rgba(123, 231, 255, 0.12);
}

html.walkup .photo-actions #photo-share {
  order: -1;
}

/* Walk-up looks: one strip, the current look centred, neighbours fading off the edges.
   Swipe the picture (or tap a name) to move it. */
.walkup-looks {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 8;
  overflow: hidden;
  padding: 10px 0;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: lowercase;
  pointer-events: auto;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 22%, #000 78%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 22%, #000 78%, transparent);
  transition: opacity 1.2s cubic-bezier(0.22, 1, 0.36, 1);
}

.walkup-looks.is-quiet {
  opacity: 0.35;
}

.walkup-looks .looks-picks {
  flex-wrap: nowrap;
  gap: 0 1.8em;
  width: max-content;
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}

.walkup-looks button {
  --d: 0;
  appearance: none;
  border: 0;
  background: none;
  padding: 6px 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  white-space: nowrap;
  color: rgba(236, 242, 248, 0.7);
  opacity: max(0.25, calc(1 - var(--d) * 0.25));
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.85);
  cursor: pointer;
  transition:
    color 0.3s ease,
    opacity 0.45s ease;
}

.walkup-looks button:hover,
.walkup-looks button:focus-visible {
  color: #fff;
}

.walkup-looks button[aria-pressed="true"] {
  color: #fff;
  opacity: 1;
}

.walkup-looks[hidden] {
  display: none;
}

html.walkup .walkup-looks {
  cursor: pointer;
}

/* Horizontal swipes on the picture change the look, so the browser must not pan or go back. */
html.walkup #stage,
html.walkup .walkup-looks {
  touch-action: none;
}

html.photo-hold .walkup-board,
html.photo-hold .walkup-tip,
html.booting .walkup-tip,
html:not(.walkup) .walkup-tip,
html.photo-hold .walkup-looks,
html.photo-hold .walkup-capture,
html.booting .walkup-board,
html.booting .walkup-looks,
html.booting .walkup-capture,
html.booting .party-gate {
  opacity: 0;
  pointer-events: none;
}

.party-gate {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: grid;
  place-items: center;
  background: transparent;
  pointer-events: auto;
}

.party-gate[hidden] {
  display: none;
}

.party-gate button {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.72);
  color: rgba(236, 242, 248, 0.94);
  font: inherit;
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: lowercase;
  padding: 14px 22px;
  cursor: pointer;
}

.party-gate-picks {
  display: grid;
  justify-items: center;
  gap: 14px;
}

/* The camera is the piece; the clip is the way in for people who will not grant it. */
.party-gate .party-gate-clip {
  border-color: transparent;
  background: rgba(8, 10, 14, 0.5);
  color: rgba(236, 242, 248, 0.7);
  font-size: 12px;
  letter-spacing: 0.12em;
  padding: 10px 16px;
}

.party-gate button:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.4);
}

html.record-on #photo-go,
html.record-on .photo-picks {
  opacity: 0.34;
  pointer-events: none;
}

html.record-on #record-go {
  opacity: 1;
  pointer-events: auto;
}

.record-pip {
  position: fixed;
  top: 18px;
  left: 50%;
  z-index: 36;
  display: flex;
  align-items: center;
  gap: 0.5em;
  transform: translateX(-50%);
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: lowercase;
  color: rgba(236, 242, 248, 0.92);
  text-shadow: 0 2px 18px rgba(3, 4, 6, 0.55);
  pointer-events: none;
  user-select: none;
}

.record-pip-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #7be7ff;
  box-shadow: 0 0 12px rgba(123, 231, 255, 0.7);
  animation: rec-pulse 1.1s ease-in-out infinite;
}

@keyframes photo-pop {
  0% {
    opacity: 0.92;
  }
  100% {
    opacity: 0;
  }
}

@keyframes rec-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.28;
  }
}

@keyframes photo-tick {
  from {
    transform: scale(1.08);
    opacity: 0.65;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

body.embedded .hud {
  display: none;
}

.looks-dock {
  position: fixed;
  top: 68px;
  right: 0;
  bottom: 20px;
  z-index: 12;
  opacity: 1;
  transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}

html.booting .hud,
html.booting .looks-dock,
html.booting .sketch-nav {
  opacity: 0;
  pointer-events: none;
}

.looks-dock[hidden] {
  display: none;
}

.looks-tab {
  position: absolute;
  top: 28%;
  right: 0;
  z-index: 2;
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-right: 0;
  border-radius: 12px 0 0 12px;
  background: rgba(8, 10, 14, 0.86);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.38);
  backdrop-filter: blur(18px) saturate(1.1);
  -webkit-backdrop-filter: blur(18px) saturate(1.1);
  color: rgba(236, 242, 248, 0.9);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: lowercase;
  writing-mode: vertical-rl;
  padding: 16px 8px;
  cursor: pointer;
}

.looks-tab:hover {
  color: #fff;
}

.looks-tab[aria-expanded="true"] {
  color: #7be7ff;
}

.looks-drawer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(320px, 84vw);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 16px 18px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-right: 0;
  border-radius: 14px 0 0 14px;
  background: rgba(8, 10, 14, 0.86);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.38);
  backdrop-filter: blur(18px) saturate(1.1);
  -webkit-backdrop-filter: blur(18px) saturate(1.1);
  color: rgba(236, 242, 248, 0.9);
  letter-spacing: 0.08em;
  text-transform: lowercase;
  overflow: hidden;
  transform: translateX(100%);
  transition: transform 0.42s cubic-bezier(0.16, 1, 0.3, 1);
}

.looks-dock.is-open .looks-drawer {
  transform: none;
}

.looks-kicker {
  font-size: 10px;
  letter-spacing: 0.16em;
  color: rgba(210, 222, 232, 0.4);
}

.looks-help {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: rgba(210, 222, 232, 0.34);
}

.looks-list {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
  overflow: auto;
}

.looks-list button {
  appearance: none;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  border: 0;
  background: none;
  padding: 8px 4px;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: left;
  color: rgba(228, 238, 246, 0.88);
  cursor: pointer;
}

.looks-list button:hover {
  color: #fff;
}

.looks-list button[aria-pressed="true"] {
  color: #7be7ff;
}

.looks-list .looks-name {
  font-size: 11px;
}

.looks-list .looks-note {
  max-width: 100%;
  overflow: hidden;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: rgba(210, 222, 232, 0.42);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.looks-list button[aria-pressed="true"] .looks-note {
  color: rgba(123, 231, 255, 0.55);
}

.looks-status {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: rgba(180, 210, 230, 0.55);
}

.looks-status[hidden],
.looks-preview[hidden] {
  display: none;
}

.looks-preview {
  position: relative;
  flex: 0 0 auto;
  aspect-ratio: 16 / 10;
  width: 100%;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 10px;
  background: #030406;
}

.looks-preview iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  pointer-events: none;
}

.looks-preview-hit {
  position: absolute;
  inset: 0;
  z-index: 1;
}

body.embedded .looks-dock,
body.embedded .photo-sheet,
body.embedded .photo-count,
body.embedded .photo-flash,
body.embedded .record-pip {
  display: none;
}

/* The panel never runs off the screen; it scrolls instead, and fades at the bottom while more is below. */
.hud {
  max-height: calc(100vh - 40px);
  max-height: calc(100dvh - 40px);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Keyboard focus scrolls rows clear of the fade. */
  scroll-padding-bottom: 32px;
}

/* An overlay, not a mask, so the panel keeps its edge and shadow. Sits over the bottom padding. */
.hud.has-more::after {
  content: "";
  position: sticky;
  bottom: -14px;
  display: block;
  height: 32px;
  margin-top: -32px;
  background: linear-gradient(transparent, rgba(8, 10, 14, 0.92));
  pointer-events: none;
}

/* Cyan always means on. Hover only where there is a real hover, and only as a tint on things that are off. */
@media (hover: hover) {
  .hud button:not([aria-pressed]):hover {
    color: #fff;
  }

  .hud button[aria-pressed="false"]:hover {
    color: rgba(236, 242, 248, 0.75);
  }

  /* Actions, not toggles: brighten, even when they carry aria-pressed="false". */
  .photo #record-go:not([aria-pressed="true"]):hover,
  .source-file #clip-record:not([aria-pressed="true"]):hover,
  .photo #photo-go:hover,
  .save-look #save-update:hover,
  .looks-strip #look-prev:hover,
  .looks-strip #look-next:hover {
    color: #fff;
  }
}

.photo-picks button[aria-pressed="false"] {
  color: rgba(210, 222, 232, 0.4);
}

/* Party mixer: strangers get the looks and the knobs, not the desk tools. The corner board
   already has threshold, the shutter takes photos, and invert stays off for walk-up. */
html.party:not(.desk) #threshold-param,
html.party:not(.desk) #invert-param,
html.party:not(.desk) #photo {
  display: none !important;
}

/* Phones and tablets: the panel caps at a bit over half the screen, so the picture stays in view. */
@media (pointer: coarse) {
  .hud {
    max-height: 60vh;
    max-height: 60dvh;
  }

  /* There is more below: say so in words, not only the fade. */
  .hud.has-more::after {
    content: "more ↓";
    width: 84px;
    height: 26px;
    margin: -34px auto 8px;
    bottom: 0;
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 999px;
    font-size: 11px;
    line-height: 24px;
    letter-spacing: 0.14em;
    text-align: center;
    color: rgba(236, 242, 248, 0.85);
    background: rgba(8, 10, 14, 0.92);
  }
}

/* Touch (any touch pointer, so touchscreen laptops too): finger-sized hit areas. */
@media (any-pointer: coarse) {
  /* Looks: one line that scrolls sideways between the arrows, like the walk-up strip. */
  .hud .looks-picks {
    position: relative;
    flex: 1 1 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
  }

  .hud .looks-picks::-webkit-scrollbar {
    display: none;
  }

  .hud .looks-picks button {
    flex: none;
    white-space: nowrap;
    scroll-snap-align: center;
  }

  .looks-strip,
  .looks-picks,
  .filters,
  .layers {
    gap: 0 0.9em;
  }

  .hud .looks-strip #look-prev,
  .hud .looks-strip #look-next {
    min-width: 32px;
  }

  .hud input[type="range"]:not(#scrub) {
    width: 130px;
  }

  .hud input[type="range"] {
    min-height: 32px;
  }

  .hud input[type="checkbox"] {
    width: 18px;
    height: 18px;
  }

  /* 16px keeps iOS from zooming the page when the field takes focus. */
  .save-look input[type="text"] {
    font-size: 16px;
  }

  .hud .looks-strip button,
  .hud .filters button,
  .hud .layers button,
  .hud .filter-strip button,
  .hud .photo button,
  .hud .source-file button,
  .hud .save-look button {
    min-height: 32px;
    padding: 0 2px;
  }

  .looks-label,
  .filters-label,
  .layers-label {
    line-height: 32px;
  }
}

/* Narrow screens: the bottom belongs to the shutter and the looks strip, so threshold stands up on the
   right edge at mid height, under the thumb. Rotated as a whole so it works in every browser; low is
   less, high is more. The translate puts its rotated edge 12px from the side. */
@media (max-width: 760px) {
  .walkup-thresh {
    right: 12px;
    top: 50%;
    bottom: auto;
    height: 34px;
    box-sizing: border-box;
    padding: 0 12px;
    letter-spacing: 0.12em;
    transform: translate(calc(50% - 17px), -50%) rotate(-90deg);
  }

  .walkup-thresh input {
    width: 150px;
  }
}

/* Phones: keep random and edit on one line. */
@media (max-width: 480px) {
  .walkup-board {
    right: 12px;
    top: 12px;
    flex-wrap: nowrap;
    gap: 6px;
  }

  .walkup-mix {
    letter-spacing: 0.12em;
    padding: 10px 12px;
  }

  .walkup-tip {
    font-size: 12px;
  }

  .walkup-tip.is-edit {
    right: 12px;
    top: 110px;
  }

  .walkup-tip.is-edit::before {
    right: 22px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .looks-tab,
  .looks-drawer,
  .boot-title,
  .hud,
  .looks-dock,
  .sketch-nav,
  .walkup-board,
  .walkup-mix,
  .walkup-thresh,
  .walkup-looks,
  .walkup-looks .looks-picks,
  .walkup-snap,
  .walkup-snap-dot {
    transition: none;
  }

  .walkup-edit.is-nudge,
  .walkup-tip {
    animation: none;
  }

  .photo-flash.is-on,
  .photo-count-num.is-tick,
  .record-pip-dot {
    animation: none;
  }

  .photo-flash.is-on {
    opacity: 0;
  }

  html.booting:not(.walkup) .hud,
  html.booting:not(.walkup) .looks-dock,
  html.booting:not(.walkup) .sketch-nav {
    opacity: 1;
    pointer-events: auto;
  }

  .boot {
    display: none;
  }
}

/* Mixer tiers share one stage; source and capture controls stay outside the tabs. */
.mixer-tabs {
  display: flex;
  gap: 24px;
  margin-top: 14px;
  border-bottom: 1px solid rgba(210, 222, 232, 0.14);
}

.mixer-tabs button {
  appearance: none;
  position: relative;
  border: 0;
  padding: 10px 0 12px;
  background: none;
  color: rgba(210, 222, 232, 0.65);
  font: inherit;
  font-size: 13px;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.mixer-tabs button[aria-selected="true"] {
  color: #7be7ff;
}

.mixer-tabs button[aria-selected="true"]::after {
  content: "";
  position: absolute;
  height: 2px;
  bottom: -1px;
  left: 0;
  right: 0;
  background: currentColor;
}

.mixer-tabs button:focus-visible,
.mixer-panel:focus-visible,
.mixer-panel button:focus-visible {
  outline: 2px solid #7be7ff;
  outline-offset: 3px;
}

/* Panels stack in one cell, so the stage is as tall as the tallest tab and the panel holds its size. */
.mixer-stage {
  display: grid;
  /* minmax(0, …): the looks row is one long scroller on touch; it must not set the panel width. */
  grid-template-columns: minmax(0, 1fr);
}

.mixer-panel {
  grid-area: 1 / 1;
  min-width: 0;
  padding: 16px 0;
  border-bottom: 1px solid rgba(210, 222, 232, 0.14);
}

.mixer-panel [hidden] {
  display: none !important;
}

/* Inactive panels keep their height but drop out of sight, focus, and the accessibility tree. */
.mixer-stage > .mixer-panel[hidden] {
  display: block !important;
  visibility: hidden;
}

.mixer-empty {
  font-size: 12px;
  letter-spacing: 0.025em;
  line-height: 1.5;
  color: rgba(236, 242, 248, 0.86);
}

.mixer-panel .looks-strip,
.mixer-panel .filters,
.mixer-panel .layers {
  margin-top: 0;
  gap: 6px;
  font-size: 12px;
  letter-spacing: 0.035em;
}

.mixer-panel .looks-label {
  display: none;
}

.mixer-panel .filters-label,
.mixer-panel .layers-label {
  flex-basis: 100%;
  margin: 0 0 3px;
  color: rgba(210, 222, 232, 0.65);
  line-height: 1.5;
}

.mixer-panel .layers {
  margin-top: 12px;
}

.mixer-panel .filters-label {
  display: flex;
  align-items: center;
  gap: 14px;
}

/* An action, not a toggle, so it stays off cyan. */
.mixer-panel .filter-shuffle {
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  color: rgba(236, 242, 248, 0.86);
}

@media (pointer: fine) {
  .mixer-panel .filter-shuffle {
    min-height: 26px;
    padding: 2px 12px;
  }
}

.mixer-panel .looks-picks {
  gap: 6px;
}

.mixer-panel .looks-strip button,
.mixer-panel .filters button,
.mixer-panel .layers button {
  min-height: 34px;
  padding: 6px 10px;
  border-radius: 6px;
  color: rgba(210, 222, 232, 0.72);
}

.mixer-panel button[aria-pressed="true"] {
  color: #7be7ff;
  background: rgba(123, 231, 255, 0.1);
}

.mixer-panel .filter-strip,
.mixer-panel .controls label {
  font-size: 12px;
  letter-spacing: 0.025em;
}

.mixer-panel .filter-tray {
  margin: 14px 0 18px;
  gap: 14px 24px;
}

@media (any-pointer: coarse) {
  .hud .mixer-tabs button,
  .hud .mixer-panel button,
  .hud .mixer-panel input[type="range"] {
    min-height: 44px;
  }

  .hud .mixer-panel button {
    padding: 8px 10px;
  }
}

/* Filters tab: the mix you have (a stack, each row with its own slider) stays pinned at the top;
   the library of everything you could add scrolls under it, grouped by what it does. */
.mix-stack {
  position: sticky;
  top: -16px;
  z-index: 2;
  margin: -16px -18px 0;
  padding: 16px 18px 12px;
  background: rgba(10, 12, 16, 0.97);
  border-bottom: 1px solid rgba(210, 222, 232, 0.14);
}

.mix-head {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  letter-spacing: 0.035em;
}

.mix-label {
  color: rgba(236, 242, 248, 0.86);
}

.mix-count {
  color: rgba(210, 222, 232, 0.55);
  font-variant-numeric: tabular-nums;
}

.mix-head .filter-shuffle {
  margin-left: auto;
  appearance: none;
  background: none;
  font: inherit;
  cursor: pointer;
}

.mixer-panel .filter-tray {
  display: grid;
  gap: 4px;
  margin: 10px 0 0;
}

.mixer-panel .filter-tray[hidden],
.mix-empty[hidden],
.mix-note[hidden] {
  display: none;
}

.mixer-panel .filter-tray .filter-strip {
  display: grid;
  grid-template-columns: 5.5em minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 10px;
}

.mixer-panel .filter-tray .filter-strip .filter-tune {
  grid-column: 1 / -1;
}

.mixer-panel .filter-tray .filter-strip label {
  display: block;
}

.mixer-panel .filter-tray input[type="range"] {
  width: 100%;
}

.midi-status {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: rgba(220, 230, 238, 0.72);
  max-width: 24em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.filter-strip-lock {
  appearance: none;
  border: 0;
  background: none;
  min-width: 30px;
  min-height: 34px;
  padding: 0;
  border-radius: 6px;
  color: rgba(210, 222, 232, 0.38);
  cursor: pointer;
  display: grid;
  place-items: center;
}
.filter-strip-lock svg {
  width: 12px;
  height: 12px;
}
.filter-strip-lock .lock-shackle {
  transform-origin: 4px 5px;
  transition: transform 0.15s;
  transform: translateX(1.4px) rotate(-18deg);
}
.filter-strip-lock[aria-pressed="true"] {
  color: #7be7ff;
}
.filter-strip-lock[aria-pressed="true"] .lock-shackle {
  transform: none;
}
.filter-strip-lock:hover {
  color: rgba(220, 230, 238, 0.9);
}
.filter-strip.is-locked .filter-strip-name {
  text-decoration: underline dotted rgba(123, 231, 255, 0.6);
  text-underline-offset: 3px;
}

.filter-strip-remove {
  appearance: none;
  border: 0;
  background: none;
  min-width: 34px;
  min-height: 34px;
  border-radius: 6px;
  color: rgba(210, 222, 232, 0.6);
  font: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.mix-empty,
.mix-note {
  margin: 10px 0 0;
  font-size: 12px;
  letter-spacing: 0.025em;
  color: rgba(210, 222, 232, 0.6);
}

.mix-note {
  color: #ffd27a;
}

.filter-jump {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 14px 0 4px;
}

.filter-jump button {
  appearance: none;
  border: 0;
  background: none;
  padding: 4px 0;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.035em;
  color: rgba(210, 222, 232, 0.65);
  text-decoration: underline;
  text-decoration-color: rgba(210, 222, 232, 0.25);
  text-underline-offset: 4px;
  cursor: pointer;
}

.mixer-panel .filters {
  display: block;
  margin-top: 0;
}

.filter-group {
  /* Jumping to a group lands it just under the pinned mix, not behind it. */
  scroll-margin-top: var(--mix-stack-h, 140px);
  padding-top: 12px;
}

.filter-group-label {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.12em;
  color: rgba(210, 222, 232, 0.5);
}

.filter-group-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.mixer-panel .filters button[aria-disabled] {
  opacity: 0.35;
}

.mixer-panel .filters button.is-preview {
  color: #fff;
  box-shadow: inset 0 0 0 1px rgba(123, 231, 255, 0.55);
}

@media (hover: hover) {
  .filter-strip-remove:hover,
  .filter-jump button:hover {
    color: #fff;
  }
}

@media (any-pointer: coarse) {
  .hud .filter-strip-remove,
  .hud .filter-jump button {
    min-height: 44px;
    min-width: 44px;
  }

  .mix-stack {
    top: -16px;
  }
}

/* Phones: the panel is half the screen, too short to pin five slider rows. Pin the count and the
   category jumps instead; the stack sits at the top of the scroll and chips show what is on. */
@media (pointer: coarse) {
  .mix-stack {
    position: static;
    margin: 0;
    padding: 0 0 12px;
    background: none;
  }

  .filter-jump {
    position: sticky;
    top: -16px;
    z-index: 2;
    margin: 12px -18px 0;
    padding: 4px 18px;
    background: rgba(10, 12, 16, 0.97);
    border-bottom: 1px solid rgba(210, 222, 232, 0.14);
  }

  .filter-jump {
    flex-wrap: nowrap;
    gap: 0 14px;
  }

  .hud .filter-jump button {
    min-width: 0;
  }

  .filter-jump::after {
    content: attr(data-count);
    margin-left: auto;
    white-space: nowrap;
    align-self: center;
    font-size: 12px;
    color: rgba(210, 222, 232, 0.55);
    font-variant-numeric: tabular-nums;
  }

  .filter-group {
    scroll-margin-top: 52px;
  }
}

/* Hands-off rows: auto shuffle under the mix head, next clip beside the clip picker. */
.key-pick {
  flex-basis: 100%;
}

.mix-auto,
.key-pick,
.clip-auto {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  letter-spacing: 0.035em;
}

.mix-auto {
  margin-top: 8px;
}

/* How looks change: a slide, or a morph over seconds or bars (bars need a tempo). */
.look-change {
  margin: 0 0 10px;
  font-size: 12px;
  letter-spacing: 0.035em;
}

.look-change button:disabled {
  opacity: 0.35;
  cursor: default;
}

.clip-auto {
  flex-basis: 100%;
}

.clip-auto[hidden] {
  display: none;
}

.mix-auto-label {
  margin-right: 6px;
  color: rgba(210, 222, 232, 0.55);
}

.mix-auto button,
.key-pick button,
.source-file .clip-auto button {
  appearance: none;
  border: 0;
  border-radius: 6px;
  background: none;
  padding: 4px 8px;
  font: inherit;
  color: rgba(210, 222, 232, 0.72);
  cursor: pointer;
}

.mix-auto button[aria-pressed="true"],
.key-pick button[aria-pressed="true"],
.source-file .clip-auto button[aria-pressed="true"] {
  color: #7be7ff;
  background: rgba(123, 231, 255, 0.1);
}

.mix-head #mix-save,
.mix-head #mix-share {
  margin-left: 0;
}

#mic-param[hidden],
#mic-wrap[hidden] {
  display: none;
}

/* Which camera, which input: only when the machine has more than one. */
.device-pick {
  max-width: 100%;
  min-height: 30px;
  font: inherit;
  font-size: 12px;
  color: rgba(220, 230, 238, 0.9);
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(210, 222, 232, 0.16);
  border-radius: 6px;
  padding: 0 6px;
}
.device-pick:focus {
  outline: none;
  border-color: rgba(123, 231, 255, 0.55);
}
.device-pick[hidden] {
  display: none;
}

@media (any-pointer: coarse) {
  .hud .mix-auto button,
  .hud .key-pick button,
  .hud .clip-auto button {
    min-height: 40px;
    min-width: 44px;
  }
}

/* Walk-up: the corner board owns the top edge, so the recording timer sits just under it. */
html.party .record-pip {
  top: calc(64px + env(safe-area-inset-top, 0px));
}

/* Clip loading: one word in the hoodie lettering, shedding coloured afterimages like the strobe ghosts. */
.clip-loader {
  position: fixed;
  inset: 0;
  z-index: 7;
  display: grid;
  place-items: center;
  background: rgba(3, 4, 6, 0.55);
  pointer-events: none;
}

.clip-loader[hidden] {
  display: none;
}

.clip-loader-word {
  margin: 0;
  font-family: "Fraunces", "Bookman Old Style", "ITC Bookman", Bookman, Georgia, serif;
  font-size: clamp(22px, 6vw, 44px);
  font-weight: 700;
  font-variation-settings: "SOFT" 100, "WONK" 1;
  color: #eef1ea;
  animation: clip-ghosts 1.4s ease-in-out infinite;
}

@keyframes clip-ghosts {
  0%,
  100% {
    text-shadow:
      0 0 0 rgba(123, 231, 255, 0),
      0 0 0 rgba(255, 59, 160, 0),
      0 0 0 rgba(255, 210, 122, 0);
  }
  50% {
    text-shadow:
      -14px 0 2px rgba(123, 231, 255, 0.55),
      14px 0 2px rgba(255, 59, 160, 0.45),
      0 -10px 3px rgba(255, 210, 122, 0.3);
  }
}

@media (prefers-reduced-motion: reduce) {
  .clip-loader-word {
    animation: none;
  }
}

/* Look previews: still cards rendered on a sample clip. A drawer on walk-up, a grid in the looks tab. */
.look-card {
  appearance: none;
  flex: none;
  display: grid;
  gap: 6px;
  width: 128px;
  padding: 0;
  border: 0;
  background: none;
  color: rgba(236, 242, 248, 0.72);
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-align: left;
  cursor: pointer;
}

.look-card img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
}

.look-card-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.look-card[aria-pressed="true"] {
  color: #7be7ff;
}

.look-card[aria-pressed="true"] img {
  box-shadow: 0 0 0 2px #7be7ff;
}

.walkup-drawer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9;
  padding: 18px 0 calc(18px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(transparent, rgba(3, 4, 6, 0.88) 28%);
  touch-action: pan-x;
  animation: drawer-in 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.walkup-drawer[hidden] {
  display: none;
}

.walkup-drawer .look-cards {
  display: flex;
  gap: 12px;
  padding: 0 16px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}

.walkup-drawer .look-cards::-webkit-scrollbar {
  display: none;
}

.walkup-drawer .look-card {
  scroll-snap-align: center;
}

@media (min-width: 700px) {
  .walkup-drawer .look-card {
    width: 168px;
  }
}

@keyframes drawer-in {
  from {
    transform: translateY(40px);
    opacity: 0;
  }
}

html.drawer-open .walkup-looks,
html.drawer-open .walkup-capture,
html.drawer-open .walkup-tip {
  opacity: 0;
  pointer-events: none;
}

html.photo-hold .walkup-drawer,
html.booting .walkup-drawer {
  display: none;
}

.look-cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(116px, 1fr));
  gap: 12px;
  margin-top: 12px;
}

.look-cards-grid .look-card {
  width: auto;
}

@media (prefers-reduced-motion: reduce) {
  .walkup-drawer {
    animation: none;
  }
}

/* Party: auto shuffle sits in the source block, under next clip. */
.source-file .mix-auto {
  flex-basis: 100%;
  margin-top: 0;
}

.mic-meter {
  --level: 0;
  --cut: 0.5;
  position: relative;
  display: inline-block;
  width: 56px;
  height: 8px;
  margin-left: 4px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
  vertical-align: middle;
}

.mic-meter-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: calc(var(--level) * 100%);
  background: rgba(210, 222, 232, 0.5);
}

.mic-meter.is-hot .mic-meter-fill {
  background: #7be7ff;
}

/* The visualizer has no hard cut any more; the tick stays out of the way. */
.mic-meter-cut {
  display: none;
  position: absolute;
  top: -1px;
  bottom: -1px;
  left: calc(var(--cut) * 100%);
  width: 2px;
  background: #ffd27a;
}

/* Layers tab: video placement on top, then one row per layer grouped by where it sits. */
.layer-group + .layer-group,
.layers .layer-group {
  margin-top: 12px;
}

.mixer-panel .layers {
  display: block;
  margin-top: 0;
}

.video-pick {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.video-pick button {
  appearance: none;
  border: 0;
  border-radius: 6px;
  background: none;
  min-height: 34px;
  padding: 6px 10px;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.035em;
  color: rgba(210, 222, 232, 0.72);
  cursor: pointer;
}

.video-pick button[aria-pressed="true"] {
  color: #7be7ff;
  background: rgba(123, 231, 255, 0.1);
}

.layer-amt {
  display: block;
  margin-top: 6px;
}

.layer-amt[hidden] {
  display: none;
}

.layer-amt input,
.layer-row input[type="range"] {
  width: 100%;
  accent-color: #7be7ff;
}

.layer-row {
  display: grid;
  grid-template-columns: 6em minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  min-height: 36px;
}

.layer-row input[hidden] {
  display: none;
}

.mixer-panel .layer-row button {
  justify-self: start;
}

@media (any-pointer: coarse) {
  .hud .video-pick button {
    min-height: 44px;
  }
}

/* Source switch, top left: which clip (‹ name ›) and the way to yourself (use camera / sample clips).
   On phones the board fills the top row, so this sits on a second row under it. */
.walkup-source {
  position: fixed;
  left: 18px;
  top: 18px;
  z-index: 8;
  display: flex;
  align-items: center;
  gap: 8px;
  pointer-events: auto;
}

.walkup-source[hidden],
.walkup-clip[hidden] {
  display: none;
}

.walkup-clip {
  display: flex;
  align-items: center;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.42);
  color: rgba(236, 242, 248, 0.88);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: lowercase;
}

.walkup-clip button {
  appearance: none;
  border: 0;
  background: none;
  color: rgba(236, 242, 248, 0.6);
  font: inherit;
  font-size: 14px;
  min-width: 34px;
  min-height: 34px;
  cursor: pointer;
}

.walkup-clip-name {
  min-width: 5.5em;
  text-align: center;
}

/* The way in: lit like edit, because trying it on yourself is the point. */
.walkup-cam {
  opacity: 0.88;
  color: #fff;
  border-color: rgba(255, 210, 122, 0.5);
  background: rgba(255, 210, 122, 0.1);
}

.walkup-tip.is-camera {
  left: 18px;
  top: 70px;
  border: 1px solid rgba(255, 210, 122, 0.5);
}

.walkup-tip.is-help {
  border: 1px solid rgba(236, 242, 248, 0.45);
}

.walkup-tip.is-help::before,
.walkup-tip.is-camera::before {
  content: "";
  position: absolute;
  left: var(--caret-x, 40px);
  top: -6px;
  width: 10px;
  height: 10px;
  background: rgba(8, 10, 14, 0.78);
  border-left: 1px solid rgba(255, 210, 122, 0.5);
  border-top: 1px solid rgba(255, 210, 122, 0.5);
  transform: rotate(45deg);
}

html.photo-hold .walkup-source,
html.booting .walkup-source,
html.drawer-open .walkup-source {
  opacity: 0;
  pointer-events: none;
}

@media (max-width: 480px) {
  .walkup-source {
    left: 12px;
    top: 62px;
  }

  .walkup-tip.is-camera {
    left: 12px;
    top: 110px;
  }
}

/* Bottom-sheet grab bar on the editor's top edge (party, phones). Positioned by setupSheetDrag. */
.hud-grab {
  display: none;
}

@media (pointer: coarse) {
  html.party:not(.walkup) .hud-grab {
    position: fixed;
    left: 20px;
    right: 20px;
    z-index: 3;
    display: grid;
    place-items: center;
    height: 26px;
    margin-top: -2px;
    touch-action: none;
  }



  .hud-grab-bar {
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background: rgba(236, 242, 248, 0.45);
  }

  html.party:not(.walkup) .hud {
    padding-top: 26px;
  }
}

/* Party: the hands-off timers as two chips on one row ("next clip · 30s", "auto shuffle · off"). */
.auto-chips {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.source-file .auto-chip {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  background: none;
  padding: 6px 12px;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.035em;
  color: rgba(210, 222, 232, 0.78);
  cursor: pointer;
}

.source-file .auto-chip[aria-pressed="true"] {
  color: #7be7ff;
  border-color: rgba(123, 231, 255, 0.45);
  background: rgba(123, 231, 255, 0.1);
}

.source-file .auto-chip[hidden] {
  display: none;
}

@media (any-pointer: coarse) {
  .hud .source-file .auto-chip {
    min-height: 40px;
  }
}

/* Editor head: the look's name and shuffle, the one-tap remix, at the very top. */
.hud-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.hud-head .title {
  margin: 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hud-shuffle {
  flex: none;
  appearance: none;
  border: 1px solid rgba(123, 231, 255, 0.45);
  border-radius: 999px;
  background: rgba(123, 231, 255, 0.1);
  color: #fff;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.06em;
  padding: 6px 14px;
  cursor: pointer;
}

@media (any-pointer: coarse) {
  .hud .hud-shuffle {
    min-height: 40px;
  }

  html.party:not(.walkup) .hud .hud-head {
    touch-action: none;
  }
}

.layer-head {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  letter-spacing: 0.035em;
  margin-bottom: 4px;
}

.mixer-panel .layers button[aria-disabled] {
  opacity: 0.35;
}

/* Desk side (local live and studio) runs the walk-up interface too. Its page links move to the bottom
   right while the mixer is open, out of the corner board's way; hidden while the picture has the screen. */
html.desk:not(.walkup) .sketch-nav {
  top: auto;
  bottom: 16px;
  opacity: 1;
  pointer-events: auto;
}

/* Invisible is not enough: the links inside keep taking clicks and would sit over the edit button. */
html.walkup .sketch-nav {
  visibility: hidden;
}

/* Mic beside the shutter (right of it; the timer is on the left). Lit while it listens, and it flashes
   on each beat the visualizer catches, so people can see it hearing the room. */
.capture-mic {
  --level: 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-width: 52px;
  min-height: 32px;
  padding: 7px 11px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.42);
  color: rgba(236, 242, 248, 0.88);
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: lowercase;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.8);
  cursor: pointer;
  transition:
    box-shadow 0.12s ease,
    background 0.2s ease;
}

.capture-mic[hidden] {
  display: none;
}

.capture-mic-icon {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
}

.capture-mic[aria-pressed="true"] {
  color: #fff;
  border-color: rgba(123, 231, 255, 0.6);
  background: rgba(123, 231, 255, calc(0.08 + var(--level) * 0.22));
}

.capture-mic.is-beat {
  box-shadow: 0 0 0 4px rgba(123, 231, 255, 0.35), 0 0 18px rgba(123, 231, 255, 0.55);
}

@media (prefers-reduced-motion: reduce) {
  .capture-mic {
    transition: none;
  }
}

/* Video opacity and the words text: labelled, laid out like a layer row (name, then the control). */
.layer-amt.video-opacity,
.layer-amt.words-param {
  display: grid;
  grid-template-columns: 6em minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  min-height: 36px;
  font-size: 12px;
  letter-spacing: 0.035em;
  color: rgba(210, 222, 232, 0.72);
}

.layer-amt.video-opacity[hidden],
.layer-amt.words-param[hidden] {
  display: none;
}

.layer-amt.words-param input {
  min-width: 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(180, 210, 230, 0.28);
  padding: 4px 0;
  color: rgba(220, 236, 255, 0.88);
  font: inherit;
  letter-spacing: 0.06em;
  outline: none;
}

.layer-amt.words-param input:focus {
  border-bottom-color: #7be7ff;
}

.layer-amt.words-param input::placeholder {
  color: rgba(180, 210, 230, 0.32);
}

/* Layers tab, built like filters: your layers (rows) on top, the grouped library of chips below. */
.layer-stack {
  margin-top: 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid rgba(210, 222, 232, 0.14);
}

.layer-stack .filter-tray[hidden],
.layer-stack .mix-empty[hidden],
.layer-stack .mix-note[hidden] {
  display: none;
}

.mixer-panel .filters.layer-library {
  margin-top: 4px;
}

.mixer-panel .layer-library button[aria-disabled] {
  opacity: 0.35;
}

.mixer-panel .layer-library button.is-preview {
  color: #fff;
  box-shadow: inset 0 0 0 1px rgba(123, 231, 255, 0.55);
}

/* Help: a "?" beside use camera, pulsing gently until the tour has been opened once. */
.walkup-help {
  min-width: 36px;
  padding: 8px 0;
  font-size: 14px;
  letter-spacing: 0;
  text-align: center;
  opacity: 0.88;
  color: #fff;
}

.walkup-help.is-new {
  animation: help-pulse 2.4s ease-in-out infinite;
}

@keyframes help-pulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(236, 242, 248, 0.35);
  }
  50% {
    box-shadow: 0 0 0 7px rgba(236, 242, 248, 0);
  }
}

/* The tour: everything dimmed but one control, a caption card beside it. */
.tour {
  position: fixed;
  inset: 0;
  z-index: 60;
}

.tour[hidden] {
  display: none;
}

.tour.is-center {
  background: rgba(3, 4, 6, 0.62);
  display: grid;
  place-items: center;
}

.tour-spot {
  position: fixed;
  border-radius: 14px;
  box-shadow:
    0 0 0 2px rgba(123, 231, 255, 0.85),
    0 0 0 9999px rgba(3, 4, 6, 0.62);
  pointer-events: none;
  transition:
    left 0.3s cubic-bezier(0.22, 1, 0.36, 1),
    top 0.3s cubic-bezier(0.22, 1, 0.36, 1),
    width 0.3s cubic-bezier(0.22, 1, 0.36, 1),
    height 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.tour-spot[hidden] {
  display: none;
}

.tour-card {
  position: fixed;
  width: min(320px, calc(100vw - 24px));
  padding: 16px 18px 14px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 14px;
  background: rgba(8, 10, 14, 0.94);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.45);
  color: rgba(236, 242, 248, 0.92);
}

.tour.is-center .tour-card {
  position: static;
}

.tour-step {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.14em;
  color: rgba(210, 222, 232, 0.55);
}

.tour-title {
  margin: 6px 0 6px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.tour-text {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: rgba(236, 242, 248, 0.82);
}

.tour-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
}

.tour-actions button {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 999px;
  background: none;
  padding: 8px 14px;
  min-height: 36px;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: rgba(236, 242, 248, 0.85);
  cursor: pointer;
}

.tour-actions .tour-skip {
  margin-right: auto;
  border-color: transparent;
  color: rgba(210, 222, 232, 0.55);
}

.tour-actions .tour-next {
  border-color: rgba(123, 231, 255, 0.55);
  background: rgba(123, 231, 255, 0.12);
  color: #fff;
}

.tour-actions [hidden] {
  display: none;
}

/* While touring, the first-visit tips stay out of the way. */
html.touring .walkup-tip {
  display: none;
}

html.touring {
  cursor: auto;
}

@media (prefers-reduced-motion: reduce) {
  .walkup-help.is-new {
    animation: none;
  }

  .tour-spot {
    transition: none;
  }
}

html.touring.cursor-idle,
html.touring.cursor-idle * {
  cursor: auto !important;
}

/* Hide-controls button (an eye, struck through) beside ?. */
.walkup-hide {
  display: grid;
  place-items: center;
  min-width: 36px;
  padding: 8px 0;
}

.walkup-hide svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
}

/* Clean screen: nothing but the picture. */
html.clean .walkup-board,
html.clean .walkup-source,
html.clean .walkup-capture,
html.clean .walkup-looks,
html.clean .walkup-tip,
html.clean .walkup-drawer,
html.clean .hud,
html.clean .hud-grab,
html.clean .sketch-nav,
html.clean .record-pip {
  opacity: 0 !important;
  visibility: hidden;
  pointer-events: none !important;
}

html.clean,
html.clean * {
  cursor: none !important;
}

.clean-hint {
  position: fixed;
  left: 50%;
  bottom: calc(28px + env(safe-area-inset-bottom, 0px));
  z-index: 9;
  margin: 0;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.72);
  color: rgba(236, 242, 248, 0.88);
  font-size: 12px;
  letter-spacing: 0.06em;
  transform: translateX(-50%);
  pointer-events: none;
  animation: walkup-tip-in 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.clean-hint[hidden] {
  display: none;
}

.walkup-tip.is-help::before {
  border-color: rgba(236, 242, 248, 0.45);
}

/* Editor head: ? (the editor tour) beside shuffle. */
.hud-head-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
}

.hud-help {
  appearance: none;
  min-width: 32px;
  min-height: 32px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  background: none;
  color: rgba(236, 242, 248, 0.88);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}

@media (any-pointer: coarse) {
  .hud .hud-help {
    min-width: 40px;
    min-height: 40px;
  }
}

/* Moments: the last few dozen states of the look, each a still of the picture then. Hover one to see
   it, tap to go there; Z steps back, shift Z forward. */
.moments {
  margin-bottom: 12px;
}

.moments[hidden] {
  display: none;
}

.moments .mix-head .filter-shuffle {
  margin-left: 0;
  padding: 2px 6px;
  color: rgba(210, 222, 232, 0.6);
  border: 0;
}

.moments .mix-head .filter-shuffle:first-of-type {
  margin-left: auto;
}

.moments .mix-head .filter-shuffle:disabled {
  opacity: 0.3;
  cursor: default;
}

.moments-strip {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding: 6px 0 4px;
  scrollbar-width: thin;
  scroll-snap-type: x proximity;
}

.moment {
  appearance: none;
  flex: none;
  display: grid;
  gap: 3px;
  width: 96px;
  padding: 0;
  border: 0;
  background: none;
  color: rgba(210, 222, 232, 0.55);
  font: inherit;
  font-size: 10px;
  letter-spacing: 0.03em;
  text-align: left;
  cursor: pointer;
  scroll-snap-align: center;
}

.moment canvas {
  display: block;
  width: 96px;
  height: 54px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
}

.moment[aria-selected="true"] canvas {
  box-shadow: 0 0 0 2px #7be7ff;
}

.moment[aria-selected="true"] {
  color: rgba(236, 242, 248, 0.9);
}

.moment span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Describe: a sentence becomes an edit. */
.describe {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 12px;
}

.describe input {
  flex: 1;
  min-width: 0;
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  padding: 7px 12px;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.02em;
  color: #e9edf2;
}

.describe input::placeholder {
  color: rgba(210, 222, 232, 0.4);
}

.describe input:focus {
  outline: none;
  border-color: rgba(123, 231, 255, 0.5);
}

.describe.is-busy input {
  opacity: 0.6;
}

/* The picture slot: an image glyph, then the picture itself as a thumb (tap again to drop it). */
.describe-pic {
  flex: none;
  width: 30px;
  height: 30px;
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04) center / cover no-repeat;
  cursor: pointer;
  position: relative;
}

.describe-pic::before {
  content: "";
  position: absolute;
  inset: 8px 7px;
  border: 1.5px solid rgba(210, 222, 232, 0.55);
  border-radius: 2px;
  background: linear-gradient(135deg, transparent 55%, rgba(210, 222, 232, 0.55) 56%);
}

.describe.has-pic .describe-pic {
  border-color: rgba(123, 231, 255, 0.6);
}

.describe.has-pic .describe-pic::before {
  display: none;
}

.describe.is-drop input {
  border-color: rgba(123, 231, 255, 0.7);
  background: rgba(123, 231, 255, 0.08);
}

/* Macros: four sliders that each move many things; rec, change, done. */
.macros {
  margin-bottom: 12px;
}

.macro-rows {
  display: grid;
  gap: 6px;
  margin-top: 6px;
}

.macro {
  display: grid;
  grid-template-columns: 5.2em 1fr auto;
  align-items: center;
  gap: 8px;
  font-size: 10px;
  letter-spacing: 0.08em;
}

.macro-name {
  width: 100%;
  min-width: 0;
  appearance: none;
  border: 0;
  border-bottom: 1px solid transparent;
  background: none;
  padding: 2px 0;
  font: inherit;
  letter-spacing: inherit;
  color: #7be7ff;
}

.macro-name:focus {
  outline: none;
  border-bottom-color: rgba(123, 231, 255, 0.5);
}

.macro.is-empty .macro-name {
  color: rgba(210, 222, 232, 0.45);
}

.macro input[type="range"] {
  width: 100%;
  accent-color: #7be7ff;
}

.macro.is-empty input[type="range"] {
  opacity: 0.35;
}

.macro-rec {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  background: none;
  padding: 3px 9px;
  font: inherit;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: rgba(210, 222, 232, 0.72);
  cursor: pointer;
}

.macro-rec[aria-pressed="true"] {
  color: #ff6b6b;
  border-color: rgba(255, 107, 107, 0.6);
  animation: macro-blink 1s steps(2) infinite;
}

@keyframes macro-blink {
  to {
    border-color: rgba(255, 107, 107, 0.15);
  }
}

/* A/B wipe: a line down the picture, A live on the left, the held B on the right. Drag it. */
.ab-wipe {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 0;
  z-index: 8;
  border-left: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
  cursor: ew-resize;
  touch-action: none;
}

.ab-wipe[hidden] {
  display: none;
}

.ab-wipe::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -14px;
  width: 28px;
}

.ab-grip {
  position: absolute;
  top: 50%;
  left: -13px;
  width: 26px;
  height: 26px;
  margin-top: -13px;
  border-radius: 50%;
  background: rgba(7, 9, 13, 0.75);
  border: 1px solid rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(6px);
}

.ab-grip::before,
.ab-grip::after {
  content: "";
  position: absolute;
  top: 9px;
  width: 0;
  height: 0;
  border: 4px solid transparent;
}

.ab-grip::before {
  left: 4px;
  border-right-color: rgba(255, 255, 255, 0.9);
}

.ab-grip::after {
  right: 4px;
  border-left-color: rgba(255, 255, 255, 0.9);
}

.ab-tag {
  position: absolute;
  top: calc(50% - 44px);
  font: 11px/1 "Helvetica Neue", Helvetica, Arial, sans-serif;
  letter-spacing: 0.14em;
  color: rgba(255, 255, 255, 0.85);
  background: rgba(7, 9, 13, 0.6);
  padding: 5px 7px;
  border-radius: 999px;
}

.ab-tag-a {
  right: 10px;
}

.ab-tag-b {
  left: 10px;
}

.ab-tools {
  display: inline-flex;
  gap: 8px;
}

.ab-tools[hidden] {
  display: none;
}

#ab-hold[aria-pressed="true"] {
  color: #7be7ff;
  border-color: rgba(123, 231, 255, 0.6);
}

/* Save and share sit above "your mix", on their own row. */
.mix-actions {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}

.mix-actions:not(:has(button:not([hidden]))) {
  display: none;
}

.mix-actions .filter-shuffle {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  background: none;
  padding: 6px 14px;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.035em;
  color: rgba(236, 242, 248, 0.86);
  cursor: pointer;
}

@media (any-pointer: coarse) {
  .hud .mix-actions .filter-shuffle {
    min-height: 40px;
  }
}

/* Drawer cards shrink and dim with distance from the middle (--d, set while scrolling). */
.walkup-drawer .look-card {
  --d: 0;
  transform: translateY(calc(var(--d) * 10px)) scale(calc(1 - var(--d) * 0.18));
  opacity: calc(1 - var(--d) * 0.45);
  transition:
    transform 0.14s ease-out,
    opacity 0.14s ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .walkup-drawer .look-card {
    transform: none;
    transition: none;
  }
}

/* A shape source (?source=text|logo|cursor|none): there is no camera or clip to pick. */
html.shape-source #walkup-source,
html.shape-source #source-pick,
html.shape-source #key-pick,
html.shape-source #invert-param {
  display: none !important;
}

/* The layer stack: one line per layer (eye, name, amount, readout, lock, tune, ×), its knobs beneath
   when tune is open. A muted row dims; the tune mark lights when a knob is off its default. */
.mixer-panel .filter-tray .layer-row {
  display: grid;
  grid-template-columns: 28px minmax(3.6em, max-content) minmax(60px, 1fr) 3.2em 30px 30px 34px;
  align-items: center;
  gap: 0 6px;
  width: 100%;
}
.layer-row label {
  min-width: 0;
}
.layer-row input[type="range"] {
  width: 100%;
  min-width: 0;
}
.layer-row.is-muted .filter-strip-name,
.layer-row.is-muted label,
.layer-row.is-muted .amt-readout {
  opacity: 0.4;
}
.layer-eye {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  min-height: 34px;
  display: grid;
  place-items: center;
  border-radius: 6px;
  color: rgba(210, 222, 232, 0.3);
  cursor: pointer;
}
.layer-eye[aria-pressed="true"] {
  color: #7be7ff;
}
.layer-eye svg {
  width: 15px;
  height: 15px;
}
.layer-tune-toggle {
  appearance: none;
  border: 0;
  background: none;
  min-height: 34px;
  padding: 0;
  border-radius: 6px;
  color: rgba(210, 222, 232, 0.45);
  font: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.layer-tune-toggle.is-tuned {
  color: #7be7ff;
}
.layer-tune-toggle[aria-expanded="true"] {
  color: #7be7ff;
  background: rgba(123, 231, 255, 0.1);
}
.amt-readout {
  appearance: none;
  border: 0;
  background: none;
  padding: 0 2px;
  min-height: 34px;
  border-radius: 4px;
  font: inherit;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: rgba(210, 222, 232, 0.55);
  text-align: right;
  cursor: text;
}
.amt-readout:hover,
.amt-readout:focus-visible {
  color: #fff;
}
.amt-edit {
  width: 3.4em;
  min-height: 28px;
  box-sizing: border-box;
  border-radius: 4px;
  border: 1px solid rgba(123, 231, 255, 0.5);
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  font: inherit;
  font-size: 11px;
  text-align: right;
  padding: 0 4px;
}
.amt-edit:focus {
  outline: none;
}
.filter-strip:not(.layer-row) > .amt-readout {
  margin-left: -6px;
  min-width: 2.2em;
}
.layer-tune {
  grid-column: 1 / -1;
  display: grid;
  gap: 4px 10px;
  padding: 2px 0 10px 34px;
}
.layer-about {
  margin: 0 0 4px;
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: 0.02em;
  color: rgba(210, 222, 232, 0.5);
}
.layer-knob {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 3.4em;
  align-items: center;
  gap: 0 8px;
}
.mixer-panel .filter-tray .layer-row .layer-knob label {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: rgba(220, 230, 238, 0.82);
}
.layer-knob label > span {
  width: 4em;
  flex: none;
}
.layer-knob input[type="range"] {
  flex: 1;
  min-width: 0;
  width: auto;
  accent-color: #7be7ff;
}
.layer-tune-reset {
  justify-self: start;
  margin-top: 4px;
  appearance: none;
  border: 1px solid rgba(210, 222, 232, 0.2);
  background: none;
  border-radius: 999px;
  padding: 4px 11px;
  font: inherit;
  font-size: 11px;
  letter-spacing: 0.06em;
  color: rgba(210, 222, 232, 0.65);
  cursor: pointer;
}
.layer-tune-reset:disabled {
  opacity: 0.35;
  cursor: default;
}

/* The library: cards with a line of what each layer does, searchable. */
.layer-search-wrap,
.lib-search-wrap {
  display: block;
  margin-top: 12px;
}
#layer-search,
.lib-search {
  width: 100%;
  box-sizing: border-box;
  min-height: 34px;
  border-radius: 8px;
  border: 1px solid rgba(210, 222, 232, 0.16);
  background: rgba(255, 255, 255, 0.04);
  color: #fff;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.02em;
  padding: 0 10px;
}
#layer-search::placeholder,
.lib-search::placeholder {
  color: rgba(210, 222, 232, 0.38);
}
#layer-search:focus,
.lib-search:focus {
  outline: none;
  border-color: rgba(123, 231, 255, 0.55);
}
.layer-library .filter-group-chips {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 6px;
}
.layer-library .filter-group[hidden],
.layer-library button[hidden] {
  display: none;
}
.mixer-panel .layer-library button {
  display: grid;
  gap: 2px;
  min-height: 0;
  padding: 8px 10px;
  border-radius: 8px;
  text-align: left;
  background: rgba(255, 255, 255, 0.03);
}
.mixer-panel .layer-library button[aria-pressed="true"] {
  background: rgba(123, 231, 255, 0.1);
}
.layer-library .lib-name {
  font-size: 12px;
  letter-spacing: 0.04em;
}
.layer-library .lib-about {
  font-size: 10.5px;
  line-height: 1.3;
  letter-spacing: 0.01em;
  text-transform: none;
  color: rgba(210, 222, 232, 0.5);
}
.mixer-panel .layer-library button[aria-pressed="true"] .lib-about {
  color: rgba(123, 231, 255, 0.6);
}
@media (max-width: 420px) {
  .mixer-panel .filter-tray .layer-row {
    grid-template-columns: 26px minmax(3em, max-content) minmax(40px, 1fr) 2.6em 26px 26px 30px;
    gap: 0 3px;
  }
  .layer-tune {
    padding-left: 0;
  }
}

/* Touch: the row's small marks keep a tall target but not a wide one, so the line still fits. */
@media (any-pointer: coarse) {
  .hud .layer-row .layer-eye,
  .hud .layer-row .layer-tune-toggle,
  .hud .layer-row .amt-readout,
  .hud .layer-row .filter-strip-lock {
    min-width: 0;
    padding: 0;
  }
  .hud .layer-row .filter-strip-remove {
    min-width: 32px;
  }
}
@media (max-width: 480px) {
  .mixer-panel .filter-tray .layer-row {
    grid-template-columns: 30px minmax(2.6em, max-content) minmax(36px, 1fr) minmax(2.2em, auto) 28px 30px 32px;
    gap: 0 4px;
  }
  .mixer-panel .filter-tray .layer-row .amt-readout {
    font-size: 12px;
  }
  .layer-tune {
    padding-left: 0;
  }
}
.layer-row .layer-eye,
.layer-row .layer-tune-toggle,
.layer-row .filter-strip-lock,
.layer-row .filter-strip-remove {
  width: 100%;
  justify-self: stretch;
}
.hud .mixer-panel .layer-row input[type="range"],
.hud .mixer-panel .layer-knob input[type="range"] {
  width: 100%;
  min-width: 0;
}
.layer-row > label {
  min-width: 0;
  overflow: hidden;
}
.layer-row > .amt-readout {
  justify-self: end;
  white-space: nowrap;
}

.mixer-panel .filters button[hidden],
.mixer-panel .filter-group[hidden],
#filter-jump button[hidden] {
  display: none;
}

/* Favourites: a star on the look's name; starred looks go to the front of the strip. */
.hud-star {
  flex: none;
  appearance: none;
  border: 1px solid rgba(210, 222, 232, 0.25);
  border-radius: 999px;
  background: none;
  width: 32px;
  height: 32px;
  padding: 0;
  font: inherit;
  font-size: 15px;
  line-height: 1;
  color: rgba(210, 222, 232, 0.6);
  cursor: pointer;
}
.hud-star[aria-pressed="true"] {
  color: #ffd36b;
  border-color: rgba(255, 211, 107, 0.6);
}
.hud-star[hidden] {
  display: none;
}
.look-card.is-fav .look-card-name::before,
.looks-picks button.is-fav::before {
  content: "★ ";
  color: #ffd36b;
}

/* The modulation matrix: a row per route. Line one: source → target, remove. Line two: depth, curve,
   attack, release. The dot beside the source breathes with that source's level. */
.matrix .mix-head {
  align-items: center;
}
.matrix-add {
  margin-left: auto;
}
.route-rows {
  display: grid;
  gap: 8px;
  margin-top: 8px;
}
.route {
  display: grid;
  gap: 4px 8px;
  padding: 8px 10px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.035);
  font-size: 12px;
  letter-spacing: 0.02em;
}
.route-line {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr) auto minmax(0, 1fr) 30px;
  align-items: center;
  gap: 0 6px;
}
.route-line .route-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #7be7ff;
  opacity: calc(0.15 + var(--live, 0) * 0.85);
  transform: scale(calc(0.6 + var(--live, 0) * 0.8));
  transition: opacity 0.08s linear, transform 0.08s linear;
}
.route-line .arrow {
  color: rgba(210, 222, 232, 0.4);
}
.route select {
  width: 100%;
  min-width: 0;
  min-height: 30px;
  font: inherit;
  font-size: 12px;
  color: rgba(220, 230, 238, 0.9);
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(210, 222, 232, 0.16);
  border-radius: 6px;
  padding: 0 6px;
}
.route select:focus {
  outline: none;
  border-color: rgba(123, 231, 255, 0.55);
}
.route-knobs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 10px;
  align-items: center;
}
.route-knobs label:first-child {
  grid-column: 1 / -1;
}
.route-knobs label {
  display: grid;
  grid-template-columns: 4.2em minmax(0, 1fr) 3em;
  align-items: center;
  gap: 0 6px;
  color: rgba(210, 222, 232, 0.6);
}
.route-knobs label > span:last-child {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: rgba(210, 222, 232, 0.55);
}
.route-knobs input[type="range"] {
  width: 100%;
  min-width: 0;
  accent-color: #7be7ff;
}
.route-knobs .route-curve {
  grid-template-columns: 4.2em minmax(0, 1fr);
}
.route-remove {
  appearance: none;
  border: 0;
  background: none;
  min-height: 30px;
  border-radius: 6px;
  color: rgba(210, 222, 232, 0.6);
  font: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.matrix.is-empty .route-rows {
  display: none;
}
@media (max-width: 520px) {
  .route-knobs {
    grid-template-columns: 1fr;
    gap: 2px;
  }
}

/* The eight bands, sub to air, as a small meter beside "modulate" while music is on. */
/* The tempo, where a clock is running: "126 bpm heard" from the tracker, "· link" from a feed. */
.bpm-chip {
  margin-left: 8px;
  font-size: 11px;
  letter-spacing: 0.02em;
  color: rgba(123, 231, 255, 0.85);
  white-space: nowrap;
}
.bpm-chip[hidden] {
  display: none;
}
.bpm-chip i {
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-left: 3px;
  border-radius: 50%;
  background: rgba(123, 231, 255, 0.25);
  vertical-align: middle;
  transition: transform 0.08s ease-out, background 0.08s;
}
.bpm-chip i:first-of-type {
  margin-left: 6px;
}
.bpm-chip i.is-on {
  background: rgba(123, 231, 255, 1);
  transform: scale(1.35);
}
.bpm-chip i:first-of-type.is-on {
  transform: scale(1.8);
}

.bands8 {
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
  height: 14px;
  margin-left: 8px;
}
.bands8[hidden] {
  display: none;
}
.bands8 i {
  display: block;
  width: 4px;
  height: 100%;
  border-radius: 1px;
  background: linear-gradient(to top, #7be7ff 0, #7be7ff calc(var(--v, 0) * 100%), rgba(123, 231, 255, 0.12) calc(var(--v, 0) * 100%));
}

/* The crowd portal block: the room's code and link, the QR guests scan, the door, the cap, who is in. */
.room {
  margin: 8px 0 4px;
  padding: 8px 0 10px;
  border-top: 1px solid rgba(210, 222, 232, 0.12);
  border-bottom: 1px solid rgba(210, 222, 232, 0.12);
}
.room[hidden] {
  display: none;
}
.room-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.room-code {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13px;
  letter-spacing: 0.12em;
  color: #7be7ff;
}
.room-toggle {
  margin-left: auto;
}
.room-body {
  display: grid;
  grid-template-columns: 112px minmax(0, 1fr);
  gap: 12px;
  margin-top: 10px;
}
.room-body[hidden] {
  display: none;
}
.room-qr {
  width: 112px;
  height: 112px;
  border-radius: 8px;
  background: #fff;
  image-rendering: pixelated;
}
.room-side {
  min-width: 0;
  display: grid;
  gap: 6px;
  align-content: start;
  font-size: 12px;
}
.room-link {
  margin: 0;
  color: rgba(220, 230, 238, 0.82);
  word-break: break-all;
}
.room-opts {
  display: grid;
  gap: 2px;
}
.room-opts .check {
  margin-top: 0;
}
.room-max {
  display: flex;
  align-items: center;
  gap: 6px;
  color: rgba(210, 222, 232, 0.6);
}
.room-max input {
  width: 3.4em;
  font: inherit;
  font-size: 12px;
  color: #fff;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(210, 222, 232, 0.16);
  border-radius: 6px;
  padding: 3px 6px;
}
.room-guests {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.room-guest {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 4px 3px 9px;
  border-radius: 999px;
  border: 1px solid rgba(210, 222, 232, 0.18);
  color: rgba(220, 230, 238, 0.85);
}
.room-guest.is-paused {
  opacity: 0.5;
}
.room-guest.is-picked {
  border-color: #ffd36b;
}
.room-guest button {
  appearance: none;
  border: 0;
  background: none;
  color: rgba(210, 222, 232, 0.6);
  font: inherit;
  font-size: 13px;
  line-height: 1;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  cursor: pointer;
}
.room-guest button:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}
.room-guest button[aria-pressed="true"] {
  color: #ffd36b;
}
/* The code on the wall itself, bottom left, visible with the controls hidden too. */
.room-corner {
  position: fixed;
  left: 18px;
  bottom: 18px;
  z-index: 40;
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  gap: 10px;
  padding: 8px 12px 8px 8px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.92);
  color: #111;
  text-decoration: none;
  font-size: 12px;
  letter-spacing: 0.04em;
  line-height: 1.3;
  pointer-events: none;
}
.room-corner[hidden] {
  display: none;
}
.room-corner canvas {
  width: 92px;
  height: 92px;
  display: block;
  image-rendering: pixelated;
}
.room-corner span {
  max-width: 12em;
}
.room-corner span b {
  display: block;
  font-weight: 600;
  font-size: 13px;
}
/* With the editor open on the party page the room block carries the code; the corner card steps aside. */
html.party:not(.walkup) .room-corner {
  display: none;
}

/* A guest whose phone caught a rude gesture: the count beside their name. */
.room-flag {
  color: #ffb36b;
}

/* ---- The editor at three depths (?lab=play, site/play.js) ---- */
.depth {
  display: flex;
  gap: 2px;
  margin: 10px 0 4px;
  padding: 3px;
  border-radius: 9px;
  background: rgba(210, 222, 232, 0.06);
}
.depth button {
  flex: 1;
  appearance: none;
  border: 0;
  border-radius: 7px;
  background: none;
  padding: 6px 0;
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: rgba(210, 222, 232, 0.6);
  cursor: pointer;
}
.depth button[aria-pressed="true"] {
  background: rgba(123, 231, 255, 0.14);
  color: #7be7ff;
}
.depth button:focus-visible {
  outline: 2px solid #7be7ff;
  outline-offset: 1px;
}

/* The play block only shows at play depth. */
.play {
  display: none;
}
html.lab-play[data-depth="play"] .play {
  display: block;
  padding: 14px 0 6px;
}
/* Play: one column, no tabs, no engine words. The looks and the describe field come out of their tabs. */
html.lab-play[data-depth="play"] .mixer-stage {
  display: flex;
  flex-direction: column;
}
html.lab-play[data-depth="play"] .play { order: 0; }
html.lab-play[data-depth="play"] #panel-filters { order: 1; }
html.lab-play[data-depth="play"] #panel-looks { order: 2; }
html.lab-play[data-depth="play"] .mixer-stage > #panel-filters,
html.lab-play[data-depth="play"] .mixer-stage > #panel-looks {
  display: block !important;
  visibility: visible;
}
html.lab-play[data-depth="play"] #panel-filters {
  padding: 4px 0 10px;
  border-bottom: 0;
}
html.lab-play[data-depth="play"] #panel-filters > :not(.mix-stack),
html.lab-play[data-depth="play"] #panel-filters .mix-stack > :not(#describe),
html.lab-play[data-depth="play"] .mixer-stage > #panel-layers,
html.lab-play[data-depth="play"] .mixer-stage > #panel-advanced,
html.lab-play[data-depth="play"] .mixer-tabs,
html.lab-play[data-depth="play"] .mixer-key,
html.lab-play[data-depth="play"] #room,
html.lab-play[data-depth="play"] #look-change,
html.lab-play[data-depth="play"] #clip-auto,
html.lab-play[data-depth="play"] #mix-auto,
html.lab-play[data-depth="play"] #auto-chips {
  display: none !important;
}
/* Shape: the ingredients. Filters and layers with their amounts; the wiring stays out of sight. */
html.lab-play[data-depth="shape"] .mixer-key,
html.lab-play[data-depth="shape"] #room,
html.lab-play[data-depth="shape"] #tab-looks,
html.lab-play[data-depth="shape"] #tab-advanced,
html.lab-play[data-depth="shape"] #macros,
html.lab-play[data-depth="shape"] #matrix,
html.lab-play[data-depth="shape"] #ab-hold,
html.lab-play[data-depth="shape"] #ab-tools,
html.lab-play[data-depth="shape"] #mix-auto,
html.lab-play[data-depth="shape"] #clip-auto,
html.lab-play[data-depth="shape"] #auto-chips,
html.lab-play[data-depth="shape"] #describe {
  display: none !important;
}

/* The feel pad: drag toward a word. The puck in the middle is the look as it is. */
.feel-pad {
  --x: 0.5;
  --y: 0.5;
  position: relative;
  margin-top: 10px;
  aspect-ratio: 16 / 10;
  border-radius: 12px;
  overflow: hidden;
  touch-action: none;
  cursor: crosshair;
  background:
    radial-gradient(circle at calc(var(--x) * 100%) calc(var(--y) * 100%), rgba(123, 231, 255, 0.22), transparent 42%),
    radial-gradient(ellipse at center, rgba(210, 222, 232, 0.07), rgba(210, 222, 232, 0.02) 70%);
  box-shadow: inset 0 0 0 1px rgba(210, 222, 232, 0.12);
  transition: box-shadow 0.2s;
}
.feel-pad:focus-visible {
  outline: 2px solid #7be7ff;
  outline-offset: 2px;
}
.feel-pad.is-dragging {
  box-shadow: inset 0 0 0 1px rgba(123, 231, 255, 0.4);
}
.feel-pad.is-asking .feel-word {
  animation: feel-ask 1.2s ease-in-out infinite;
}
@keyframes feel-ask {
  50% { opacity: 0.35; }
}
.feel-cross::before,
.feel-cross::after {
  content: "";
  position: absolute;
  background: rgba(210, 222, 232, 0.1);
  pointer-events: none;
}
.feel-cross::before { left: 50%; top: 12%; bottom: 12%; width: 1px; }
.feel-cross::after { top: 50%; left: 8%; right: 8%; height: 1px; }
.feel-word {
  position: absolute;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: rgba(210, 222, 232, 0.66);
  pointer-events: none;
  white-space: nowrap;
}
.feel-pad.is-model .feel-word {
  color: rgba(225, 238, 245, 0.88);
}
.feel-x-low { left: 10px; top: 50%; transform: translateY(-50%); }
.feel-x-high { right: 10px; top: 50%; transform: translateY(-50%); }
.feel-y-high { top: 8px; left: 50%; transform: translateX(-50%); }
.feel-y-low { bottom: 8px; left: 50%; transform: translateX(-50%); }
.feel-puck {
  position: absolute;
  left: calc(var(--x) * 100%);
  top: calc(var(--y) * 100%);
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  border-radius: 50%;
  border: 1.5px solid #e9f7ff;
  box-shadow: 0 0 14px rgba(123, 231, 255, 0.7), inset 0 0 6px rgba(123, 231, 255, 0.5);
  pointer-events: none;
}
.feel-pad:not(.is-dragging) .feel-puck {
  transition: left 0.25s ease, top 0.25s ease;
}
.feel-by {
  margin-right: auto;
}
.play-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
}
.play .play-vary,
.play .feel-again {
  appearance: none;
  flex: none;
  border: 1px solid rgba(123, 231, 255, 0.35);
  border-radius: 999px;
  background: rgba(123, 231, 255, 0.1);
  padding: 7px 16px;
  font: inherit;
  font-size: 13px;
  line-height: 1.2;
  color: #7be7ff;
  cursor: pointer;
}
.play .feel-again {
  padding: 3px 10px;
  font-size: 11px;
  border-color: rgba(210, 222, 232, 0.2);
  background: none;
  color: rgba(210, 222, 232, 0.7);
}
.play .play-vary:hover {
  background: rgba(123, 231, 255, 0.18);
}
.play-hint {
  font-size: 11px;
  color: rgba(210, 222, 232, 0.45);
}

/* Variations: the picture in bands, the live look on the left. The editor steps aside while they show. */
html.varying .hud *,
html.varying .hud,
html.varying .walkup-board,
html.varying #walkup-looks,
html.varying #walkup-capture,
html.varying #walkup-mix,
html.varying #walkup-source {
  visibility: hidden !important;
}
.vary {
  position: fixed;
  inset: 0;
  z-index: 9;
}
.vary[hidden] {
  display: none;
}
.vary-bands {
  position: absolute;
  inset: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
}
.vary-band {
  position: relative;
  appearance: none;
  border: 0;
  border-left: 1px solid rgba(0, 0, 0, 0.55);
  box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.28);
  background: transparent;
  padding: 0;
  cursor: pointer;
  color: inherit;
  font: inherit;
}
.vary-band:first-child {
  border-left: 0;
  box-shadow: none;
}
.vary-band:hover,
.vary-band:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px rgba(123, 231, 255, 0.75);
}
.vary-tag {
  position: absolute;
  left: 12px;
  right: 12px;
  top: 14px;
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: rgba(235, 243, 248, 0.92);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.9);
  text-align: left;
}
.vary-tag b {
  font-weight: 600;
  color: #7be7ff;
}
.vary-band.is-now .vary-tag b {
  color: rgba(235, 243, 248, 0.92);
}
.vary-tools {
  position: absolute;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px;
  border-radius: 999px;
  background: rgba(8, 10, 14, 0.82);
  box-shadow: 0 0 0 1px rgba(210, 222, 232, 0.14);
  font-size: 13px;
}
.vary-tools button {
  appearance: none;
  border: 0;
  border-radius: 999px;
  background: none;
  padding: 7px 14px;
  font: inherit;
  color: rgba(210, 222, 232, 0.8);
  cursor: pointer;
}
.vary-tools button:hover,
.vary-tools button[aria-pressed="true"] {
  background: rgba(210, 222, 232, 0.1);
  color: #fff;
}
.vary-tools .vary-done {
  background: rgba(123, 231, 255, 0.16);
  color: #7be7ff;
}
.vary-strength {
  display: flex;
  padding: 0 4px;
  border-left: 1px solid rgba(210, 222, 232, 0.14);
  border-right: 1px solid rgba(210, 222, 232, 0.14);
}
@media (max-width: 640px) {
  .vary-tag { flex-direction: column; gap: 2px; left: 8px; right: 6px; font-size: 11px; }
  .vary-tools { bottom: max(16px, env(safe-area-inset-bottom)); font-size: 12px; }
  .vary-tools button { padding: 7px 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .feel-pad.is-asking .feel-word { animation: none; }
  .feel-pad:not(.is-dragging) .feel-puck { transition: none; }
}
