:root {
  color-scheme: dark;
  --stone: oklch(0.13 0.018 255);
  --stone-deep: oklch(0.065 0.012 255);
  --oak: oklch(0.28 0.068 48);
  --oak-dark: oklch(0.16 0.045 38);
  --oak-light: oklch(0.39 0.086 60);
  --leather: oklch(0.2 0.055 28);
  --leather-dark: oklch(0.1 0.028 24);
  --iron: oklch(0.23 0.012 45);
  --iron-dark: oklch(0.105 0.006 45);
  --brass: oklch(0.68 0.13 78);
  --brass-bright: oklch(0.84 0.16 84);
  --brass-dark: oklch(0.42 0.1 72);
  --wax: oklch(0.46 0.17 25);
  --mimic: oklch(0.48 0.16 24);
  --tongue: oklch(0.62 0.18 18);
  --vellum: oklch(0.82 0.065 82);
  --vellum-deep: oklch(0.68 0.08 77);
  --vellum-ink: oklch(0.18 0.045 44);
  --vellum-text: oklch(0.34 0.1 40);
  --vellum-text-muted: oklch(0.34 0.055 48);
  --vellum-text-strong: oklch(0.24 0.055 44);
  --vellum-text-dim: oklch(0.32 0.06 48);
  --vellum-text-accent: oklch(0.28 0.12 28);
  --placeholder: oklch(0.3 0.05 48);
  --tooth: oklch(0.96 0.025 92);
  --ink: oklch(0.97 0.02 86);
  --muted: oklch(0.82 0.045 78);
  --dim: oklch(0.68 0.045 70);
  --danger: oklch(0.68 0.2 26);
  --raised-shadow:
    0 2px 0 oklch(1 0 0 / 0.06) inset,
    0 -12px 24px oklch(0 0 0 / 0.22) inset,
    0 12px 0 oklch(0.04 0.012 24 / 0.9),
    0 26px 36px oklch(0 0 0 / 0.42);

  /* Type scale — 8 steps, 1.125–1.2 ratio between closely-spaced steps.
     xs is micro labels only; sm covers secondary metadata and notes;
     base is body and form labels; md/lg are emphasized text and h3;
     xl is h2 and data; 2xl is mobile h1; display is desktop h1. */
  --text-xs: 0.8125rem;      /* 13px — micro labels, avatar initials only */
  --text-sm: 0.9375rem;      /* 15px — secondary metadata, notes, inputs */
  --text-base: 1rem;         /* 16px — body, form labels */
  --text-md: 1.125rem;       /* 18px — song titles, emphasized body */
  --text-lg: 1.25rem;        /* 20px — h3 */
  --text-xl: 1.5rem;         /* 24px — h2, stat numbers */
  --text-2xl: 2.625rem;      /* 42px — mobile h1 */
  --text-display: clamp(2.75rem, 5vw, 3.75rem); /* 44–60px — h1 */

  /* Font families — Cinzel for display (carved stone), Crimson Pro for body
     (old-style serif, reads like printed vellum). Both from Google Fonts. */
  --font-display: "Cinzel", "Trajan Pro", Georgia, "Times New Roman", serif;
  --font-body: "Crimson Pro", Georgia, "Times New Roman", serif;

  font-family: var(--font-body);
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1, "onum" 1;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  background:
    radial-gradient(ellipse at 48% -8%, oklch(0.72 0.15 82 / 0.18), transparent 34rem),
    radial-gradient(circle at 9% 23%, oklch(0.42 0.14 28 / 0.2), transparent 24rem),
    radial-gradient(circle at 92% 8%, oklch(0.38 0.12 304 / 0.22), transparent 28rem),
    linear-gradient(180deg, oklch(0.16 0.025 260), var(--stone) 42%, var(--stone-deep));
}

body::before {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 18% 28%, oklch(1 0 0 / 0.035) 0 0.08rem, transparent 0.12rem),
    radial-gradient(circle at 72% 38%, oklch(0 0 0 / 0.18) 0 0.1rem, transparent 0.13rem),
    radial-gradient(circle at 52% 80%, oklch(1 0 0 / 0.025) 0 0.07rem, transparent 0.1rem),
    linear-gradient(180deg, transparent, oklch(0 0 0 / 0.26));
  content: "";
}

/* Logged-out closed tavern. This branch does not use the app shell,
   hero panel, queue panel, or shared button classes. */
.lo-shell {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(20rem, 0.82fr) minmax(0, 1.18fr);
  gap: 1.45rem;
  width: min(1750px, calc(100% - 2rem));
  min-height: 100vh;
  margin: 0 auto;
  padding: 1rem 0;
  overflow: hidden;
  color: var(--ink);
}

.lo-sky,
.lo-sky::before,
.lo-sky::after {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.lo-sky {
  background:
    radial-gradient(circle at 75% 14%, oklch(0.92 0.055 96 / 0.92) 0 3.25rem, transparent 3.42rem),
    radial-gradient(circle at 71% 16%, oklch(0.8 0.12 92 / 0.2), transparent 10rem),
    radial-gradient(ellipse at 42% 10%, oklch(0.62 0.16 302 / 0.18), transparent 25rem),
    radial-gradient(ellipse at 58% -8%, oklch(0.48 0.14 218 / 0.2), transparent 30rem),
    radial-gradient(ellipse at 18% 80%, oklch(0.48 0.15 24 / 0.16), transparent 28rem),
    linear-gradient(180deg, oklch(0.18 0.06 266), oklch(0.09 0.04 258) 56%, oklch(0.035 0.018 245));
}

.lo-sky::before {
  content: "";
  background:
    radial-gradient(circle at 8% 18%, oklch(1 0 0 / 0.82) 0 1px, transparent 1.6px),
    radial-gradient(circle at 18% 43%, oklch(1 0 0 / 0.55) 0 1px, transparent 1.5px),
    radial-gradient(circle at 34% 12%, oklch(1 0 0 / 0.74) 0 1px, transparent 1.6px),
    radial-gradient(circle at 51% 31%, oklch(1 0 0 / 0.6) 0 1px, transparent 1.5px),
    radial-gradient(circle at 68% 52%, oklch(1 0 0 / 0.44) 0 1px, transparent 1.5px),
    radial-gradient(circle at 84% 27%, oklch(1 0 0 / 0.72) 0 1px, transparent 1.6px),
    radial-gradient(circle at 93% 66%, oklch(1 0 0 / 0.48) 0 1px, transparent 1.5px),
    radial-gradient(circle at 27% 72%, oklch(0.95 0.035 92 / 0.46) 0 1px, transparent 1.45px),
    radial-gradient(circle at 61% 11%, oklch(0.95 0.035 92 / 0.5) 0 1px, transparent 1.45px),
    radial-gradient(circle at 79% 78%, oklch(0.95 0.035 92 / 0.38) 0 1px, transparent 1.45px);
  animation: lo-stars 5.6s ease-in-out infinite;
}

.lo-sky::after {
  content: "";
  background:
    radial-gradient(ellipse at 25% 18%, oklch(0.58 0.12 288 / 0.16), transparent 18rem),
    radial-gradient(ellipse at 63% 32%, oklch(0.42 0.12 220 / 0.18), transparent 22rem),
    radial-gradient(ellipse at 42% 102%, oklch(0 0 0 / 0.5), transparent 35rem),
    linear-gradient(180deg, transparent 56%, oklch(0.02 0.012 248 / 0.5));
  animation: lo-sky-breathe 9s ease-in-out infinite;
}

.lo-star,
.lo-cloud,
.lo-fog {
  position: fixed;
  z-index: 0;
  pointer-events: none;
}

.lo-star {
  width: 0.18rem;
  height: 0.18rem;
  border-radius: 50%;
  background: oklch(0.96 0.02 92);
  box-shadow: 0 0 0.75rem oklch(0.86 0.1 92 / 0.42);
}

.lo-star.one {
  top: 17%;
  left: 44%;
  animation: lo-drift-a 16s linear infinite;
}

.lo-star.two {
  top: 30%;
  left: 88%;
  animation: lo-drift-b 19s linear infinite;
}

.lo-star.three {
  top: 9%;
  left: 13%;
  animation: lo-drift-a 22s linear infinite reverse;
}

.lo-cloud {
  width: 34rem;
  height: 10rem;
  border-radius: 999px;
  background:
    radial-gradient(ellipse at 35% 52%, oklch(0.24 0.06 272 / 0.22), transparent 60%),
    radial-gradient(ellipse at 62% 48%, oklch(0.16 0.05 256 / 0.2), transparent 68%);
  filter: blur(16px);
}

.lo-cloud.one {
  top: 16%;
  left: 11%;
  animation: lo-clouds 36s linear infinite;
}

.lo-cloud.two {
  right: -8rem;
  bottom: 19%;
  animation: lo-clouds 44s linear infinite reverse;
}

.lo-fog {
  height: 12rem;
  border-radius: 999px;
  opacity: 0.34;
  background:
    radial-gradient(ellipse at 18% 50%, oklch(0.74 0.05 255 / 0.18), transparent 62%),
    radial-gradient(ellipse at 58% 52%, oklch(0.64 0.06 278 / 0.16), transparent 68%),
    radial-gradient(ellipse at 88% 48%, oklch(0.5 0.05 230 / 0.12), transparent 60%);
  filter: blur(22px);
  transform: translate3d(0, 0, 0);
}

.lo-fog.one {
  right: -12rem;
  bottom: 8%;
  width: 54rem;
  animation: lo-fog-drift-a 32s linear infinite;
}

.lo-fog.two {
  left: -16rem;
  bottom: 24%;
  width: 48rem;
  animation: lo-fog-drift-b 40s linear infinite;
}

.lo-fog.three {
  left: 18%;
  top: 24%;
  width: 34rem;
  height: 8rem;
  opacity: 0.18;
  animation: lo-fog-drift-c 52s linear infinite;
}

.lo-aside {
  position: relative;
  z-index: 1;
  display: grid;
  align-content: center;
  gap: 1.5rem;
  min-height: calc(100vh - 2rem);
  padding: 0.75rem;
}

.lo-sign-wrap {
  position: relative;
  width: min(22rem, 100%);
  margin: 0 auto;
  padding-top: 4.2rem;
}

.lo-sign-wrap::before {
  position: absolute;
  top: -5.25rem;
  left: 50%;
  z-index: 3;
  width: min(31rem, calc(100vw - 4rem));
  height: 1.16rem;
  border: 1px solid oklch(0.47 0.014 58 / 0.34);
  border-radius: 0.42rem;
  background:
    radial-gradient(circle at 8% 37%, oklch(0 0 0 / 0.52) 0 0.08rem, transparent 0.1rem),
    radial-gradient(circle at 18% 67%, oklch(0.68 0.018 64 / 0.22) 0 0.05rem, transparent 0.07rem),
    radial-gradient(circle at 31% 29%, oklch(0 0 0 / 0.5) 0 0.06rem, transparent 0.08rem),
    radial-gradient(circle at 46% 73%, oklch(0.78 0.02 68 / 0.18) 0 0.055rem, transparent 0.08rem),
    radial-gradient(circle at 62% 34%, oklch(0 0 0 / 0.46) 0 0.075rem, transparent 0.1rem),
    radial-gradient(circle at 78% 64%, oklch(0 0 0 / 0.5) 0 0.065rem, transparent 0.09rem),
    radial-gradient(circle at 91% 38%, oklch(0.7 0.018 64 / 0.2) 0 0.05rem, transparent 0.075rem),
    linear-gradient(90deg, oklch(0.035 0.003 45), transparent 12% 88%, oklch(0.035 0.003 45)),
    repeating-linear-gradient(96deg, transparent 0 0.36rem, oklch(1 0 0 / 0.04) 0.37rem 0.42rem, transparent 0.43rem 0.74rem),
    linear-gradient(180deg, oklch(0.43 0.012 58), oklch(0.22 0.008 50) 34%, oklch(0.07 0.004 45) 72%, oklch(0.025 0.003 45));
  box-shadow:
    inset 0 0.12rem 0.08rem oklch(1 0 0 / 0.12),
    inset 0 0.34rem 0.2rem oklch(0.7 0.016 65 / 0.09),
    inset 0 -0.18rem 0.1rem oklch(0 0 0 / 0.82),
    inset 0 -0.42rem 0.32rem oklch(0 0 0 / 0.48),
    0 0.18rem 0 oklch(0.015 0.002 45 / 0.96),
    0 0.56rem 0.48rem oklch(0 0 0 / 0.56);
  content: "";
  transform: translateX(-50%);
}

.lo-sign-wrap::after {
  position: absolute;
  top: -5.42rem;
  left: 50%;
  z-index: 4;
  width: min(33.25rem, calc(100vw - 2.4rem));
  height: 1.5rem;
  border-radius: 0.48rem;
  background:
    radial-gradient(ellipse at 2.5% 50%, oklch(0.11 0.006 46) 0 0.72rem, transparent 0.74rem),
    radial-gradient(ellipse at 97.5% 50%, oklch(0.11 0.006 46) 0 0.72rem, transparent 0.74rem),
    radial-gradient(circle at 2.5% 31%, oklch(0.73 0.018 66 / 0.24) 0 0.08rem, transparent 0.1rem),
    radial-gradient(circle at 97.5% 31%, oklch(0.73 0.018 66 / 0.22) 0 0.08rem, transparent 0.1rem),
    linear-gradient(90deg, transparent 0 3.2%, oklch(0 0 0 / 0.42) 3.3% 3.9%, transparent 4% 96%, oklch(0 0 0 / 0.42) 96.1% 96.7%, transparent 96.8% 100%);
  box-shadow:
    inset 0 0.08rem 0.08rem oklch(1 0 0 / 0.08),
    inset 0 -0.2rem 0.22rem oklch(0 0 0 / 0.58);
  content: "";
  pointer-events: none;
  transform: translateX(-50%);
}

.lo-sign {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 14rem;
  border: 3px solid oklch(0.1 0.025 36);
  border-radius: 3px;
  background:
    linear-gradient(180deg, oklch(0.38 0.07 52 / 0.18), transparent 35%),
    repeating-linear-gradient(2deg, transparent 0 3px, oklch(0.22 0.045 45 / 0.42) 3px 4px, transparent 4px 8px),
    repeating-linear-gradient(-1deg, transparent 0 8px, oklch(0.28 0.055 48 / 0.34) 8px 9px, transparent 9px 15px),
    linear-gradient(90deg, oklch(0.05 0.015 35 / 0.72), transparent 13%, transparent 87%, oklch(0.05 0.015 35 / 0.72)),
    linear-gradient(180deg, oklch(0.23 0.055 46), oklch(0.16 0.04 40));
  box-shadow:
    0 0 0 4px oklch(0.65 0.12 78 / 0.26) inset,
    0 0 0 7px oklch(0.07 0.018 30 / 0.92) inset,
    inset 0 8px 16px oklch(0 0 0 / 0.4),
    0 8px 0 oklch(0.035 0.012 28 / 0.82),
    0 14px 8px oklch(0 0 0 / 0.32);
}

.lo-mark {
  width: min(14rem, 58%);
  height: auto;
  filter: drop-shadow(0 4px 3px oklch(0 0 0 / 0.44));
}

.lo-chain {
  --lo-iron-black: oklch(0.075 0.006 45);
  --lo-iron-shadow: oklch(0.02 0.003 45);
  --lo-iron-deep: oklch(0.12 0.008 45);
  --lo-iron-mid: oklch(0.24 0.011 50);
  --lo-iron-high: oklch(0.53 0.018 58);
  position: absolute;
  top: -4.8rem;
  z-index: 2;
  display: flex;
  width: 1.35rem;
  flex-direction: column;
  align-items: center;
  filter: drop-shadow(0.16rem 0.26rem 0.16rem oklch(0 0 0 / 0.6));
  transform-origin: top center;
}

.lo-chain::before {
  position: absolute;
  top: -0.18rem;
  left: 50%;
  width: 1.05rem;
  height: 0.68rem;
  border: 1px solid oklch(0.5 0.018 58 / 0.34);
  border-radius: 0 0 999px 999px;
  background:
    radial-gradient(circle at 35% 28%, var(--lo-iron-high) 0 0.07rem, transparent 0.08rem),
    radial-gradient(circle at 65% 28%, var(--lo-iron-high) 0 0.06rem, transparent 0.075rem),
    linear-gradient(90deg, var(--lo-iron-shadow), var(--lo-iron-mid) 38%, var(--lo-iron-high) 48%, var(--lo-iron-deep) 68%, var(--lo-iron-black));
  box-shadow:
    inset 0.1rem 0 0.12rem oklch(1 0 0 / 0.08),
    inset -0.12rem -0.16rem 0.16rem oklch(0 0 0 / 0.64),
    0 0.18rem 0.18rem oklch(0 0 0 / 0.52);
  content: "";
  transform: translateX(-50%);
}

.lo-chain-left {
  left: calc(50% - 10rem + 0.6rem);
  transform: rotate(-1.5deg);
}

.lo-chain-right {
  right: calc(50% - 10rem + 0.6rem);
  transform: rotate(1.5deg);
}

.lo-chain span {
  position: relative;
  display: block;
  flex: 0 0 auto;
}

.lo-chain span + span {
  margin-top: -0.65rem;
}

.lo-chain span:nth-child(odd) {
  z-index: 2;
  width: 1.16rem;
  height: 1.78rem;
  border-radius: 999px;
  background:
    radial-gradient(ellipse at 32% 14%, oklch(0.82 0.022 70 / 0.34) 0 0.08rem, transparent 0.18rem),
    radial-gradient(ellipse at 72% 86%, oklch(0 0 0 / 0.76) 0 0.18rem, transparent 0.34rem),
    repeating-linear-gradient(124deg, transparent 0 0.2rem, oklch(1 0 0 / 0.045) 0.21rem 0.24rem, transparent 0.25rem 0.48rem),
    linear-gradient(100deg, var(--lo-iron-black), var(--lo-iron-deep) 18%, var(--lo-iron-high) 38%, var(--lo-iron-mid) 47%, var(--lo-iron-black) 63%, var(--lo-iron-deep) 82%, var(--lo-iron-shadow));
  box-shadow:
    inset 0.18rem 0.1rem 0.15rem oklch(1 0 0 / 0.08),
    inset -0.2rem -0.24rem 0.2rem oklch(0 0 0 / 0.62),
    0.08rem 0.16rem 0.14rem oklch(0 0 0 / 0.68),
    0 0 0 1px oklch(0.66 0.022 62 / 0.2);
  -webkit-mask: radial-gradient(ellipse at 50% 50%, transparent 0 39%, #000 41% 100%);
  mask: radial-gradient(ellipse at 50% 50%, transparent 0 39%, #000 41% 100%);
}

.lo-chain span:nth-child(even) {
  z-index: 3;
  width: 0.54rem;
  height: 1.68rem;
  border-radius: 999px;
  background:
    radial-gradient(ellipse at 42% 10%, oklch(0.82 0.02 68 / 0.32), transparent 0.22rem),
    radial-gradient(ellipse at 70% 92%, oklch(0 0 0 / 0.72), transparent 0.3rem),
    repeating-linear-gradient(164deg, transparent 0 0.16rem, oklch(1 0 0 / 0.055) 0.17rem 0.19rem, transparent 0.2rem 0.42rem),
    linear-gradient(90deg, var(--lo-iron-shadow), var(--lo-iron-deep) 18%, var(--lo-iron-high) 44%, var(--lo-iron-mid) 55%, var(--lo-iron-black) 100%);
  box-shadow:
    inset 0.1rem 0 0.12rem oklch(1 0 0 / 0.1),
    inset -0.16rem 0 0.14rem oklch(0 0 0 / 0.6),
    0.12rem 0.18rem 0.16rem oklch(0 0 0 / 0.72),
    0 0 0 1px oklch(0.68 0.022 62 / 0.18);
}

.lo-inscription {
  max-width: 32rem;
  margin: 0 auto;
  text-align: center;
}

.lo-note {
  margin: 0 0 0.65rem;
  color: var(--brass-bright);
  font-size: var(--text-sm);
  font-weight: 800;
}

.lo-inscription h1 {
  max-width: 12ch;
  margin: 0 auto 1rem;
  color: var(--tooth);
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.05;
  text-wrap: balance;
}

.lo-inscription p:not(.lo-note) {
  max-width: 34rem;
  margin: 0 auto;
  color: oklch(0.84 0.04 78);
  font-size: var(--text-md);
  line-height: 1.55;
  text-wrap: pretty;
}

.lo-door-panel {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  min-height: calc(100vh - 2rem);
}

.lo-door {
  position: relative;
  display: grid;
  aspect-ratio: 9 / 16;
  width: auto;
  max-width: min(100%, 34rem);
  height: min(calc(100vh - 2rem), 60rem);
  min-height: 0;
  place-items: center;
  overflow: hidden;
  border: 2px solid oklch(0.07 0.016 32);
  border-radius: 4px;
  background:
    linear-gradient(90deg, oklch(0 0 0 / 0.38), transparent 8%, transparent 92%, oklch(0 0 0 / 0.44)),
    linear-gradient(180deg, oklch(0.37 0.078 55 / 0.24), transparent 24%, oklch(0 0 0 / 0.28)),
    repeating-linear-gradient(89deg, oklch(0.2 0.055 39) 0 1px, transparent 1px 17%),
    repeating-linear-gradient(3deg, transparent 0 7px, oklch(0.31 0.062 47 / 0.38) 7px 9px, transparent 9px 18px),
    repeating-linear-gradient(-2deg, transparent 0 16px, oklch(0.12 0.035 34 / 0.48) 16px 18px, transparent 18px 30px),
    linear-gradient(180deg, oklch(0.31 0.072 48), oklch(0.17 0.048 37) 58%, oklch(0.1 0.032 30));
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.08),
    inset 0 -22px 28px oklch(0 0 0 / 0.42),
    0 10px 0 oklch(0.03 0.01 24 / 0.86);
}

.lo-door::before,
.lo-door::after {
  position: absolute;
  inset: 0;
  content: "";
  pointer-events: none;
}

.lo-door::before {
  background:
    linear-gradient(90deg,
      transparent 0 15.8%,
      oklch(0.055 0.018 28 / 0.74) 16% 16.5%,
      transparent 16.8% 32.6%,
      oklch(0.055 0.018 28 / 0.66) 32.8% 33.3%,
      transparent 33.5% 49.4%,
      oklch(0.055 0.018 28 / 0.7) 49.6% 50.1%,
      transparent 50.3% 66.1%,
      oklch(0.055 0.018 28 / 0.66) 66.3% 66.8%,
      transparent 67% 82.7%,
      oklch(0.055 0.018 28 / 0.74) 82.9% 83.4%,
      transparent 83.6% 100%);
}

.lo-door::after {
  background:
    radial-gradient(ellipse at 50% 20%, oklch(0.78 0.13 82 / 0.08), transparent 24rem),
    radial-gradient(ellipse at 48% 62%, oklch(0 0 0 / 0.34), transparent 27rem);
}

.lo-door-slit {
  position: absolute;
  top: 33%;
  left: 9%;
  right: 9%;
  z-index: 2;
  height: 3.5rem;
  overflow: hidden;
  border: 1px solid oklch(0.055 0.015 30);
  background:
    linear-gradient(180deg, oklch(0.012 0.006 250), oklch(0.035 0.018 254) 48%, oklch(0.01 0.005 250));
  box-shadow:
    inset 0 0.62rem 0.72rem oklch(0 0 0 / 0.86),
    inset 0 -0.52rem 0.58rem oklch(0 0 0 / 0.86),
    inset 0.5rem 0 0.6rem oklch(0 0 0 / 0.76),
    inset -0.5rem 0 0.6rem oklch(0 0 0 / 0.76),
    0 0.45rem 0.4rem oklch(0 0 0 / 0.32);
}

.lo-slit-chamber,
.lo-slit-slide,
.lo-slit-frame {
  position: absolute;
  inset: 0;
}

.lo-slit-chamber {
  z-index: 1;
  background:
    radial-gradient(ellipse at 33% 48%, oklch(0.74 0.18 84 / 0.28), transparent 8%),
    radial-gradient(ellipse at 62% 48%, oklch(0.74 0.18 84 / 0.26), transparent 8%),
    radial-gradient(ellipse at 47% 50%, oklch(0.42 0.16 22 / 0.18), transparent 36%),
    linear-gradient(180deg, oklch(0.012 0.006 250), oklch(0.05 0.022 254) 46%, oklch(0.01 0.005 250));
}

.lo-eye {
  position: absolute;
  z-index: 2;
  top: 50%;
  width: 1.05rem;
  height: 0.62rem;
  border-radius: 999px;
  background:
    radial-gradient(circle at 50% 52%, oklch(0.12 0.06 35) 0 0.12rem, transparent 0.13rem),
    radial-gradient(ellipse at 50% 52%, oklch(0.96 0.18 82) 0 0.28rem, oklch(0.66 0.2 31) 0.3rem 0.38rem, transparent 0.4rem);
  box-shadow:
    0 0 0.6rem oklch(0.76 0.2 34 / 0.48),
    0 0 1.1rem oklch(0.82 0.16 82 / 0.28);
  transform: translateY(-50%);
  animation: lo-eye-watch 4.8s ease-in-out infinite;
}

.lo-eye-left {
  left: 34%;
}

.lo-eye-right {
  left: 58%;
  width: 1.12rem;
}

.lo-eye-small {
  left: 47%;
  top: 57%;
  width: 0.62rem;
  height: 0.38rem;
  opacity: 0.75;
}

.lo-slit-slide {
  z-index: 3;
  inset: 0 auto 0 -5%;
  width: 112%;
  background:
    linear-gradient(90deg, oklch(0 0 0 / 0.28), transparent 10%, transparent 86%, oklch(0 0 0 / 0.32)),
    repeating-linear-gradient(2deg, transparent 0 6px, oklch(0.31 0.062 47 / 0.46) 6px 8px, transparent 8px 15px),
    repeating-linear-gradient(-1deg, transparent 0 13px, oklch(0.13 0.038 34 / 0.5) 13px 15px, transparent 15px 25px),
    linear-gradient(180deg, oklch(0.28 0.064 46), oklch(0.13 0.038 34));
  box-shadow:
    inset 0 0 0 1px oklch(0 0 0 / 0.34),
    inset 0 0.16rem 0 oklch(1 0 0 / 0.06),
    inset 0 -0.24rem 0.28rem oklch(0 0 0 / 0.38);
  animation: lo-slit-slide-open 1.35s 0.45s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.lo-slit-frame {
  z-index: 4;
  background:
    linear-gradient(180deg, oklch(0 0 0 / 0.7), transparent 22%, transparent 76%, oklch(0 0 0 / 0.72)),
    linear-gradient(90deg, oklch(0 0 0 / 0.58), transparent 6%, transparent 94%, oklch(0 0 0 / 0.58));
  box-shadow:
    inset 0 0.28rem 0.2rem oklch(0.04 0.016 30),
    inset 0 -0.28rem 0.18rem oklch(0.04 0.016 30);
}

.lo-door-crossbar {
  position: absolute;
  left: 5%;
  right: 5%;
  z-index: 1;
  height: 3.2rem;
  border: 1px solid oklch(0.08 0.018 34);
  background:
    linear-gradient(180deg, oklch(0.36 0.075 52), oklch(0.18 0.047 36)),
    oklch(0.22 0.055 42);
  box-shadow:
    inset 0 0.2rem 0 oklch(1 0 0 / 0.07),
    inset 0 -0.35rem 0.4rem oklch(0 0 0 / 0.35),
    0 0.45rem 0.6rem oklch(0 0 0 / 0.42);
}

.lo-door-crossbar.top {
  top: 15%;
  transform: rotate(-1deg);
}

.lo-door-crossbar.bottom {
  bottom: 15%;
  transform: rotate(1.2deg);
}

.lo-door-knocker {
  position: absolute;
  right: 13%;
  top: 50%;
  z-index: 2;
  width: 4.7rem;
  height: 6.3rem;
  transform: translateY(-50%) rotate(5deg);
}

.lo-door-knocker::before,
.lo-door-knocker::after {
  position: absolute;
  content: "";
  pointer-events: none;
}

.lo-door-knocker::before {
  top: 0;
  left: 50%;
  width: 2.15rem;
  height: 2.15rem;
  border: 0.18rem solid oklch(0.14 0.012 52);
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 28%, oklch(0.76 0.04 72 / 0.7) 0 0.22rem, transparent 0.24rem),
    radial-gradient(circle at 50% 58%, oklch(0.13 0.012 48) 0 0.28rem, transparent 0.3rem),
    linear-gradient(135deg, oklch(0.58 0.035 68), oklch(0.22 0.014 54) 52%, oklch(0.06 0.006 45));
  box-shadow:
    inset 0.16rem 0.16rem 0.16rem oklch(1 0 0 / 0.14),
    inset -0.2rem -0.22rem 0.18rem oklch(0 0 0 / 0.52),
    0 0.22rem 0.24rem oklch(0 0 0 / 0.46);
  transform: translateX(-50%);
}

.lo-door-knocker::after {
  left: 50%;
  bottom: 0;
  width: 3.4rem;
  height: 4.25rem;
  border: 0.44rem solid oklch(0.42 0.035 62);
  border-top-color: oklch(0.58 0.04 70);
  border-right-color: oklch(0.2 0.016 52);
  border-bottom-color: oklch(0.11 0.01 48);
  border-left-color: oklch(0.34 0.025 58);
  border-radius: 50% 50% 48% 48%;
  background: radial-gradient(ellipse at 50% 50%, transparent 0 54%, oklch(0 0 0 / 0.24) 55% 64%, transparent 65%);
  box-shadow:
    inset 0.18rem 0.18rem 0.15rem oklch(1 0 0 / 0.12),
    inset -0.24rem -0.3rem 0.22rem oklch(0 0 0 / 0.48),
    0 0.46rem 0.34rem oklch(0 0 0 / 0.5);
  transform: translateX(-50%);
}

.lo-door-action {
  position: relative;
  z-index: 3;
  display: grid;
  justify-items: center;
  gap: 0.65rem;
  width: min(22rem, calc(100% - 3rem));
  padding: 1rem 1.05rem 1.1rem;
  border: 1px solid oklch(0.11 0.025 36);
  border-radius: 8px;
  background:
    linear-gradient(180deg, oklch(0.2 0.048 38 / 0.98), oklch(0.095 0.025 30 / 0.98));
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.08),
    0 6px 0 oklch(0.035 0.012 26 / 0.82);
  text-align: center;
}

.lo-door-note {
  margin: 0;
  color: oklch(0.82 0.06 78);
  font-size: var(--text-sm);
  font-weight: 700;
}

.lo-door-action h2 {
  margin: 0;
  color: var(--tooth);
  font-family: var(--font-display);
  font-size: 1.75rem;
  line-height: 1.1;
}

.lo-discord-link {
  display: inline-flex;
  min-height: 2.8rem;
  align-items: center;
  justify-content: center;
  padding: 0 1.05rem;
  border-radius: 7px;
  background:
    radial-gradient(ellipse at 50% 0, oklch(0.96 0.15 88 / 0.72), transparent 1.2rem),
    linear-gradient(180deg, var(--brass-bright), var(--brass) 48%, var(--brass-dark));
  color: var(--vellum-ink);
  font-size: var(--text-base);
  font-weight: 800;
  text-decoration: none;
  text-shadow: 0 1px 0 oklch(1 0 0 / 0.15);
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.38),
    inset 0 -4px 0 oklch(0.25 0.07 50 / 0.32),
    0 3px 0 oklch(0.1 0.02 30 / 0.68);
  transition:
    transform 170ms cubic-bezier(0.25, 1, 0.5, 1),
    filter 170ms cubic-bezier(0.25, 1, 0.5, 1);
}

.lo-discord-link:hover {
  filter: brightness(1.06);
  transform: translateY(-1px);
}

.lo-discord-link:active {
  filter: brightness(0.95);
  transform: translateY(0);
}

.lo-discord-link:focus-visible {
  outline: 3px solid oklch(0.9 0.14 84 / 0.55);
  outline-offset: 3px;
}

@keyframes lo-stars {
  0%,
  100% {
    opacity: 0.72;
  }
  50% {
    opacity: 1;
  }
}

@keyframes lo-drift-a {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(2.2rem, 0.7rem, 0);
  }
}

@keyframes lo-drift-b {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-1.8rem, 0.9rem, 0);
  }
}

@keyframes lo-clouds {
  from {
    transform: translate3d(-1.5rem, 0, 0);
  }
  to {
    transform: translate3d(2rem, 0.6rem, 0);
  }
}

@keyframes lo-fog-drift-a {
  0% {
    opacity: 0.22;
    transform: translate3d(0, 0, 0);
  }
  50% {
    opacity: 0.4;
    transform: translate3d(-8rem, -0.8rem, 0);
  }
  100% {
    opacity: 0.22;
    transform: translate3d(-16rem, 0.35rem, 0);
  }
}

@keyframes lo-fog-drift-b {
  0% {
    opacity: 0.16;
    transform: translate3d(0, 0, 0);
  }
  50% {
    opacity: 0.32;
    transform: translate3d(7rem, 0.7rem, 0);
  }
  100% {
    opacity: 0.16;
    transform: translate3d(14rem, -0.2rem, 0);
  }
}

@keyframes lo-fog-drift-c {
  0%,
  100% {
    transform: translate3d(-2rem, 0, 0);
  }
  50% {
    transform: translate3d(2rem, 0.6rem, 0);
  }
}

@keyframes lo-sky-breathe {
  0%,
  100% {
    opacity: 0.82;
  }
  50% {
    opacity: 1;
  }
}

@keyframes lo-slit-slide-open {
  to {
    transform: translateX(78%);
  }
}

@keyframes lo-eye-watch {
  0%,
  100% {
    filter: brightness(0.9);
  }
  48% {
    filter: brightness(1.18);
  }
  53% {
    filter: brightness(0.58) scaleY(0.28);
  }
  58% {
    filter: brightness(1.12);
  }
}

@media (prefers-reduced-motion: reduce) {
  .lo-sky::after,
  .lo-sky::before,
  .lo-star,
  .lo-cloud,
  .lo-fog,
  .lo-eye {
    animation: none;
  }

  .lo-slit-slide {
    transform: translateX(78%);
    animation: none;
  }
}

@media (max-width: 900px) {
  .lo-shell {
    grid-template-columns: 1fr;
    gap: 1rem;
    width: min(100% - 1rem, 48rem);
    overflow: visible;
    min-height: 0;
  }

  .lo-aside {
    min-height: auto;
    padding: 2.8rem 0.5rem 0;
  }

  .lo-sign-wrap {
    width: min(18rem, 82vw);
    padding-top: 0;
  }

  .lo-sign-wrap::before {
    display: none;
  }

  .lo-sign-wrap::after {
    display: none;
  }

  .lo-sign {
    min-height: 11.5rem;
  }

  .lo-mark {
    width: min(11rem, 58%);
  }

  .lo-chain {
    top: -3.35rem;
  }

  .lo-chain-left {
    left: 1.65rem;
  }

  .lo-chain-right {
    right: 1.65rem;
  }

  .lo-inscription h1 {
    max-width: 13ch;
    font-size: 2.625rem;
  }

  .lo-inscription p:not(.lo-note) {
    font-size: var(--text-base);
  }

  .lo-door-panel {
    min-height: 0;
    padding: 0.5rem 0 1rem;
    place-items: start center;
  }

  .lo-door {
    height: auto;
    width: min(100%, 24rem);
  }
}

@media (max-width: 560px) {
  .lo-shell {
    width: min(100% - 0.75rem, 30rem);
    padding: 0.5rem 0;
  }

  .lo-sign-wrap {
    width: min(15.5rem, 82vw);
  }

  .lo-sign {
    min-height: 9.8rem;
  }

  .lo-chain {
    top: -3.05rem;
    width: 1rem;
    transform-origin: top center;
  }

  .lo-chain span:nth-child(odd) {
    width: 0.98rem;
    height: 1.5rem;
  }

  .lo-chain span:nth-child(even) {
    width: 0.46rem;
    height: 1.42rem;
  }

  .lo-chain span + span {
    margin-top: -0.55rem;
  }

  .lo-chain-left {
    left: 1.35rem;
  }

  .lo-chain-right {
    right: 1.35rem;
  }

  .lo-inscription {
    max-width: 25rem;
  }

  .lo-inscription h1 {
    font-size: 2.2rem;
  }

  .lo-door-panel {
    min-height: 0;
  }

  .lo-door {
    width: min(100%, 21rem);
  }

  .lo-door-slit {
    left: 7%;
    right: 7%;
    height: 3rem;
  }

  .lo-door-crossbar {
    height: 2.5rem;
  }

  .lo-door-action {
    width: min(19rem, calc(100% - 1.6rem));
  }

  .lo-door-action h2 {
    font-size: 1.45rem;
  }

  .lo-discord-link {
    width: 100%;
  }
}

button,
input {
  font: inherit;
}

a {
  color: inherit;
}

.app-shell {
  position: relative;
  display: grid;
  grid-template-columns: minmax(20rem, 0.82fr) minmax(0, 1.18fr);
  gap: 1.45rem;
  /* In idle mode we keep a comfortable reading width (max
     1750px centered) so the brand hero and ledger feel like a
     well-typeset book on a wide monitor. In playing mode the
     overrides below drop the cap and use the full viewport —
     a karaoke stage wants every pixel. */
  width: min(1750px, calc(100% - 2rem));
  min-height: 100vh;
  margin: 0 auto;
  padding: 1rem 0;
}

/* ============================================================
   Layout swap: idle (single page) vs playing (stage + sidebar).
   Hard switch — no transition. The data-layout attribute is set
   by the App() component based on session.status.

   Playing layout grid:
     row 1: top bar (auto height, full width)
     row 2: sidebar (left) | stage (right, flex-grow)
   Below the 880px breakpoint the playing layout collapses to a
   single column and the stage (video embed) is hidden — the
   queue becomes the main view. The rotation prompt is rendered
   by the component layer (Phase H).
   ============================================================ */

.app-shell[data-layout="playing"] {
  /* Single-column on small screens (queue-only, no video).
     Two-column layout kicks in via @media (min-width: 880px).
     Width is full viewport (minus a small gutter) so 4K, 2K,
     8K, foldable landscape — every landscape aspect ratio —
     uses the entire screen. No 1750px cap here. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "topbar"
    "queue";
  width: calc(100% - 1rem);
  margin: 0 auto;
  min-height: 100vh;
}

@media (min-width: 880px) {
  .app-shell[data-layout="playing"] {
    grid-template-columns: 320px minmax(0, 1fr);
    grid-template-rows: 56px 1fr;
    /* Two rows × two columns. The topbar spans both columns.
       The queue-panel spans row 2 col 1 + 2 — its own internal
       grid splits that row into the queue sidebar and the main
       queue content. Note the row 2 area is also named "queue"
       (matches the base mobile rule above, and matches the
       queue-panel's grid-area: queue), NOT "sidebar stage".
       The original CSS had named the areas "sidebar stage" but
       those are areas inside the queue-panel — naming them at
       the app-shell level created implicit grid tracks that
       broke the layout. */
    grid-template-areas:
      "topbar topbar"
      "queue queue";
    gap: 0.85rem;
    /* Full viewport width (minus a small gutter). 4K, 2K, 8K,
       ultrawide — every landscape ratio uses the whole screen.
       The internal max-width on .hero-panel and .queue-panel
       keeps their content centered without capping the shell. */
    width: calc(100% - 2rem);
    margin: 0 auto;
    padding: 0.85rem 0;
    min-height: 100vh;
  }
}

/* Tablet (880-1199px): narrower sidebar, slightly shorter top bar.
   Below the top bar collapses to 48px; the sidebar drops to 280px.
   This buys a couple inches of stage width on iPad-sized screens
   without breaking the layout. */
@media (min-width: 880px) and (max-width: 1199px) {
  .app-shell[data-layout="playing"] {
    grid-template-columns: 280px minmax(0, 1fr);
    grid-template-rows: 48px 1fr;
  }
}

/* Wide desktops: slightly wider sidebar. The 320px mark is a
   sweet spot — wide enough for the compact candle + queue rows
   to read clearly, narrow enough that a 1080p monitor still has
   1700+px of stage area for the 16:9 video. */
@media (min-width: 1600px) {
  .app-shell[data-layout="playing"] {
    grid-template-columns: 360px minmax(0, 1fr);
  }
}

/* Assign grid areas. .hero-panel becomes the top bar; .queue-panel
   becomes the main area. The sidebar is a child of the queue
   panel — not a separate grid item — so we can keep the queue
   content inside its existing container. */
.app-shell[data-layout="playing"] .hero-panel {
  grid-area: topbar;
  height: clamp(48px, 5vw, 64px);
  min-height: 0;
  padding: 0;
  overflow: hidden;
}

.app-shell[data-layout="playing"] .queue-panel {
  grid-area: queue;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "sidebar"
    "songs";
  gap: 0.6rem;
  overflow: hidden;
}

@media (min-width: 880px) {
  .app-shell[data-layout="playing"] .queue-panel {
    grid-template-columns: 320px minmax(0, 1fr);
    grid-template-rows: 1fr;
    grid-template-areas:
      "sidebar songs";
    gap: 0.85rem;
  }
}

/* The proposal form + mimic live inside .queue-panel today. In
   playing mode we hide them — the top bar handles proposing, and
   the mimic is decoration we don't need mid-song. */
.app-shell[data-layout="playing"] .mimic-stage,
.app-shell[data-layout="playing"] .offering-board,
.app-shell[data-layout="playing"] .toolbar {
  display: none;
}

.app-shell[data-layout="playing"] .hero-copy,
.app-shell[data-layout="playing"] .chain,
.app-shell[data-layout="playing"] .stat-board {
  display: none;
}

/* TopBar is only meaningful in playing mode. Hidden in idle. */
.app-shell[data-layout="idle"] .topbar {
  display: none;
}

/* Queue sidebar (Phase E will populate). In idle layout it's
   hidden — the sidebar only exists when the night is started.
   In playing layout it occupies the .queue-panel "sidebar" grid
   area. On mobile (<880px) it stacks above the songs area.
   The placeholder border keeps it visible during development so
   we can see the layout structure; Phase E replaces it with a
   proper sidebar. */
.queue-sidebar {
  display: none;
}

.app-shell[data-layout="playing"] .queue-sidebar {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 0.85rem;
  border: 1px solid var(--iron-dark);
  outline: 1px solid oklch(0.86 0.14 84 / 0.18);
  border-radius: 4px;
  /* Same woody/oak background as the idle-layout queue-panel —
     a leather ledger darkening to oak at the bottom, with the
     radial highlights that give it depth. The pale vellum it had
     before washed out the candle and competed with the song rows
     for contrast; the oak palette keeps the sidebar reading like
     part of the same furniture as the rest of the tavern. */
  background:
    radial-gradient(circle at 50% 0%, oklch(0.78 0.14 82 / 0.08), transparent 14rem),
    linear-gradient(180deg, oklch(0.32 0.06 42) 0%, var(--oak) 18%, var(--oak-dark) 96%),
    var(--oak);
  color: var(--ink);
  overflow-y: auto;
  grid-area: sidebar;
  min-height: 0;
}

.sidebar-candle {
  /* Compact candle: shrink the SVG and stack the meter-text
     tighter so it fits a ~280-360px sidebar comfortably. */
}

.sidebar-candle .meter-svg {
  width: 56px;
  height: 140px;
  flex: 0 0 auto;
}

/* The tankard's general rule (`.wax-candle-meter .meter-svg--tankard
   { width: 100% }`) overrides a simple `.sidebar-candle` selector,
   so we scope with the parent attribute selector to win specificity. */
.app-shell[data-layout="playing"] .sidebar-candle .meter-svg--tankard {
  width: 130px;
  height: auto;
  aspect-ratio: 5 / 2;
  flex: 0 0 auto;
}

.sidebar-candle .meter-text {
  flex: 1 1 auto;
  min-width: 0;
}

.sidebar-candle .wax-candle-meter {
  gap: 0.5rem;
}

.sidebar-candle .meter-text .meter-now {
  font-size: var(--text-base);
}

.sidebar-candle .meter-text .meter-sub {
  font-size: var(--text-xs, 0.75rem);
}

.sidebar-queue {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  flex: 1 1 auto;
  min-height: 0;
}

.sidebar-section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid oklch(0.84 0.12 82 / 0.28);
}

.sidebar-section-header h3 {
  margin: 0;
  font-size: var(--text-base);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--vellum);
  font-family: var(--font-display);
}

.sidebar-section-count {
  font-size: var(--text-sm);
  color: oklch(0.78 0.05 78);
}

.sidebar-song-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 0;
}

.sidebar-subheading {
  margin: 0.5rem 0 0.25rem;
  font-size: var(--text-sm);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--vellum);
  font-weight: 600;
}

.sidebar-filter-bar {
  display: flex;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}

.sidebar-filter-bar .filter-input {
  flex: 1;
  padding: 0.45rem 0.7rem;
  font-size: var(--text-sm);
}

.sidebar-filter-bar .filter-select {
  padding: 0.45rem 0.7rem;
  font-size: var(--text-sm);
  min-width: 110px;
}

/* In the sidebar the SongRow needs to compress to a narrower
   width. The idle-layout SongRow is tuned for ~700px+ main
   content; in a 280-360px sidebar the 7.5rem thumbnail + 1fr
   text + auto buttons overflows. We stack the thumbnail above
   the metadata and put the action buttons inline below the
   main column so the row still reads as a single card but fits
   the column. */
.app-shell[data-layout="playing"] .song-row {
  grid-template-columns: 1fr;
  grid-template-rows: auto auto;
  padding: 0.55rem 0.7rem;
  gap: 0.45rem;
  font-size: var(--text-sm);
}

.app-shell[data-layout="playing"] .song-row .song-thumb {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  max-height: 5.5rem;
  display: block;
}

.app-shell[data-layout="playing"] .song-row .song-thumb img,
.app-shell[data-layout="playing"] .song-row .song-thumb span {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  font-size: 0; /* hide the "YT" placeholder text */
}

.app-shell[data-layout="playing"] .song-row .song-heading {
  flex-wrap: wrap;
  gap: 0.15rem 0.5rem;
}

.app-shell[data-layout="playing"] .song-row .song-heading a {
  font-size: var(--text-base);
  flex-basis: 100%;
}

.app-shell[data-layout="playing"] .song-row .song-meta {
  flex-wrap: wrap;
  gap: 0.2rem 0.4rem;
  font-size: var(--text-xs);
}

.app-shell[data-layout="playing"] .song-row .song-actions {
  align-items: flex-start;
}

.app-shell[data-layout="playing"] .song-row .delete-button,
.app-shell[data-layout="playing"] .song-row .admin-button {
  font-size: var(--text-xs);
  padding: 0.25rem 0.5rem;
  align-self: flex-start;
}

.app-shell[data-layout="playing"] .song-row .notes-add-button,
.app-shell[data-layout="playing"] .song-row .notes-edit-button {
  background: transparent;
  color: var(--dim);
  border-color: transparent;
}

.app-shell[data-layout="playing"] .song-row .notes-add-button:hover,
.app-shell[data-layout="playing"] .song-row .notes-edit-button:hover {
  background: oklch(1 0 0 / 0.04);
  color: var(--tooth);
  border-color: oklch(1 0 0 / 0.08);
}

.app-shell[data-layout="playing"] .song-row .notes-editor {
  font-size: var(--text-xs);
}

.sidebar-song-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.3rem 0.4rem;
  border-radius: 3px;
  font-size: var(--text-sm);
  background: oklch(0.98 0.01 80 / 0.6);
  border: 1px solid oklch(0.86 0.14 84 / 0.18);
}

.sidebar-song-row:hover {
  background: oklch(0.96 0.03 80);
}

.sidebar-song-title {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 600;
  color: var(--tooth);
}

.sidebar-song-duration {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  color: var(--dim);
  font-size: var(--text-xs, 0.75rem);
}

.sidebar-empty {
  margin: 0;
  font-style: italic;
  color: var(--dim);
  font-size: var(--text-sm);
  text-align: center;
  padding: 0.5rem 0;
}

.sidebar-sung-summary {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--dim);
  font-style: italic;
  padding-top: 0.25rem;
  border-top: 1px dashed oklch(0.86 0.14 84 / 0.3);
}

.sidebar-admin {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  flex: 0 0 auto;
  padding-top: 0.5rem;
  border-top: 1px solid oklch(0.86 0.14 84 / 0.3);
}

/* Queue main: in playing mode this gets the "songs" grid area.
   In idle mode it's just a normal block; we don't apply any
   special flex/grid rules so the original layout is preserved
   (the existing CSS handles spacing for toolbar, mimic, songs,
   etc. via their own selectors). */
.app-shell[data-layout="playing"] .queue-main {
  grid-area: songs;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  min-height: 0;
}

/* ============================================================
   Phase H: rotation prompt + no-video below breakpoint
   ============================================================
   In playing mode below the 880px breakpoint the video embed is
   hidden — the queue becomes the main view. If the device's
   portrait height clears the threshold (the device is a small
   tablet or foldable that would fit landscape), show a fixed
   banner above the top bar prompting the user to rotate. Tiny
   phones don't get the prompt (rotating wouldn't help). */

.rotation-prompt {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: 0.55rem 1rem;
  background: linear-gradient(180deg, oklch(0.42 0.16 65) 0%, oklch(0.36 0.14 60) 100%);
  color: oklch(0.16 0.04 50);
  font-weight: 700;
  font-size: var(--text-sm);
  text-align: center;
  border-bottom: 1px solid oklch(0.3 0.15 22);
  box-shadow: 0 2px 8px oklch(0.1 0.02 50 / 0.4);
}

.rotation-prompt[data-visible="1"] {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
}

.rotation-prompt-icon {
  font-size: 1.1em;
}

/* ============================================================
   PlayerStage — the main area in playing mode.

   The stage is a single full-bleed container holding the video
   embed (or fallback). It sits inside .queue-main, which is the
   "songs" grid area of the queue-panel at desktop, or the only
   row at mobile. The stage has no card chrome, no title, no admin
   controls — the top bar owns the song meta and admin actions,
   the sidebar owns the queue. The stage is purely a window onto
   the video. ============================================================ */

/* "Start the night" CTA. Admin-only, lives in the hero-panel
   right above HeroStats. We deliberately do NOT use
   `margin-top: auto` here — the hero-panel is a flex column
   with `justify-content: space-between`, and we want HeroStats
   to remain the last flex item so it stays pinned to the
   bottom. This CTA just sits in its natural position between
   hero-copy and HeroStats. */
.hero-start {
  display: flex;
  justify-content: center;
  padding: 0.75rem 0;
}

.hero-start .admin-button {
  width: 100%;
  max-width: 18rem;
}

.queue-main {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.app-shell[data-layout="playing"] .queue-main {
  padding: 0;
  gap: 0;
}

.app-shell[data-layout="playing"] .queue-main .embed-player {
  flex: 1 1 auto;
  width: 100%;
  height: 100%;
  min-height: 0;
  /* The embed-player already has aspect-ratio 16/9 baked in
     (it's a video). For wide desktop screens the video would
     otherwise center vertically with letterbox bars — the
     queue-panel parent uses min-height: 100% on its row, so
     the embed stretches into the available vertical space and
     the browser letterboxes inside the iframe. */
}

.player-stage-empty {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 0.75rem;
  padding: 3rem 1.5rem;
  background:
    radial-gradient(ellipse at 50% 0%, oklch(0.36 0.07 42 / 0.95), oklch(0.18 0.04 30) 70%);
  border-radius: 4px;
  border: 1px solid var(--iron-dark);
  text-align: center;
  flex: 1 1 auto;
  min-height: 240px;
}

.player-stage-empty-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--vellum);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.player-stage-empty-body {
  margin: 0;
  font-size: var(--text-base);
  color: oklch(0.75 0.04 80);
  max-width: 38ch;
  line-height: 1.5;
}

/* ============================================================
   EmbedPlayer fallback overlay (Phase G)
   ============================================================
   When the YouTube IFrame Player API fails to load (network
   blocked, CSP wrong, etc.) the EmbedPlayer shows this overlay
   instead of the iframe. The thumbnail is preserved from the
   song's metadata; the admin gets a "Mark as sung anyway" button
   so they can still advance the queue. */

.embed-player {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: oklch(0.1 0.04 50);
  border-radius: 4px;
  overflow: hidden;
}

.embed-player-target {
  width: 100%;
  height: 100%;
}

.embed-player-target[data-state="loading"] {
  display: flex;
  align-items: center;
  justify-content: center;
  color: oklch(0.7 0.04 80);
  font-style: italic;
}

.embed-player-target[data-state="loading"]::before {
  content: "Loading the mimic's player…";
  font-size: var(--text-sm);
}

.embed-player-target[data-state="ready"] {
  /* YT replaces this with the iframe; nothing visible from our
     CSS side. The 16:9 aspect comes from the parent. */
}

.embed-player-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, oklch(0.15 0.04 50) 0%, oklch(0.22 0.04 50) 100%);
  color: var(--tooth);
  padding: 1rem;
  gap: 0.75rem;
}

.embed-player-thumb {
  width: 100%;
  max-height: 60%;
  object-fit: contain;
  border-radius: 3px;
}

.embed-player-fallback-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.5rem;
}

.embed-player-fallback-reason {
  margin: 0;
  font-size: var(--text-sm);
  color: oklch(0.88 0.04 80);
  font-style: italic;
}

.embed-player-fallback-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.embed-player-open,
.embed-player-mark-sung {
  background: oklch(0.3 0.05 50);
  border: 1px solid var(--iron-dark);
  color: var(--tooth);
  padding: 0.4rem 0.8rem;
  border-radius: 3px;
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}

.embed-player-open:hover,
.embed-player-mark-sung:hover {
  background: oklch(0.36 0.06 50);
}

.embed-player-mark-sung {
  background: oklch(0.4 0.12 25);
  border-color: oklch(0.3 0.15 22);
}

.embed-player-mark-sung:hover {
  background: oklch(0.46 0.14 25);
}

/* ============================================================
   TopBar (playing mode only)
   ============================================================
   Two-zone horizontal strip:
     - topbar-left: status badge | song title | song duration
     - topbar-right: admin buttons (admin only) | user chip | logout
   On screens too narrow for the full layout the song title
   truncates and the duration hides. The bar is fixed-height
   (set by the parent .hero-panel's height), so children need
   to fit within it. */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  height: 100%;
  padding: 0 0.9rem;
  background: linear-gradient(180deg, oklch(0.18 0.04 50) 0%, oklch(0.22 0.04 50) 100%);
  color: var(--tooth);
  border: 1px solid var(--iron-dark);
  border-radius: 4px;
  box-sizing: border-box;
  overflow: hidden;
}

.topbar-left,
.topbar-right {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  min-width: 0;
}

.topbar-left {
  flex: 1 1 auto;
}

.topbar-right {
  flex: 0 0 auto;
  flex-shrink: 0;
}

.topbar-divider {
  width: 1px;
  height: 1.4em;
  background: var(--iron-dark);
  flex: 0 0 auto;
}

.topbar-title {
  font-size: var(--text-base);
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 1 1 auto;
  color: oklch(0.92 0.04 80);
}

.topbar-progress {
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--dim);
  flex: 0 0 auto;
}

/* Admin buttons row: icon + label. On narrow bars the label
   drops out and only the icon remains (via @media inside the
   bar). */
.topbar-admin {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex: 0 0 auto;
}

.topbar-button {
  background: oklch(0.3 0.04 50);
  border: 1px solid var(--iron-dark);
  color: var(--tooth);
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 0.3rem 0.55rem;
  border-radius: 3px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  white-space: nowrap;
  transition: background 120ms ease, transform 80ms ease;
}

.topbar-button:hover:not(:disabled) {
  background: oklch(0.36 0.05 50);
}

.topbar-button:active:not(:disabled) {
  transform: translateY(1px);
}

.topbar-button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.topbar-button-stop {
  background: oklch(0.4 0.12 25);
  border-color: oklch(0.3 0.15 22);
}

.topbar-button-stop:hover:not(:disabled) {
  background: oklch(0.46 0.14 25);
}

.topbar-button-advance {
  background: oklch(0.32 0.06 145);
  border-color: oklch(0.25 0.08 145);
}

.topbar-button-advance:hover:not(:disabled) {
  background: oklch(0.38 0.07 145);
}

.topbar-button-pause,
.topbar-button-resume {
  background: oklch(0.32 0.06 240);
  border-color: oklch(0.25 0.08 240);
}

.topbar-button-pause:hover:not(:disabled),
.topbar-button-resume:hover:not(:disabled) {
  background: oklch(0.38 0.07 240);
}

.topbar-button-logout {
  background: oklch(0.26 0.03 50);
}

/* Inline stop-confirm form: replaces the Stop button when the
   admin taps it. The input expects the literal "STOP" before
   the Confirm button enables. */
.topbar-stop-confirm {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  background: oklch(0.4 0.12 25 / 0.18);
  border: 1px solid oklch(0.3 0.15 22);
  border-radius: 3px;
  padding: 0.18rem 0.3rem;
}

.topbar-stop-input {
  background: oklch(0.16 0.04 50);
  border: 1px solid oklch(0.3 0.04 50);
  color: var(--tooth);
  font-family: inherit;
  font-size: var(--text-sm);
  padding: 0.18rem 0.4rem;
  border-radius: 2px;
  width: 6.5rem;
  outline: none;
}

.topbar-stop-input:focus {
  border-color: oklch(0.5 0.14 22);
}

/* User chip: avatar + username + logout. The username hides on
   narrow bars (where the avatar alone is enough to identify). */
.topbar-user {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex: 0 0 auto;
}

.topbar-username {
  font-size: var(--text-sm);
  font-weight: 600;
  color: oklch(0.88 0.04 80);
  white-space: nowrap;
}

/* Below the 880px breakpoint the bar compresses: the song title
   collapses to a max-width and the progress badge hides. The
   admin buttons keep both icon + label so the controls are
   unambiguous on a phone. */
@media (max-width: 879px) {
  .topbar {
    padding: 0 0.5rem;
    gap: 0.4rem;
  }
  .topbar-title {
    max-width: 10rem;
  }
  .topbar-progress {
    display: none;
  }
}

@media (max-width: 540px) {
  /* Very narrow bars: drop button labels so the icons fit. */
  .topbar-button-label {
    display: none;
  }
  .topbar-button {
    padding: 0.3rem 0.45rem;
  }
  .topbar-title {
    max-width: 6rem;
  }
}

.hero-panel,
.queue-panel {
  position: relative;
  overflow: hidden;
  border: 2px solid var(--iron-dark);
  outline: 1px solid oklch(0.86 0.14 84 / 0.18);
  outline-offset: -0.65rem;
  box-shadow: var(--raised-shadow);
}

.hero-panel::after,
.queue-panel::after {
  position: absolute;
  inset: 0.85rem;
  background:
    radial-gradient(circle at 0 0, var(--brass) 0 0.28rem, transparent 0.31rem),
    radial-gradient(circle at 100% 0, var(--brass) 0 0.28rem, transparent 0.31rem),
    radial-gradient(circle at 0 100%, var(--brass) 0 0.28rem, transparent 0.31rem),
    radial-gradient(circle at 100% 100%, var(--brass) 0 0.28rem, transparent 0.31rem);
  content: "";
  pointer-events: none;
}

.hero-panel {
  position: sticky;
  top: 1rem;
  display: flex;
  min-height: calc(100vh - 2rem);
  flex-direction: column;
  justify-content: space-between;
  padding: 1.55rem;
  border-radius: 8px 8px 4px 4px;
  background:
    radial-gradient(ellipse at 52% 8%, oklch(0.76 0.16 82 / 0.14), transparent 16rem),
    radial-gradient(ellipse at 28% 28%, oklch(0.48 0.12 52 / 0.28), transparent 10rem),
    radial-gradient(ellipse at 78% 68%, oklch(0.09 0.02 28 / 0.74), transparent 18rem),
    linear-gradient(90deg, oklch(0.07 0.018 25 / 0.64), transparent 14%, transparent 86%, oklch(0.055 0.016 22 / 0.72)),
    linear-gradient(180deg, var(--oak-light), var(--oak) 18%, var(--oak-dark));
}

.hero-panel::before {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg, oklch(1 0 0 / 0.04), transparent 10%, oklch(0 0 0 / 0.1) 13%, transparent 18%, transparent 82%, oklch(0 0 0 / 0.1) 87%, transparent 91%),
    radial-gradient(circle at 17% 65%, oklch(0.54 0.18 24 / 0.16), transparent 12rem),
    linear-gradient(180deg, oklch(1 0 0 / 0.045), transparent 22%, oklch(0 0 0 / 0.26));
  content: "";
}

/* Forged iron chains hanging the sign */
.chain {
  --chain-scale: 1;
  --chain-pin-inset: 0.6rem;
  --iron-black: oklch(0.075 0.006 45);
  --iron-shadow: oklch(0.02 0.003 45);
  --iron-deep: oklch(0.12 0.008 45);
  --iron-mid: oklch(0.24 0.011 50);
  --iron-high: oklch(0.53 0.018 58);
  position: absolute;
  top: -1.15rem;
  z-index: 4;
  display: flex;
  width: 1.35rem;
  flex-direction: column;
  align-items: center;
  pointer-events: none;
  transform-origin: top center;
  filter:
    drop-shadow(0.18rem 0.28rem 0.18rem oklch(0 0 0 / 0.62))
    drop-shadow(0 0.75rem 0.7rem oklch(0 0 0 / 0.36));
}

.chain::before {
  position: absolute;
  top: -0.15rem;
  left: 50%;
  width: 1.05rem;
  height: 0.68rem;
  border: 1px solid oklch(0.5 0.018 58 / 0.34);
  border-radius: 0 0 999px 999px;
  background:
    radial-gradient(circle at 35% 28%, var(--iron-high) 0 0.07rem, transparent 0.08rem),
    radial-gradient(circle at 65% 28%, var(--iron-high) 0 0.06rem, transparent 0.075rem),
    linear-gradient(90deg, var(--iron-shadow), var(--iron-mid) 38%, var(--iron-high) 48%, var(--iron-deep) 68%, var(--iron-black));
  box-shadow:
    inset 0.1rem 0 0.12rem oklch(1 0 0 / 0.08),
    inset -0.12rem -0.16rem 0.16rem oklch(0 0 0 / 0.64),
    0 0.18rem 0.18rem oklch(0 0 0 / 0.52);
  content: "";
  transform: translateX(-50%);
}

.chain::after {
  position: absolute;
  top: 0.45rem;
  bottom: -0.25rem;
  left: 50%;
  z-index: -1;
  width: 0.34rem;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, oklch(0 0 0 / 0.28), transparent);
  content: "";
  transform: translateX(-50%);
}

.chain.left {
  left: calc(50% - 10rem + var(--chain-pin-inset));
  transform: rotate(-1.5deg) scale(var(--chain-scale));
}

.chain.right {
  right: calc(50% - 10rem + var(--chain-pin-inset));
  transform: rotate(1.5deg) scale(var(--chain-scale));
}

.chain .link {
  position: relative;
  display: block;
  flex: 0 0 auto;
  transform-style: preserve-3d;
}

.chain .link + .link {
  margin-top: -0.65rem;
}

.chain .link::before,
.chain .link::after {
  position: absolute;
  content: "";
  pointer-events: none;
}

/* Forward-facing links: open forged ovals with visible inner voids. */
.chain .link:nth-child(odd) {
  z-index: 2;
  width: 1.16rem;
  height: 1.78rem;
  border-radius: 999px;
  background:
    radial-gradient(ellipse at 32% 14%, oklch(0.82 0.022 70 / 0.34) 0 0.08rem, transparent 0.18rem),
    radial-gradient(ellipse at 72% 86%, oklch(0 0 0 / 0.76) 0 0.18rem, transparent 0.34rem),
    repeating-linear-gradient(124deg, transparent 0 0.2rem, oklch(1 0 0 / 0.045) 0.21rem 0.24rem, transparent 0.25rem 0.48rem),
    linear-gradient(100deg, var(--iron-black), var(--iron-deep) 18%, var(--iron-high) 38%, var(--iron-mid) 47%, var(--iron-black) 63%, var(--iron-deep) 82%, var(--iron-shadow));
  box-shadow:
    inset 0.18rem 0.1rem 0.15rem oklch(1 0 0 / 0.08),
    inset -0.2rem -0.24rem 0.2rem oklch(0 0 0 / 0.62),
    0.08rem 0.16rem 0.14rem oklch(0 0 0 / 0.68),
    0 0 0 1px oklch(0.66 0.022 62 / 0.2);
  -webkit-mask: radial-gradient(ellipse at 50% 50%, transparent 0 39%, #000 41% 100%);
  mask: radial-gradient(ellipse at 50% 50%, transparent 0 39%, #000 41% 100%);
}

.chain .link:nth-child(odd)::before {
  inset: 0.11rem 0.2rem auto auto;
  width: 0.2rem;
  height: 1.22rem;
  border-radius: 999px;
  background: linear-gradient(180deg, oklch(0.9 0.02 70 / 0.38), transparent 58%);
  transform: rotate(10deg);
}

.chain .link:nth-child(odd)::after {
  right: 0.18rem;
  bottom: 0.12rem;
  width: 0.22rem;
  height: 0.72rem;
  border-radius: 999px;
  background: oklch(0 0 0 / 0.38);
  transform: rotate(18deg);
}

/* Perpendicular links: edge-on ovals read as thick vertical iron bars. */
.chain .link:nth-child(even) {
  z-index: 3;
  width: 0.54rem;
  height: 1.68rem;
  border-radius: 999px;
  background:
    radial-gradient(ellipse at 42% 10%, oklch(0.82 0.02 68 / 0.32), transparent 0.22rem),
    radial-gradient(ellipse at 70% 92%, oklch(0 0 0 / 0.72), transparent 0.3rem),
    repeating-linear-gradient(164deg, transparent 0 0.16rem, oklch(1 0 0 / 0.055) 0.17rem 0.19rem, transparent 0.2rem 0.42rem),
    linear-gradient(90deg, var(--iron-shadow), var(--iron-deep) 18%, var(--iron-high) 44%, var(--iron-mid) 55%, var(--iron-black) 100%);
  box-shadow:
    inset 0.1rem 0 0.12rem oklch(1 0 0 / 0.1),
    inset -0.16rem 0 0.14rem oklch(0 0 0 / 0.6),
    0.12rem 0.18rem 0.16rem oklch(0 0 0 / 0.72),
    0 0 0 1px oklch(0.68 0.022 62 / 0.18);
}

.chain .link:nth-child(even)::before {
  inset: 0.14rem 0.1rem;
  border-radius: inherit;
  background: linear-gradient(90deg, oklch(1 0 0 / 0.14), transparent 38%, oklch(0 0 0 / 0.28) 76%);
}

.chain .link:nth-child(even)::after {
  top: 50%;
  left: 50%;
  width: 1.02rem;
  height: 0.28rem;
  border-radius: 999px;
  background: radial-gradient(ellipse at center, oklch(0 0 0 / 0.5), transparent 68%);
  transform: translate(-50%, -50%);
}

.hero-copy,
.login-panel,
.stat-board,
.brand-lockup {
  position: relative;
  z-index: 5;
}

.brand-lockup {
  --chain-pin-inset: 0.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20rem;
  margin: 5rem auto 1.35rem;
  padding: 1rem 0.5rem 1.1rem;
  border: 3px solid oklch(0.12 0.025 40);
  border-radius: 3px;
  /* Realistic dark wood grain: layered repeating gradients at slight angles */
  background:
    /* Top sheen: subtle overhead light reflecting off polished wood */
    linear-gradient(180deg,
      oklch(0.35 0.06 50 / 0.18) 0%,
      transparent 35%),
    /* Grain layer 1: fine lines, slight angle */
    repeating-linear-gradient(2deg,
      transparent 0px,
      transparent 3px,
      oklch(0.22 0.045 45 / 0.4) 3px,
      oklch(0.22 0.045 45 / 0.4) 4px,
      transparent 4px,
      transparent 8px),
    /* Grain layer 2: medium lines, opposite angle for depth */
    repeating-linear-gradient(-1deg,
      transparent 0px,
      transparent 6px,
      oklch(0.28 0.055 48 / 0.35) 6px,
      oklch(0.28 0.055 48 / 0.35) 7.5px,
      transparent 7.5px,
      transparent 14px),
    /* Grain layer 3: wider, softer streaks */
    repeating-linear-gradient(0.5deg,
      transparent 0px,
      transparent 12px,
      oklch(0.18 0.035 42 / 0.3) 12px,
      oklch(0.18 0.035 42 / 0.3) 14px,
      transparent 14px,
      transparent 22px),
    /* Grain layer 4: occasional lighter heartwood streaks */
    repeating-linear-gradient(-0.5deg,
      transparent 0px,
      transparent 28px,
      oklch(0.32 0.06 52 / 0.2) 28px,
      oklch(0.32 0.06 52 / 0.2) 30px,
      transparent 30px,
      transparent 45px),
    /* Edge darkening: vignette for aged sign look */
    linear-gradient(90deg,
      oklch(0.06 0.015 35 / 0.7) 0%,
      transparent 12%,
      transparent 88%,
      oklch(0.06 0.015 35 / 0.7) 100%),
    /* Base wood color: dark walnut */
    linear-gradient(180deg,
      oklch(0.22 0.05 46) 0%,
      oklch(0.18 0.04 42) 50%,
      oklch(0.15 0.035 38) 100%);
  box-shadow:
    /* Brass trim inset */
    0 0 0 4px oklch(0.65 0.12 78 / 0.3) inset,
    0 0 0 7px oklch(0.08 0.02 30 / 0.9) inset,
    /* Deep inset shadow for thickness */
    inset 0 8px 16px oklch(0 0 0 / 0.4),
    inset 0 -4px 8px oklch(0 0 0 / 0.25),
    /* Drop shadow for hanging depth */
    0 6px 12px oklch(0 0 0 / 0.5),
    0 12px 24px oklch(0 0 0 / 0.35);
}

.brand-lockup::before,
.brand-lockup::after {
  position: absolute;
  top: -0.45rem;
  z-index: 5;
  width: 1.36rem;
  height: 0.92rem;
  margin: 0 .65rem;
  border: 1px solid oklch(0.58 0.02 62 / 0.28);
  border-radius: 0.18rem 0.18rem 0.42rem 0.42rem;
  background:
    radial-gradient(circle at 32% 68%, oklch(0.78 0.025 70 / 0.55) 0 0.08rem, oklch(0.08 0.006 45) 0.09rem 0.15rem, transparent 0.16rem),
    radial-gradient(circle at 68% 68%, oklch(0.78 0.025 70 / 0.42) 0 0.065rem, oklch(0.07 0.005 45) 0.08rem 0.14rem, transparent 0.15rem),
    linear-gradient(90deg, oklch(0.035 0.004 45), oklch(0.22 0.012 52) 38%, oklch(0.46 0.018 60) 48%, oklch(0.12 0.009 48) 68%, oklch(0.025 0.003 45));
  box-shadow:
    inset 0.08rem 0.1rem 0.12rem oklch(1 0 0 / 0.08),
    inset -0.12rem -0.16rem 0.18rem oklch(0 0 0 / 0.64),
    0 0.18rem 0.18rem oklch(0 0 0 / 0.46);
  content: "";
}

.brand-lockup::before {
  left: var(--chain-pin-inset);
  transform: translateX(-50%);
}

.brand-lockup::after {
  right: var(--chain-pin-inset);
  transform: translateX(50%);
}

.brand-mark {
  width: min(13rem, 56%);
  height: auto;
  flex: 0 0 auto;
  object-fit: contain;
  filter: drop-shadow(0 4px 3px oklch(0 0 0 / 0.42));
}

.guild-note,
.section-note {
  margin: 0 0 0.7rem;
  color: var(--brass-bright);
  font-size: var(--text-sm);
  font-weight: 800;
  letter-spacing: 0.01em;
}

h1,
h2,
h3,
p {
  margin-top: 0;
}

h1 {
  max-width: 13ch;
  margin-bottom: 1rem;
  color: var(--tooth);
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.05;
  text-wrap: balance;
}

h2 {
  margin-bottom: 0.25rem;
  color: var(--tooth);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 600;
  letter-spacing: 0.005em;
  line-height: 1.2;
  text-wrap: balance;
}

h3 {
  margin-bottom: 0.45rem;
  color: var(--tooth);
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.005em;
  line-height: 1.25;
  text-wrap: balance;
}

.hero-copy p:not(.guild-note),
.empty-state p {
  max-width: 65ch;
  color: var(--muted);
  font-size: var(--text-base);
  line-height: 1.65;
  letter-spacing: 0.005em;
  text-wrap: pretty;
}

.login-panel {
  display: grid;
  gap: 1rem;
  align-items: start;
}

.login-panel p {
  color: var(--muted);
}

.button {
  display: inline-flex;
  min-height: 2.75rem;
  align-items: center;
  justify-content: center;
  border: 1px solid oklch(0.31 0.08 54);
  border-radius: 7px;
  cursor: pointer;
  font-size: var(--text-base);
  font-weight: 700;
  text-decoration: none;
  transition:
    transform 170ms cubic-bezier(0.25, 1, 0.5, 1),
    filter 170ms cubic-bezier(0.25, 1, 0.5, 1),
    box-shadow 170ms cubic-bezier(0.25, 1, 0.5, 1);
}

.discord-button,
.primary-action {
  background:
    radial-gradient(ellipse at 50% 0, oklch(0.96 0.15 88 / 0.72), transparent 1.2rem),
    linear-gradient(180deg, var(--brass-bright), var(--brass) 48%, var(--brass-dark));
  color: var(--vellum-ink);
  padding: 0 1.1rem;
  text-shadow: 0 1px 0 oklch(1 0 0 / 0.15);
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.38),
    inset 0 -4px 0 oklch(0.25 0.07 50 / 0.32),
    0 3px 0 oklch(0.1 0.02 30 / 0.68);
}

.button:hover {
  filter: brightness(1.06);
  transform: translateY(-1px);
}

.button:active {
  filter: brightness(0.95);
  transform: translateY(0);
  box-shadow:
    inset 0 2px 4px oklch(0 0 0 / 0.2),
    inset 0 -1px 0 oklch(1 0 0 / 0.1);
}

.button:focus-visible,
input:focus-visible {
  outline: 3px solid oklch(0.9 0.14 84 / 0.55);
  outline-offset: 2px;
}

.primary-action:disabled {
  cursor: wait;
  opacity: 0.7;
}

.delete-button {
  background:
    linear-gradient(180deg, oklch(0.25 0.05 25), oklch(0.15 0.03 25));
  color: oklch(0.7 0.1 25);
  border-color: oklch(0.3 0.08 25);
  padding: 0 0.75rem;
  font-size: var(--text-sm);
  min-height: 2rem;
}

.delete-button:hover {
  background:
    linear-gradient(180deg, oklch(0.3 0.06 25), oklch(0.2 0.04 25));
  color: oklch(0.8 0.12 25);
}

/* Logout: sits in the user-chip alongside the avatar and username.
   It should be visually quiet — the loud brass CTA is for primary
   actions only. Smaller, dimmer, secondary palette. */
.logout-button {
  background:
    linear-gradient(180deg, oklch(0.21 0.04 36), oklch(0.13 0.025 30));
  color: oklch(0.78 0.05 60);
  border-color: oklch(0.32 0.06 50);
  padding: 0 0.7rem;
  font-size: var(--text-sm);
  min-height: 2rem;
  letter-spacing: 0.04em;
}

.logout-button:hover {
  background:
    linear-gradient(180deg, oklch(0.27 0.05 36), oklch(0.18 0.03 30));
  color: oklch(0.86 0.06 65);
  border-color: oklch(0.42 0.08 50);
}

/* Notes affordances. The "+ Add note" link-style button should
   not compete with the song title. The "Edit note" sits next to
   the existing note text and is similarly quiet. */
.notes-add-button,
.notes-edit-button {
  background: oklch(0.9 0.045 82 / 0.3);
  color: var(--vellum-ink);
  border-color: oklch(0.24 0.055 44 / 0.2);
  padding: 0 0.45rem;
  min-height: 1.5rem;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
}

.notes-add-button:hover,
.notes-edit-button:hover {
  background: oklch(0.92 0.05 82 / 0.46);
  color: var(--vellum-text-strong);
  border-color: oklch(0.24 0.055 44 / 0.28);
}

.duplicate-warning {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
  margin-top: 0.75rem;
  border: 1px solid oklch(0.7 0.15 80);
  border-radius: 8px;
  background: linear-gradient(180deg, oklch(0.25 0.06 80), oklch(0.18 0.04 80));
  color: oklch(0.85 0.1 80);
  font-size: var(--text-sm);
}

.duplicate-warning strong {
  color: oklch(0.9 0.18 80);
}

.duplicate-warning em {
  font-style: normal;
  font-weight: 700;
  color: var(--vellum);
}

.duplicate-warning .avatar {
  width: 1.25rem;
  height: 1.25rem;
  vertical-align: middle;
}

.dismiss-warning {
  margin-left: auto;
  background: transparent;
  border: 1px solid oklch(0.5 0.1 80);
  color: oklch(0.7 0.1 80);
  padding: 0.25rem 0.5rem;
  font-size: var(--text-xs);
  min-height: auto;
}

.dismiss-warning:hover {
  background: oklch(0.3 0.08 80);
  color: oklch(0.9 0.15 80);
}

.stat-board {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}

/* The candle (RuntimeStat) is the first child of the stat-board
   and is meant to be the tall, full-width piece. Spanning both
   columns puts it on the top row and pushes the two compact
   stat tiles ("songs" / "your offerings") to a shared second
   row below it. On mobile the grid collapses to a single column
   (see the media query below) where the span is released. */
.stat-board > :first-child {
  grid-column: 1 / -1;
}

.stat-tile {
  position: relative;
  min-width: 0;
  border: 1px solid oklch(0.43 0.08 56 / 0.9);
  border-radius: 8px;
  background:
    radial-gradient(circle at top right, oklch(0.69 0.14 82 / 0.18), transparent 5.5rem),
    linear-gradient(180deg, oklch(0.19 0.045 36 / 0.96), oklch(0.085 0.014 28 / 0.97));
  padding: 0.9rem;
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.08),
    inset 0 -8px 14px oklch(0 0 0 / 0.18);
}

.stat-tile strong {
  display: block;
  max-width: 100%;
  color: var(--tooth);
  font-size: var(--text-xl);
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.stat-tile span {
  display: block;
  max-width: 100%;
  color: var(--dim);
  font-size: var(--text-sm);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.runtime-warning {
  border-color: oklch(0.6 0.2 25);
  animation: runtime-pulse 1.5s ease-in-out infinite;
}

.runtime-warning strong {
  color: oklch(0.8 0.2 25);
}

.runtime-warning-text {
  display: block;
  margin-top: 0.35rem;
  color: oklch(0.75 0.2 25) !important;
  font-weight: 700;
  font-size: var(--text-sm) !important;
}

@keyframes runtime-pulse {
  0%, 100% {
    box-shadow:
      inset 0 1px 0 oklch(1 0 0 / 0.08),
      inset 0 -8px 14px oklch(0 0 0 / 0.18),
      0 0 0 0 oklch(0.6 0.2 25 / 0);
  }
  50% {
    box-shadow:
      inset 0 1px 0 oklch(1 0 0 / 0.08),
      inset 0 -8px 14px oklch(0 0 0 / 0.18),
      0 0 20px 4px oklch(0.6 0.2 25 / 0.4);
  }
}

.queue-panel {
  position: relative;
  min-width: 0;
  padding: 1.35rem 1.35rem 1.35rem 2.8rem;
  border-radius: 5px 10px 10px 5px;
  background:
    radial-gradient(circle at 24% 0, oklch(0.78 0.14 82 / 0.1), transparent 18rem),
    radial-gradient(circle at 85% 88%, oklch(0 0 0 / 0.36), transparent 22rem),
    linear-gradient(90deg, oklch(0.055 0.018 24 / 0.94), var(--leather-dark) 9%, var(--leather) 56%, var(--leather-dark) 96%),
    var(--leather);
}

/* Spine: rounded leather book-binding on the left edge, raised cords underneath */
.queue-panel::before {
  position: absolute;
  top: 0.35rem;
  bottom: 0.35rem;
  left: 0;
  width: 2rem;
  z-index: 1;
  pointer-events: none;
  border-radius: 7px 0 0 7px;
  content: "";
  background:
    /* raised cord bands running across the spine */
    repeating-linear-gradient(
      180deg,
      oklch(0.3 0.065 44) 0,
      oklch(0.26 0.055 40) 1.35rem,
      oklch(0.11 0.028 30) 1.35rem,
      oklch(0.09 0.022 28) 1.45rem,
      oklch(0.42 0.09 49) 1.45rem,
      oklch(0.46 0.095 51) 1.57rem,
      oklch(0.38 0.08 46) 1.69rem,
      oklch(0.09 0.022 28) 1.69rem,
      oklch(0.13 0.03 32) 1.79rem,
      oklch(0.3 0.065 44) 1.89rem
    ),
    /* base leather: warm brown, candlelight from the left */
    linear-gradient(90deg, oklch(0.34 0.075 46), oklch(0.22 0.05 38) 65%, oklch(0.12 0.03 30));
  box-shadow:
    inset -6px 0 9px oklch(0 0 0 / 0.5),
    inset 2px 0 0 oklch(0.5 0.1 50 / 0.22),
    6px 0 16px oklch(0 0 0 / 0.4);
}

/* Clasps: brass bosses riveted onto the spine */
.ledger-clasp {
  position: absolute;
  left: 0.5rem;
  z-index: 2;
  width: 1rem;
  height: 1rem;
  pointer-events: none;
  border: 1px solid oklch(0.26 0.08 48);
  border-radius: 50%;
  background:
    radial-gradient(circle at 36% 30%, var(--brass-bright), var(--brass) 55%, var(--brass-dark));
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.45),
    inset 0 -2px 3px oklch(0 0 0 / 0.35),
    0 2px 4px oklch(0 0 0 / 0.55);
}

.ledger-clasp::after {
  position: absolute;
  inset: 0.28rem;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, oklch(0.5 0.12 78), var(--brass-dark));
  box-shadow: inset 0 1px 1px oklch(1 0 0 / 0.25);
  content: "";
}

.ledger-clasp.top {
  top: 1.8rem;
}

.ledger-clasp.bottom {
  bottom: 1.8rem;
}



.queue-main {
  position: relative;
  isolation: isolate;
}

.toolbar {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.user-chip,
.song-meta {
  display: flex;
  align-items: center;
}

.user-chip {
  gap: 0.55rem;
  border: 1px solid oklch(0.44 0.07 55);
  border-radius: 999px;
  background: linear-gradient(180deg, oklch(0.18 0.035 38), oklch(0.09 0.012 28));
  color: var(--muted);
  font-size: var(--text-base);
  font-weight: 600;
  padding: 0.3rem 0.7rem 0.3rem 0.3rem;
  white-space: nowrap;
  box-shadow: inset 0 1px 0 oklch(1 0 0 / 0.08);
}

.offering-board {
  position: relative;
  z-index: 2;
  margin: 1.15rem 0 0.95rem;
  border: 1px solid oklch(0.42 0.07 52);
  border-radius: 3px 10px 3px 12px;
  background:
    radial-gradient(ellipse at 13% 0, oklch(1 0.05 90 / 0.38), transparent 9rem),
    radial-gradient(ellipse at 91% 90%, oklch(0.5 0.12 42 / 0.14), transparent 7rem),
    linear-gradient(180deg, var(--vellum), var(--vellum-deep));
  color: var(--vellum-ink);
  padding: 1rem;
  box-shadow:
    0 5px 0 oklch(0.07 0.015 24 / 0.48),
    inset 0 0 0 2px oklch(0.3 0.06 52 / 0.13),
    inset 0 -14px 24px oklch(0.35 0.08 42 / 0.13);
}

.offering-board::before {
  position: absolute;
  inset: -0.43rem 1.2rem auto;
  height: 0.42rem;
  border: 1px solid oklch(0.1 0.01 40 / 0.65);
  border-radius: 999px;
  background: linear-gradient(180deg, oklch(0.64 0.02 65), var(--iron), var(--iron-dark));
  content: "";
}

.wax-seal {
  position: absolute;
  right: 1rem;
  bottom: -0.82rem;
  width: 2.2rem;
  height: 2.2rem;
  cursor: pointer;
  border: 1px solid oklch(0.22 0.11 22 / 0.72);
  border-radius: 54% 46% 58% 42% / 46% 57% 43% 54%;
  background:
    /* Wet wax glints and tiny surface dimples. */
    radial-gradient(ellipse at 30% 22%, oklch(0.78 0.19 24 / 0.76) 0 0.16rem, transparent 0.48rem),
    radial-gradient(circle at 69% 30%, oklch(0.66 0.18 18 / 0.36) 0 0.07rem, transparent 0.26rem),
    radial-gradient(circle at 23% 72%, oklch(0.18 0.08 21 / 0.48) 0 0.12rem, transparent 0.34rem),
    radial-gradient(circle at 78% 66%, oklch(0.17 0.07 20 / 0.42) 0 0.09rem, transparent 0.32rem),
    /* Uneven raised rim: brighter candlelit top-left, darker pooled bottom-right. */
    conic-gradient(from 222deg at 49% 49%,
      oklch(0.24 0.11 21) 0deg,
      var(--wax) 44deg,
      oklch(0.6 0.19 21) 82deg,
      var(--tongue) 108deg,
      var(--mimic) 146deg,
      oklch(0.34 0.14 22) 214deg,
      oklch(0.17 0.08 20) 286deg,
      oklch(0.42 0.16 25) 334deg,
      oklch(0.24 0.11 21) 360deg),
    /* Oxblood body under the pooled rim. */
    radial-gradient(ellipse at 47% 43%, oklch(0.55 0.19 23), var(--wax) 44%, oklch(0.28 0.12 22) 73%, oklch(0.16 0.07 20));
  box-shadow:
    inset 0.16rem 0.18rem 0.22rem oklch(0.86 0.18 28 / 0.18),
    inset -0.22rem -0.25rem 0.34rem oklch(0.07 0.035 20 / 0.78),
    inset 0 0 0 0.12rem oklch(0.28 0.13 23 / 0.72),
    inset 0 0.08rem 0.06rem oklch(1 0 0 / 0.1),
    0 0.08rem 0 oklch(0.98 0.035 82 / 0.18),
    0 0.28rem 0.34rem oklch(0 0 0 / 0.48),
    0 0.64rem 0.82rem oklch(0 0 0 / 0.24);
  transform: rotate(-7deg);
}

.wax-seal::after {
  position: absolute;
  inset: 0.43rem;
  border: 0.12rem solid oklch(0.14 0.06 23 / 0.68);
  border-radius: 49% 51% 46% 54% / 55% 46% 54% 45%;
  background:
    /* Simple tavern-rune stamp cut into the wax. */
    linear-gradient(90deg, transparent 0 calc(50% - 0.035rem), oklch(0.11 0.045 22 / 0.43) calc(50% - 0.035rem) calc(50% + 0.035rem), transparent calc(50% + 0.035rem)),
    linear-gradient(38deg, transparent 0 42%, oklch(0.12 0.05 22 / 0.34) 43% 48%, transparent 49%),
    linear-gradient(142deg, transparent 0 43%, oklch(0.12 0.05 22 / 0.32) 44% 49%, transparent 50%),
    radial-gradient(ellipse at 50% 57%, oklch(0.12 0.05 22 / 0.34) 0 0.17rem, transparent 0.19rem),
    radial-gradient(circle at 42% 34%, oklch(0.78 0.16 24 / 0.08), transparent 0.34rem),
    radial-gradient(circle at 50% 50%, oklch(0.06 0.025 20 / 0.24), transparent 70%);
  box-shadow:
    inset 0.06rem 0.08rem 0.1rem oklch(0.04 0.02 20 / 0.58),
    inset -0.05rem -0.06rem 0.08rem oklch(0.84 0.16 26 / 0.12),
    0 0.04rem 0 oklch(0.75 0.16 25 / 0.12),
    0 -0.04rem 0.05rem oklch(0.05 0.02 20 / 0.28);
  content: "";
}

.board-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.8rem;
}

.board-heading span {
  color: var(--vellum-text);
  font-size: var(--text-base);
  font-weight: 800;
}

.board-heading strong {
  color: var(--vellum-text-strong);
  font-size: var(--text-base);
  font-weight: 600;
}

.avatar {
  display: inline-grid;
  width: 1.85rem;
  height: 1.85rem;
  flex: 0 0 auto;
  place-items: center;
  overflow: hidden;
  border-radius: 999px;
  background: var(--mimic);
  color: white;
  font-size: var(--text-xs);
  font-weight: 800;
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.proposal-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 10rem auto;
  gap: 0.75rem;
  align-items: end;
  margin-bottom: 0;
}

.proposal-form > form {
  display: contents;
}

.proposal-form > .form-status,
.proposal-form > .notice,
.proposal-form > .confirmation-panel {
  grid-column: 1 / -1;
}

.form-status {
  margin: 0;
  color: var(--vellum-text-strong);
  font-size: var(--text-base);
  font-weight: 700;
}

.confirmation-panel {
  display: grid;
  grid-template-columns: minmax(7.5rem, 10.5rem) minmax(0, 1fr) auto;
  gap: 0.95rem;
  align-items: center;
  min-width: 0;
  max-width: 100%;
  border: 1px solid oklch(0.42 0.075 52 / 0.9);
  border-radius: 8px;
  background:
    radial-gradient(ellipse at top left, oklch(0.94 0.08 84 / 0.24), transparent 12rem),
    linear-gradient(180deg, oklch(0.73 0.07 80 / 0.98), oklch(0.55 0.075 68 / 0.98));
  color: var(--vellum-ink);
  padding: 0.85rem;
  box-shadow:
    0 4px 0 oklch(0.07 0.015 24 / 0.42),
    inset 0 1px 0 oklch(1 0 0 / 0.26);
}

.confirmation-panel.duplicate-conflict {
  grid-template-columns: minmax(0, 1fr) auto;
}

.confirmation-thumb {
  display: grid;
  width: 100%;
  max-width: 10.5rem;
  aspect-ratio: 16 / 9;
  place-items: center;
  overflow: hidden;
  border: 2px solid oklch(0.35 0.07 48);
  border-radius: 5px;
  background: oklch(0.075 0.012 30);
  color: var(--brass-bright);
  font-size: var(--text-sm);
  font-weight: 800;
}

.confirmation-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.confirmation-thumb span {
  display: grid;
  width: 100%;
  height: 100%;
  place-items: center;
}

.confirmation-body {
  display: grid;
  min-width: 0;
  gap: 0.35rem;
}

.confirmation-kicker {
  color: var(--vellum-text);
  font-size: var(--text-sm);
  font-weight: 800;
}

.confirmation-body > strong {
  min-width: 0;
  color: var(--vellum-ink);
  font-size: var(--text-lg);
  font-weight: 850;
  line-height: 1.15;
  overflow-wrap: anywhere;
  text-wrap: pretty;
}

.confirmation-runtime,
.confirmation-note {
  color: var(--vellum-text-strong);
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 1.35;
}

.confirmation-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: flex-end;
}

.similar-status,
.similar-list {
  display: grid;
  gap: 0.25rem;
  margin-top: 0.35rem;
  max-width: 100%;
}

.similar-status {
  border: 1px solid oklch(0.42 0.07 54 / 0.42);
  border-radius: 6px;
  background: oklch(0.68 0.06 78 / 0.42);
  padding: 0.55rem 0.65rem;
}

.similar-status strong,
.similar-list > strong {
  color: var(--vellum-text-strong);
  font-size: var(--text-sm);
  font-weight: 800;
}

.similar-status span {
  color: var(--vellum-text);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.35;
}

.similar-list ul {
  display: grid;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.similar-list li {
  display: flex;
  min-width: 0;
  flex-wrap: wrap;
  gap: 0.25rem 0.4rem;
  align-items: baseline;
  border: 1px solid oklch(0.42 0.07 54 / 0.38);
  border-radius: 6px;
  background: oklch(0.62 0.065 74 / 0.38);
  color: var(--vellum-text);
  padding: 0.5rem 0.6rem;
  font-size: var(--text-sm);
  line-height: 1.3;
}

.similar-list li em {
  min-width: 0;
  color: var(--vellum-ink);
  font-style: normal;
  font-weight: 800;
  overflow-wrap: anywhere;
}

.similar-list li strong {
  color: var(--vellum-text-strong);
}

.similarity-score {
  margin-left: auto;
  border-radius: 999px;
  background: oklch(0.45 0.14 24 / 0.18);
  color: var(--vellum-text-accent);
  padding: 0.1rem 0.45rem;
  font-size: var(--text-xs);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

label {
  display: grid;
  gap: 0.4rem;
  color: currentColor;
  font-size: var(--text-base);
  font-weight: 700;
}

input {
  width: 100%;
  min-height: 2.75rem;
  border: 1px solid oklch(0.42 0.075 46);
  border-radius: 5px;
  background:
    radial-gradient(circle at top left, oklch(1 0.02 86 / 0.34), transparent 8rem),
    oklch(0.72 0.065 78);
  color: var(--vellum-ink);
  outline: none;
  padding: 0 0.85rem;
  box-shadow:
    inset 0 2px 4px oklch(0 0 0 / 0.18),
    inset 0 1px 0 oklch(1 0 0 / 0.28);
}

input::placeholder {
  color: var(--placeholder);
}

input:focus {
  border-color: var(--brass);
}

.form-error {
  margin: 0.5rem 0 1rem;
  color: var(--danger);
  font-size: var(--text-sm);
  font-weight: 600;
}

.filter-bar {
  position: relative;
  z-index: 3;
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.filter-input {
  flex: 1;
  padding: 0.6rem 0.85rem;
  border: 1px solid oklch(0.4 0.08 55);
  border-radius: 6px;
  background: oklch(0.15 0.03 30);
  color: var(--vellum);
  font-size: var(--text-base);
  font-family: inherit;
}

.filter-input::placeholder {
  color: oklch(0.5 0.05 50);
}

.filter-input:focus {
  outline: 2px solid oklch(0.8 0.15 84);
  outline-offset: 1px;
}

.filter-select {
  padding: 0.6rem 0.85rem;
  border: 1px solid oklch(0.4 0.08 55);
  border-radius: 6px;
  background: oklch(0.15 0.03 30);
  color: var(--vellum);
  font-size: var(--text-base);
  font-family: inherit;
  min-width: 140px;
}

.filter-select:focus {
  outline: 2px solid oklch(0.8 0.15 84);
  outline-offset: 1px;
}

.filter-select option {
  background: oklch(0.15 0.03 30);
  color: var(--vellum);
}

.song-list {
  position: relative;
  z-index: 3;
  display: grid;
  gap: 0.75rem;
  margin: 1.1rem 0 0;
  padding: 0;
  list-style: none;
}

.song-row {
  position: relative;
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr) auto;
  gap: 1rem;
  align-items: center;
  border: 1px solid oklch(0.42 0.075 52 / 0.9);
  border-radius: 3px 9px 4px 11px;
  background:
    radial-gradient(ellipse at top left, oklch(0.92 0.07 82 / 0.2), transparent 10rem),
    linear-gradient(180deg, oklch(0.74 0.07 80 / 0.98), oklch(0.55 0.075 68 / 0.98));
  color: var(--vellum-ink);
  padding: 0.85rem;
  box-shadow:
    0 5px 0 oklch(0.07 0.015 24 / 0.45),
    inset 0 1px 0 oklch(1 0 0 / 0.28),
    inset 0 -12px 22px oklch(0.28 0.08 42 / 0.12);
}

.song-row::before {
  position: absolute;
  inset: 0.32rem;
  border: 1px solid oklch(0.25 0.06 44 / 0.12);
  border-radius: 3px 7px 3px 8px;
  content: "";
  pointer-events: none;
}

.notice-pin {
  position: absolute;
  top: 0.45rem;
  z-index: 1;
  width: 0.72rem;
  height: 0.72rem;
  border: 1px solid var(--brass-dark);
  border-radius: 999px;
  background:
    radial-gradient(circle at 35% 30%, oklch(0.94 0.13 88), transparent 0.16rem),
    radial-gradient(circle, var(--brass), var(--brass-dark));
  box-shadow: 0 2px 2px oklch(0 0 0 / 0.38);
}

.notice-pin.left {
  left: 0.55rem;
}

.notice-pin.right {
  right: 0.55rem;
}

.song-row.mine {
  background:
    radial-gradient(ellipse at top left, oklch(0.9 0.12 82 / 0.3), transparent 12rem),
    linear-gradient(180deg, oklch(0.78 0.08 82 / 0.98), oklch(0.6 0.09 70 / 0.98));
}

.song-thumb {
  display: grid;
  aspect-ratio: 16 / 9;
  place-items: center;
  overflow: hidden;
  border: 2px solid oklch(0.35 0.07 48);
  border-radius: 4px;
  background: oklch(0.075 0.012 30);
  color: var(--brass-bright);
  font-weight: 800;
  text-decoration: none;
  box-shadow:
    inset 0 0 0 1px oklch(1 0 0 / 0.08),
    0 2px 3px oklch(0 0 0 / 0.22);
  transition: border-color 170ms cubic-bezier(0.25, 1, 0.5, 1);
}

.song-thumb:hover {
  border-color: var(--brass);
}

.song-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.song-main {
  min-width: 0;
}

.song-heading a {
  min-width: 0;
  overflow: hidden;
  color: var(--vellum-ink);
  font-size: var(--text-lg);
  font-weight: 800;
  text-decoration: none;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color 170ms cubic-bezier(0.25, 1, 0.5, 1);
}

.song-heading a:hover {
  color: var(--vellum-text-accent);
}

.runtime-single {
  color: var(--vellum-text);
  font-size: var(--text-base);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.song-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 0.45rem;
  min-width: 0;
}

.song-action-buttons {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.4rem;
}

.song-meta {
  gap: 0.35rem;
  margin-top: 0.5rem;
  color: var(--vellum-text-muted);
  font-size: var(--text-base);
}

.song-meta .avatar {
  width: 1.35rem;
  height: 1.35rem;
  font-size: var(--text-xs);
}

.song-meta strong {
  color: var(--vellum-text-strong);
}

.song-meta em {
  border-radius: 999px;
  background: oklch(0.45 0.16 24 / 0.18);
  color: var(--vellum-text-accent);
  font-style: normal;
  font-weight: 700;
  padding: 0.1rem 0.45rem;
}



.empty-state,
.notice,
.loading-stack {
  display: grid;
  min-height: 0;
  align-content: center;
  justify-items: start;
  border: 1px solid oklch(0.42 0.07 52);
  border-radius: 3px 11px 3px 12px;
  background:
    radial-gradient(ellipse at top left, oklch(0.96 0.08 84 / 0.26), transparent 14rem),
    radial-gradient(ellipse at 90% 100%, oklch(0.42 0.1 44 / 0.16), transparent 12rem),
    linear-gradient(180deg, var(--vellum), var(--vellum-deep));
  color: var(--vellum-ink);
  padding: 2rem;
  box-shadow:
    0 5px 0 oklch(0.07 0.015 24 / 0.45),
    inset 0 1px 0 oklch(1 0 0 / 0.28),
    inset 0 -16px 24px oklch(0.28 0.08 42 / 0.13);
}

.empty-state .section-note {
  color: var(--vellum-text);
}

.empty-state h3 {
  color: var(--vellum-ink);
}

.empty-state p {
  color: var(--vellum-text-strong);
}

.notice {
  gap: 0.8rem;
}

.notice.error {
  color: var(--danger);
}

.notice span {
  color: currentColor;
}

.notice button {
  background:
    radial-gradient(ellipse at 50% 0, oklch(0.92 0.13 84 / 0.34), transparent 1.2rem),
    linear-gradient(180deg, var(--brass), var(--brass-dark));
  color: var(--vellum-ink);
  text-shadow: 0 1px 0 oklch(1 0 0 / 0.15);
  padding: 0 1rem;
}

.skeleton {
  width: min(34rem, 100%);
  height: 4rem;
  border-radius: 12px;
  background: linear-gradient(
    90deg,
    oklch(0.18 0.03 36),
    oklch(0.28 0.055 44),
    oklch(0.18 0.03 36)
  );
  animation: shimmer 1.2s ease-in-out infinite;
}

.skeleton.wide {
  width: min(42rem, 100%);
}

.skeleton.short {
  width: min(24rem, 72%);
}

@keyframes shimmer {
  0%,
  100% {
    opacity: 0.48;
  }
  50% {
    opacity: 1;
  }
}

@media (max-width: 900px) {
  .app-shell {
    grid-template-columns: 1fr;
  }

  .hero-panel {
    position: relative;
    top: auto;
    min-height: auto;
    gap: 2rem;
  }

  .brand-lockup {
    width: 16rem;
    margin: 4.7rem auto 1.35rem;
  }

  .brand-lockup::before,
  .brand-lockup::after {
    margin: 0 .65rem;
  }

  .chain {
    --chain-scale: 0.94;
    top: -1.05rem;
  }

  .chain.left {
    left: calc(50% - 8rem + 0.6rem);
  }

  .chain.right {
    right: calc(50% - 8rem + 0.6rem);
  }

  h1 {
    max-width: 12ch;
  }

  .proposal-form,
  .song-row {
    grid-template-columns: 1fr;
  }

  .confirmation-panel,
  .confirmation-panel.duplicate-conflict {
    grid-template-columns: 1fr;
    align-items: stretch;
  }

  .confirmation-thumb {
    width: min(18rem, 100%);
    max-width: 100%;
  }

  .confirmation-actions {
    justify-content: flex-start;
  }

  .song-thumb {
    width: min(16rem, 100%);
  }
}

@media (max-width: 560px) {
  .app-shell {
    width: min(100% - 1rem, 1600px);
    padding: 0.5rem 0;
  }

  .hero-panel,
  .queue-panel {
    padding: 1rem;
  }

  .queue-panel {
    padding-left: 2.2rem;
  }

  .confirmation-panel {
    gap: 0.8rem;
    padding: 0.75rem;
  }

  .confirmation-actions {
    display: grid;
    grid-template-columns: 1fr;
  }

  .confirmation-actions .button {
    width: 100%;
  }

  .queue-panel::before {
    width: 1.5rem;
  }

  .ledger-clasp {
    left: 0.3rem;
    width: 0.85rem;
    height: 0.85rem;
  }

  .brand-lockup {
    width: 13rem;
    padding: 0.85rem 0.4rem 0.95rem;
  }

  .chain {
    --chain-scale: 0.84;
    top: -0.95rem;
  }

  .brand-mark {
    width: min(10rem, 65%);
  }

  h1 {
    font-size: var(--text-2xl);
  }

  .toolbar,
  .song-heading,
  .board-heading {
    align-items: flex-start;
    flex-direction: column;
  }

  .stat-board {
    grid-template-columns: 1fr;
  }

  /* On mobile the grid is a single column, so the candle's
     explicit `1 / -1` span would create a phantom empty column.
     `auto` lets it just take the single column. */
  .stat-board > :first-child {
    grid-column: auto;
  }

  .stat-board .wax-candle-meter {
    align-items: center;
    gap: 0.65rem;
  }

  .stat-board .wax-candle-meter .meter-svg--tankard {
    width: min(4.9rem, 24vw);
    max-width: 32%;
    flex: 0 0 auto;
  }

  .stat-board .wax-candle-meter .meter-text {
    min-width: 0;
  }

  .stat-board .wax-candle-meter .meter-text .meter-now {
    font-size: var(--text-lg);
    overflow-wrap: anywhere;
  }

  .stat-board .wax-candle-meter .meter-text .meter-sub,
  .stat-board .wax-candle-meter .meter-text .meter-warning {
    font-size: var(--text-xs);
    line-height: 1.2;
  }

  .chain.left {
    left: calc(50% - 6.5rem + 0.6rem);
  }

  .chain.right {
    right: calc(50% - 6.5rem + 0.6rem);
  }
}

/* ─── Mimic chest chomp animation ─────────────────────────────────── */

.mimic-stage {
  position: relative;
  display: flow-root;
  z-index: 1;
  isolation: isolate;
  perspective: 1000px;
  transform-style: preserve-3d;
}

.mimic-stage::before {
  position: absolute;
  inset: -0.7rem -1rem;
  z-index: 1;
  pointer-events: none;
  border-radius: 12px;
  background:
    radial-gradient(ellipse at 50% 50%,
      oklch(0.02 0.012 24 / 0.88) 0 12%,
      oklch(0.03 0.02 24 / 0.62) 26%,
      transparent 60%);
  content: "";
  opacity: 0;
  transform: scaleX(0.7) scaleY(0.32);
  filter: blur(10px);
  will-change: opacity, transform, filter;
}

/* Container: overlays the offering board only during the devour. */
.mimic {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1;
  width: min(42rem, calc(100% + 5rem));
  height: calc(100% + 7rem);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.86);
  transform-style: preserve-3d;
  will-change: transform, opacity;
}

.mimic-stage.chomping .mimic {
  opacity: 1;
}

/* ── Chest base (bottom jaw) ─────────────────────────────────────── */

.mimic-body {
  position: absolute;
  top: calc(50% + 0.15rem);
  left: 0;
  width: 100%;
  height: calc(50% + 3.2rem);
  /* Dark wood grain */
  background:
    repeating-linear-gradient(2deg,
      transparent 0, transparent 4px,
      oklch(0.15 0.04 40 / 0.4) 4px, oklch(0.15 0.04 40 / 0.4) 5px,
      transparent 5px, transparent 11px),
    repeating-linear-gradient(-1deg,
      transparent 0, transparent 8px,
      oklch(0.2 0.05 44 / 0.3) 8px, oklch(0.2 0.05 44 / 0.3) 9px,
      transparent 9px, transparent 18px),
    linear-gradient(180deg, var(--oak) 0%, var(--oak-dark) 100%);
  border: 3px solid oklch(0.1 0.02 35);
  border-top: none;
  border-radius: 0 0 8px 8px;
  box-shadow:
    inset 0 8px 16px oklch(1 0 0 / 0.04),
    inset 0 -12px 24px oklch(0 0 0 / 0.4),
    0 12px 32px oklch(0 0 0 / 0.6);
  overflow: visible;
}

/* Iron band: bottom */
.mimic-body::before {
  content: "";
  position: absolute;
  bottom: 8px;
  left: -3px;
  right: -3px;
  height: 7px;
  background: linear-gradient(180deg,
    oklch(0.12 0.008 45),
    oklch(0.35 0.018 52) 30%,
    oklch(0.25 0.012 48) 65%,
    oklch(0.1 0.006 42));
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.1),
    0 1px 3px oklch(0 0 0 / 0.4);
}

/* Iron band: top of base (mouth edge) */
.mimic-body::after {
  content: "";
  position: absolute;
  top: -1px;
  left: -3px;
  right: -3px;
  height: 7px;
  background: linear-gradient(180deg,
    oklch(0.12 0.008 45),
    oklch(0.35 0.018 52) 30%,
    oklch(0.25 0.012 48) 65%,
    oklch(0.1 0.006 42));
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.1),
    0 1px 3px oklch(0 0 0 / 0.4);
}

/* ── Eyes: menacing, glowing ──────────────────────────────────────── */

.mimic-eyes {
  position: absolute;
  top: 24%;
  left: 50%;
  width: 140px;
  margin-left: -70px;
  display: flex;
  justify-content: space-between;
  z-index: 5;
}

.mimic-eye {
  position: relative;
  border-radius: 50% 50% 45% 55% / 55% 55% 45% 45%;
  background:
    radial-gradient(circle at 45% 40%,
      oklch(0.98 0.2 90),
      oklch(0.9 0.22 86) 20%,
      oklch(0.6 0.2 80) 50%,
      oklch(0.35 0.15 75));
  box-shadow:
    0 0 14px oklch(0.85 0.22 88 / 0.7),
    0 0 28px oklch(0.85 0.22 88 / 0.35),
    inset 0 2px 4px oklch(0 0 0 / 0.4);
  overflow: hidden;
}

.mimic-eye.main {
  width: 32px;
  height: 36px;
}

.mimic-eye.side {
  width: 18px;
  height: 20px;
  margin-top: 12px;
}

/* Vertical slit pupil */
.mimic-eye::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 28%;
  height: 68%;
  margin: -34% 0 0 -14%;
  border-radius: 50%;
  background: oklch(0.02 0.01 20);
  box-shadow: 0 0 4px oklch(0 0 0 / 0.9);
}

/* ── Bottom jaw teeth ────────────────────────────────────────────── */

.mimic-jaw-bottom {
  position: absolute;
  top: calc(50% - 1.25rem);
  left: 0;
  width: 100%;
  height: 1.5rem;
  transform-origin: center top;
  transform: rotateX(0deg);
  will-change: transform;
  z-index: 4;
}

.mimic-jaw-bottom .jaw-shape {
  width: 100%;
  height: 100%;
  background: linear-gradient(180deg, var(--oak-dark), var(--oak) 50%);
  border-radius: 2px;
}

.mimic-jaw-bottom .teeth {
  position: absolute;
  top: -16px;
  left: 6%;
  right: 6%;
  height: 20px;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.mimic-jaw-bottom .tooth {
  width: 11px;
  height: 18px;
  background: linear-gradient(0deg, var(--tooth), oklch(0.92 0.05 90));
  clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
  filter: drop-shadow(0 -2px 2px oklch(0 0 0 / 0.4));
}

/* Fangs: longer at the sides */
.mimic-jaw-bottom .tooth:nth-child(1),
.mimic-jaw-bottom .tooth:nth-child(7) {
  height: 26px;
  width: 13px;
}

/* ── Lid (top jaw): hinged at back, opens upward ──────────────────── */

.mimic-jaw-top {
  position: absolute;
  bottom: calc(50% + 0.15rem);
  left: -0.25rem;
  width: calc(100% + 0.5rem);
  height: clamp(4.75rem, 42%, 8.25rem);
  transform-origin: center bottom;
  transform: rotateX(0deg);
  will-change: transform;
  z-index: 6;
}

.mimic-jaw-top .jaw-shape {
  width: 100%;
  height: 100%;
  /* Slightly lighter oak for the lid */
  background:
    repeating-linear-gradient(3deg,
      transparent 0, transparent 5px,
      oklch(0.18 0.045 42 / 0.35) 5px, oklch(0.18 0.045 42 / 0.35) 6px,
      transparent 6px, transparent 13px),
    linear-gradient(180deg, var(--oak-light), var(--oak));
  border: 3px solid oklch(0.1 0.02 35);
  border-bottom: none;
  border-radius: 10px 10px 0 0;
  box-shadow:
    inset 0 8px 14px oklch(1 0 0 / 0.06),
    inset 0 -4px 8px oklch(0 0 0 / 0.2);
  position: relative;
}

/* Iron band across lid */
.mimic-jaw-top .jaw-shape::before {
  content: "";
  position: absolute;
  top: 14px;
  left: -3px;
  right: -3px;
  height: 7px;
  background: linear-gradient(180deg,
    oklch(0.12 0.008 45),
    oklch(0.35 0.018 52) 30%,
    oklch(0.25 0.012 48) 65%,
    oklch(0.1 0.006 42));
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.1),
    0 1px 3px oklch(0 0 0 / 0.4);
}

/* Lid top edge highlight */
.mimic-jaw-top .jaw-shape::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: linear-gradient(90deg,
    oklch(0.1 0.02 35),
    oklch(0.28 0.06 48 / 0.5) 30%,
    oklch(0.1 0.02 35));
}

/* Teeth along bottom edge of lid */
.mimic-jaw-top .teeth {
  position: absolute;
  bottom: -5px;
  left: 6%;
  right: 6%;
  height: 20px;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
}

.mimic-jaw-top .tooth {
  width: 11px;
  height: 18px;
  background: linear-gradient(180deg, var(--tooth), oklch(0.92 0.05 90));
  clip-path: polygon(0% 0%, 100% 0%, 80% 100%, 20% 100%);
  filter: drop-shadow(0 2px 2px oklch(0 0 0 / 0.4));
}

.mimic-jaw-top .tooth:nth-child(1),
.mimic-jaw-top .tooth:nth-child(7) {
  height: 26px;
  width: 13px;
}

/* ── Tongue: forked, lolls out when mouth opens ───────────────────── */

.mimic-tongue {
  position: absolute;
  top: calc(50% - 1.1rem);
  left: 50%;
  width: 2.35rem;
  height: 2.35rem;
  margin-left: -1.175rem;
  border-radius: 40% 40% 50% 50% / 30% 30% 70% 70%;
  background:
    radial-gradient(ellipse at 50% 30%,
      oklch(0.7 0.22 20),
      var(--tongue) 50%,
      oklch(0.38 0.14 18));
  box-shadow:
    inset 0 5px 8px oklch(1 0 0 / 0.15),
    inset 0 -4px 8px oklch(0 0 0 / 0.35),
    0 4px 8px oklch(0 0 0 / 0.35);
  z-index: 3;
}

/* Forked tongue tip */
.mimic-tongue::after {
  content: "";
  position: absolute;
  bottom: -7px;
  left: 50%;
  width: 18px;
  height: 11px;
  margin-left: -9px;
  background: var(--tongue);
  clip-path: polygon(0% 0%, 35% 100%, 50% 60%, 65% 100%, 100% 0%);
}

/* ── Lock on front of chest ──────────────────────────────────────── */

.mimic-lock {
  position: absolute;
  top: calc(50% + 2.3rem);
  left: 50%;
  width: 26px;
  height: 30px;
  margin-left: -13px;
  z-index: 7;
}

/* Lock hasp (U-shape at top) */
.mimic-lock::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 18px;
  height: 16px;
  margin-left: -9px;
  border: 3px solid var(--brass);
  border-bottom: none;
  border-radius: 9px 9px 0 0;
  box-shadow: 0 -1px 5px oklch(0.68 0.13 78 / 0.4);
}

/* Lock body */
.mimic-lock::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 22px;
  height: 18px;
  margin-left: -11px;
  border-radius: 3px;
  background:
    radial-gradient(circle at 40% 35%, var(--brass-bright), var(--brass) 55%, var(--brass-dark));
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.3),
    inset 0 -2px 3px oklch(0 0 0 / 0.35),
    0 2px 5px oklch(0 0 0 / 0.4);
}

/* ── Hinges at back of lid ───────────────────────────────────────── */

.mimic-hinge {
  position: absolute;
  bottom: calc(50% - 0.05rem);
  z-index: 1;
}

.mimic-hinge.left {
  left: 18px;
}

.mimic-hinge.right {
  right: 18px;
}

.mimic-hinge::before {
  content: "";
  display: block;
  width: 16px;
  height: 20px;
  border-radius: 3px;
  background:
    linear-gradient(90deg,
      oklch(0.1 0.006 42),
      oklch(0.3 0.015 50) 40%,
      oklch(0.2 0.01 46));
  box-shadow:
    inset 0 1px 0 oklch(1 0 0 / 0.1),
    0 2px 4px oklch(0 0 0 / 0.5);
}

/* ── Animation keyframes ─────────────────────────────────────────── */

.mimic-stage.chomping .mimic {
  animation: mimic-devour 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.mimic-stage.chomping {
  animation: mimic-stage-layer 1.8s step-end forwards;
}

.mimic-stage.chomping::before {
  animation: mimic-mouth-shadow 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.mimic-stage.chomping .mimic-body {
  animation: mimic-body-devour 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.mimic-stage.chomping .mimic-jaw-top {
  animation: jaw-devour-top 1.8s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.mimic-stage.chomping .mimic-jaw-bottom {
  animation: jaw-devour-bottom 1.8s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.mimic-stage.chomping .mimic-tongue {
  animation: tongue-devour 1.8s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.mimic-stage.chomping .mimic-eye {
  animation: mimic-eye-flare 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.mimic-stage.chomping .mimic-jaw-top .tooth,
.mimic-stage.chomping .mimic-jaw-bottom .tooth {
  animation: tooth-bite 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.mimic-stage.chomping .offering-board {
  transform-origin: 50% 54%;
  will-change: transform, opacity, filter, clip-path;
  animation: board-devoured 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes mimic-stage-layer {
  0%, 13% {
    z-index: 1;
  }
  14%, 74% {
    z-index: 5;
  }
  75%, 100% {
    z-index: 1;
  }
}

@keyframes mimic-devour {
  0% {
    z-index: 1;
    opacity: 0;
    transform: translate(-50%, -50%) translateY(4.5rem) rotateX(-10deg) scale(0.76);
  }
  10% {
    opacity: 0.42;
  }
  14% {
    z-index: 4;
    opacity: 0.72;
  }
  20% {
    opacity: 1;
  }
  24% {
    transform: translate(-50%, -50%) translateY(1.4rem) rotateX(-4deg) scale(0.9, 0.82);
  }
  38% {
    z-index: 4;
    opacity: 1;
    transform: translate(-50%, -50%) rotateX(0deg) scale(1.03, 1.09);
  }
  47% {
    z-index: 4;
    transform: translate(-50%, -50%) translateY(-0.3rem) rotateX(5deg) scale(1.08, 0.94);
  }
  56% {
    transform: translate(-50%, -50%) translateY(0.15rem) rotateX(0deg) scale(0.98, 1.03);
  }
  72% {
    z-index: 4;
    opacity: 1;
    transform: translate(-50%, -50%) translateY(0.55rem) scale(0.92, 0.98);
  }
  100% {
    z-index: 1;
    opacity: 0;
    transform: translate(-50%, -50%) translateY(2.4rem) rotateX(8deg) scale(0.72, 0.82);
  }
}

@keyframes mimic-mouth-shadow {
  0%, 18% {
    z-index: 3;
    opacity: 0;
    transform: scaleX(0.62) scaleY(0.2);
    filter: blur(12px);
  }
  34% {
    z-index: 3;
    opacity: 0.9;
    transform: scaleX(1.12) scaleY(1.06);
    filter: blur(7px);
  }
  48% {
    z-index: 3;
    opacity: 1;
    transform: scaleX(0.7) scaleY(0.18);
    filter: blur(4px);
  }
  70% {
    z-index: 3;
    opacity: 0.55;
    transform: scaleX(0.28) scaleY(0.12);
    filter: blur(9px);
  }
  100% {
    z-index: 1;
    opacity: 0;
    transform: scaleX(0.18) scaleY(0.08);
    filter: blur(12px);
  }
}

@keyframes mimic-body-devour {
  0%, 20% {
    transform: translateY(3.8rem) scaleY(0.72);
  }
  38% {
    transform: translateY(calc(42% + 1.6rem)) scaleY(1.12);
  }
  47% {
    transform: translateY(-0.9rem) scaleY(0.92);
  }
  55% {
    transform: translateY(0.25rem) scaleY(1.06);
  }
  72% {
    transform: translateY(0.65rem) scaleY(0.96);
  }
  100% {
    transform: translateY(2.3rem) scaleY(0.78);
  }
}

@keyframes jaw-devour-top {
  0%, 20% {
    transform: translateY(3.1rem) rotateX(12deg) scaleY(0.78);
  }
  32% {
    transform: translateY(calc(-45% - 1.3rem)) rotateX(-46deg) scaleX(1.04) scaleY(1.22);
  }
  40% {
    transform: translateY(calc(-50% - 1.7rem)) rotateX(-58deg) scaleX(1.08) scaleY(1.28);
  }
  48% {
    transform: translateY(0.6rem) rotateX(13deg) scaleX(0.96) scaleY(0.86);
  }
  56% {
    transform: translateY(-0.22rem) rotateX(-4deg) scaleX(1.01) scaleY(1.02);
  }
  68%, 100% {
    transform: translateY(0) rotateX(0deg) scale(1);
  }
}

@keyframes jaw-devour-bottom {
  0%, 20% {
    transform: translateY(3.2rem) rotateX(-8deg) scaleY(0.72);
  }
  32% {
    transform: translateY(calc(42% + 1rem)) rotateX(22deg) scaleX(1.04) scaleY(1.18);
  }
  40% {
    transform: translateY(calc(50% + 1.35rem)) rotateX(31deg) scaleX(1.08) scaleY(1.24);
  }
  48% {
    transform: translateY(-0.4rem) rotateX(-12deg) scaleX(0.95) scaleY(0.82);
  }
  56% {
    transform: translateY(0.2rem) rotateX(4deg) scaleX(1.02) scaleY(1.04);
  }
  68%, 100% {
    transform: translateY(0) rotateX(0deg) scale(1);
  }
}

@keyframes tongue-devour {
  0%, 20% {
    transform: translateY(1.2rem) scaleX(0.7) scaleY(0.22);
    opacity: 0;
  }
  34% {
    transform: translateY(-1.4rem) scaleX(1.18) scaleY(2.7);
    opacity: 1;
  }
  44% {
    transform: translateY(0.6rem) scaleX(0.62) scaleY(0.25);
    opacity: 0.5;
  }
  58%, 100% {
    transform: translateY(1.1rem) scaleX(0.7) scaleY(0.18);
    opacity: 0;
  }
}

@keyframes mimic-eye-flare {
  0%, 22% {
    transform: scaleY(0.58);
    filter: brightness(0.8);
  }
  36% {
    transform: scaleY(1.18) scaleX(1.08);
    filter: brightness(1.45) saturate(1.2);
  }
  50% {
    transform: scaleY(0.38) scaleX(1.2);
    filter: brightness(1.8) saturate(1.35);
  }
  72%, 100% {
    transform: scaleY(0.72);
    filter: brightness(0.9);
  }
}

@keyframes tooth-bite {
  0%, 34% {
    transform: translateY(0) scaleY(1);
  }
  48% {
    transform: translateY(0.2rem) scaleY(1.24);
  }
  56% {
    transform: translateY(-0.05rem) scaleY(0.94);
  }
  68%, 100% {
    transform: translateY(0) scaleY(1);
  }
}

@keyframes board-devoured {
  0%, 20% {
    transform: translateY(0) scale(1);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
    filter: brightness(1);
    opacity: 1;
  }
  30% {
    transform: translateY(-0.35rem) rotate(-0.6deg) scale(1.015, 0.98);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
    filter: brightness(0.94) saturate(1.04);
    opacity: 1;
  }
  40% {
    transform: translateY(0.15rem) rotate(0.7deg) scaleX(1.04) scaleY(0.92);
    clip-path: polygon(2% 0, 98% 0, 100% 100%, 0 100%);
    filter: brightness(0.72) saturate(1.1);
    opacity: 0.96;
  }
  48% {
    transform: translateY(0.5rem) rotate(-0.4deg) scaleX(0.68) scaleY(0.48);
    clip-path: polygon(12% 10%, 88% 4%, 82% 93%, 18% 100%);
    filter: brightness(0.52) saturate(1.2) blur(0.2px);
    opacity: 0.82;
  }
  58% {
    transform: translateY(1.7rem) rotate(1.5deg) scaleX(0.28) scaleY(0.22);
    clip-path: polygon(38% 0, 64% 10%, 58% 100%, 42% 90%);
    filter: brightness(0.34) saturate(1.25) blur(0.45px);
    opacity: 0.46;
  }
  70% {
    transform: translateY(2.4rem) rotate(-1deg) scaleX(0.06) scaleY(0.08);
    clip-path: polygon(48% 0, 53% 12%, 52% 100%, 47% 90%);
    filter: brightness(0.22) blur(0.7px);
    opacity: 0;
  }
  100% {
    transform: translateY(2.4rem) scale(0);
    clip-path: polygon(50% 0, 50% 0, 50% 100%, 50% 100%);
    filter: brightness(0.2) blur(0.7px);
    opacity: 0;
  }
}

/* Reduced motion: instant swap */
@media (prefers-reduced-motion: reduce) {
  .mimic-stage.chomping,
  .mimic-stage.chomping::before,
  .mimic-stage.chomping .mimic,
  .mimic-stage.chomping .mimic-body,
  .mimic-stage.chomping .mimic-jaw-top,
  .mimic-stage.chomping .mimic-jaw-bottom,
  .mimic-stage.chomping .mimic-tongue,
  .mimic-stage.chomping .mimic-eye,
  .mimic-stage.chomping .mimic-jaw-top .tooth,
  .mimic-stage.chomping .mimic-jaw-bottom .tooth,
  .mimic-stage.chomping .offering-board {
    animation: none !important;
  }

  .mimic-stage.chomping .offering-board {
    opacity: 0 !important;
  }

  .mimic-stage.chomping .mimic {
    opacity: 0 !important;
  }

  .mimic-stage.chomping {
    z-index: 1 !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
  }
}

/* ============================================================
   Runtime meter — wax candle (desktop) / tankard (mobile)
   ============================================================
   The component sets these inline custom properties on the root:
     --meter-fill    0..=1    fill level (0 empty, 1 full)
     --meter-warning  0 or 1   1 when past the 3h safe point
     --meter-phase    idle|active   visual state
     --flame-scale    unitless multiplier for flame size (default 1)
     --flame-flicker-period    CSS time for one flicker cycle
     --flame-tint    "warm" | "warn"   flame color preset

   --flame-scale is set by the component based on the candle's
   remaining wax (low candle => smaller flame). --flame-flicker-period
   shortens as wax runs out (a guttering flame flickers faster).
   --flame-tint swaps the flame fill when the warning state is on.

   The same SVG renders on both phases; only the wax color, the
   flame visibility, and the rune visibility differ. Mobile
   (@media max-width: 767px) widens the silhouette so the same
   shape reads as a tankard of ale rather than a candle — a
   visual swap, not a new component.
*/

.wax-candle-meter {
  --meter-fill: 0;
  --meter-warning: 0;
  --meter-phase: idle;
  --flame-scale: 1;
  --flame-flicker-period: 1.4s;
  --flame-tint: warm;
  --candle-wax: oklch(0.88 0.06 80);
  --candle-wax-shadow: oklch(0.7 0.08 70);
  --candle-flame: oklch(0.85 0.18 60);
  --candle-warn-wax: oklch(0.55 0.22 22);
  --candle-warn-flame: oklch(0.7 0.3 145);
  --candle-warn-glow: oklch(0.6 0.25 22);
  display: flex;
  align-items: flex-end;
  gap: 0.6rem;
  width: 100%;
  font-variant-numeric: tabular-nums;
}

.wax-candle-meter .meter-svg {
  /* The candle's intrinsic ratio. The candle SVG is 56x140; the
     tankard SVG (mobile only) is full container width and
     auto-height. */
  width: 56px;
  height: 140px;
  flex: 0 0 auto;
  display: block;
}

/* The tankard fills the available width and keeps its own
   intentionally taller stein ratio from the SVG viewBox. */
.wax-candle-meter .meter-svg--tankard {
  width: 100%;
  height: auto;
  aspect-ratio: 120 / 88;
}

/* Candle stack: four separate SVG layers share the same
   80x200 viewBox and are overlaid in one fixed-size box.
   This keeps each job dumb and isolated: wax clips itself,
   drips are clipped to the current wax area, pooled wax stays
   at the base, and the flame/wick layer simply follows the
   wax top. */
.wax-candle-meter .candle-stack {
  position: relative;
}

.wax-candle-meter .candle-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

.wax-candle-meter .candle-layer--body {
  position: relative;
}

/* The flame is intentionally NOT a full-height overlay. It is
   a 40-unit-tall SVG rendered at 28px tall (same 0.7 scale as
   the candle stack). Its bottom edge is positioned exactly at
   the current wax surface: full-wax top is 28px, wax travel is
   105px, flame height is 28px. */
.wax-candle-meter .candle-layer--flame {
  top: calc((28px + (1 - var(--meter-fill)) * 105px) - 28px);
  height: 28px;
  transition: top 360ms cubic-bezier(0.22, 1, 0.36, 1);
}

.wax-candle-meter .meter-text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.wax-candle-meter .meter-text .meter-now {
  font-size: var(--text-xl);
  font-weight: 800;
  line-height: 1;
  color: var(--tooth);
}

.wax-candle-meter .meter-text .meter-sub {
  font-size: var(--text-sm);
  color: var(--dim);
  font-weight: 600;
}

.wax-candle-meter .meter-text .meter-warning {
  margin-top: 0.35rem;
  color: var(--candle-warn-glow);
  font-weight: 700;
  font-size: var(--text-sm);
  opacity: calc(var(--meter-warning));
  transition: opacity 240ms ease;
}

/* Candle wax body: a simple vertical bar clipped from the
   top. At fill=0 the inset is 100% (no wax visible); at
   fill=1 the inset is 0% (wax fills the full candle). */
.wax-candle-meter .candle-wax {
  fill: var(--candle-wax);
  filter: drop-shadow(0 1px 0 var(--candle-wax-shadow));
  clip-path: inset(calc((1 - var(--meter-fill)) * 100%) 0 0 0);
  transition: clip-path 360ms cubic-bezier(0.22, 1, 0.36, 1);
}

.wax-candle-meter .candle-shell {
  clip-path: inset(calc((1 - var(--meter-fill)) * 100%) 0 0 0);
  transition: clip-path 360ms cubic-bezier(0.22, 1, 0.36, 1);
}

.wax-candle-meter .candle-wick {
  stroke: oklch(0.16 0.04 40);
  stroke-width: 1.6;
  stroke-linecap: round;
}

/* Flame internals no longer do layout. The separate flame SVG
   layer is positioned with CSS; this group only exists as a
   styling hook for the wick/flame/spark/rune/vapor. */
.wax-candle-meter .candle-top {
  transform: none;
}

.wax-candle-meter .candle-flame {
  fill: var(--candle-flame);
  opacity: 0;
  transform-origin: 50% 100%;
  transition: opacity 240ms ease;
}

/* Active phase: show the flame and run the flicker. Idle hides
   the flame (the candle is unlit, just a wax reservoir). The
   flame size and flicker speed both scale with --flame-scale /
   --flame-flicker-period so the component can drive a low-wax
   flame to be smaller and more nervous. The base scale of 1
   becomes whatever --flame-scale resolves to (component sets it
   from candle fill level). */
.wax-candle-meter[data-phase="active"] .candle-flame {
  opacity: 1;
  transform: scale(var(--flame-scale));
  animation: flame-flicker var(--flame-flicker-period) ease-in-out infinite,
             flame-gust 9s ease-in-out infinite;
}

/* Warning tint: swap the flame fill to the sickly green
   preset. We keep the flicker going because a dying flame
   still flickers, just at the wrong color. */
.wax-candle-meter[data-warning="1"][data-phase="active"] .candle-flame {
  fill: var(--candle-warn-flame);
}

/* Snuffed: the queue is fully consumed in the active phase. The
   flame dips and gutters, then fades to a wisp of smoke. After
   the snuff completes the flame stays invisible until the next
   session start ignites it again. The snuff animation overrides
   the flicker/gust so the flame doesn't keep going while it
   dies. */
.wax-candle-meter[data-phase="active"][data-snuffer="1"] .candle-flame {
  animation: flame-snuff 1.2s cubic-bezier(0.55, 0.06, 0.68, 0.19) forwards;
}

/* Drip interaction: when a drip path fires (data-drip-75 etc),
   the flame dips briefly — a tiny gust from the falling wax
   disturbing the air around the wick. Reads as "the flame
   winced", not a snuff. */
.wax-candle-meter[data-phase="active"][data-drip-75="1"] .candle-flame,
.wax-candle-meter[data-phase="active"][data-drip-50="1"] .candle-flame,
.wax-candle-meter[data-phase="active"][data-drip-25="1"] .candle-flame {
  animation: flame-dip 1.6s cubic-bezier(0.55, 0.06, 0.68, 0.19),
             flame-flicker var(--flame-flicker-period) ease-in-out infinite;
}

@keyframes flame-snuff {
  0% {
    opacity: 1;
    transform: scale(var(--flame-scale)) scaleY(1) translateY(0);
  }
  30% {
    opacity: 0.85;
    transform: scale(var(--flame-scale)) scaleY(0.7) translateY(2px);
  }
  60% {
    opacity: 0.45;
    transform: scale(var(--flame-scale)) scaleY(0.35) translateY(6px);
  }
  100% {
    opacity: 0;
    transform: scale(var(--flame-scale)) scaleY(0.05) translateY(12px);
  }
}

/* Drip dip: the flame shrinks briefly then springs back. The
   keyframes are co-prime with the flicker so they don't
   synchronize (a real flame looks chaotic, not choreographed).
   After the dip the flicker resumes from wherever the flame
   was. */
@keyframes flame-dip {
  0% {
    opacity: 1;
    transform: scale(var(--flame-scale)) scaleY(1) translateX(0);
  }
  18% {
    opacity: 0.85;
    transform: scale(var(--flame-scale)) scaleY(0.7) translateX(2px);
  }
  40% {
    opacity: 0.95;
    transform: scale(calc(var(--flame-scale) * 1.05)) scaleY(1.1) translateX(-1px);
  }
  100% {
    opacity: 1;
    transform: scale(var(--flame-scale)) scaleY(1) translateX(0);
  }
}

/* Wind gust: rare, asymmetric skew of the flame. Runs at a
   9s period so it appears every few cycles, not on every
   flicker. The skew is small (~4deg) so it reads as
   'a draft passed', not 'the flame is dying'. */
@keyframes flame-gust {
  0%, 78%, 100% {
    transform: scale(var(--flame-scale)) skewX(0deg);
  }
  83% {
    transform: scale(calc(var(--flame-scale) * 1.02)) skewX(-4deg);
  }
  88% {
    transform: scale(calc(var(--flame-scale) * 0.96)) skewX(3deg);
  }
  93% {
    transform: scale(var(--flame-scale)) skewX(-1deg);
  }
}

/* Warning: red wax, sickly green flame (active), pulsing glow. */
.wax-candle-meter[data-warning="1"] .candle-wax {
  fill: var(--candle-warn-wax);
  animation: warning-pulse 2s ease-in-out infinite;
}

.wax-candle-meter[data-warning="1"][data-phase="active"] .candle-flame {
  fill: var(--candle-warn-flame);
}

.wax-candle-meter .candle-rune {
  fill: var(--candle-warn-glow);
  opacity: calc(var(--meter-warning));
  transition: opacity 240ms ease;
}

.wax-candle-meter[data-warning="1"] .candle-rune {
  animation: warning-pulse 2s ease-in-out infinite;
}

/* ===== Drips =====
   The drips live in their own SVG layer. That whole layer is
   clipped to the current wax rectangle, so a drip can never
   appear above the remaining wax body (it must have wax to cling
   to). The wax rectangle spans y=40..190 in a 200-unit viewBox,
   so the dynamic top clip is 20% + (1 - fill) * 75%; the bottom
   clip is 5%. */
.wax-candle-meter .candle-layer--drips {
  clip-path: inset(calc(20% + (1 - var(--meter-fill)) * 75%) 0 5% 0);
  transition: clip-path 360ms cubic-bezier(0.22, 1, 0.36, 1);
}
.wax-candle-meter .candle-drip {
  fill: var(--candle-wax);
  opacity: 0;
  transform: translateY(0);
  transform-origin: 50% 50%;
}

.wax-candle-meter[data-drip-75="1"] .candle-drip--75,
.wax-candle-meter[data-drip-50="1"] .candle-drip--50,
.wax-candle-meter[data-drip-25="1"] .candle-drip--25 {
  opacity: 1;
  animation: drip-fall 1.6s cubic-bezier(0.55, 0.06, 0.68, 0.19) forwards;
}

/* Separate pooled wax layer. Always visible and not clipped
   by the wax body or drip layer. */
.wax-candle-meter .candle-pool {
  fill: var(--candle-wax);
  opacity: 1;
  filter: drop-shadow(0 1px 0 var(--candle-wax-shadow));
}

.wax-candle-meter[data-warning="1"] .candle-drip,
.wax-candle-meter[data-warning="1"] .candle-pool {
  /* Red wax during the warning state, per PLAN.md §6. */
  fill: var(--candle-warn-wax);
}

@keyframes drip-fall {
  0% {
    transform: translate(0, 0);
    opacity: 1;
  }
  60% {
    transform: translate(8px, 80px);
    opacity: 1;
  }
  85% {
    transform: translate(0, 130px);
    opacity: 0.9;
  }
  100% {
    transform: translate(0, 130px);
    opacity: 0;
  }
}

/* ===== Wax settle =====
   When a new song arrives, the wax body wobbles briefly and a
   wisp of "scent" vapor rises from the wick. Triggered by
   [data-settle="1"] which the component sets for 250ms after a
   level increase, then unsets. The class is on a child element
   (not the root) because the root already has data-phase and
   data-warning for layout decisions. */
.wax-candle-meter .candle-wax--settling {
  animation: wax-settle 250ms cubic-bezier(0.36, 0.07, 0.19, 0.97);
  transform-origin: 50% 100%;
}

.wax-candle-meter .candle-vapor {
  fill: oklch(0.85 0.04 80 / 0.5);
  opacity: 0;
  transform: translateY(0);
}

.wax-candle-meter[data-settle="1"] .candle-vapor {
  animation: vapor-rise 1.4s ease-out forwards;
}

@keyframes wax-settle {
  0% {
    transform: scaleX(1) scaleY(1);
  }
  30% {
    transform: scaleX(1.04) scaleY(0.985);
  }
  60% {
    transform: scaleX(0.985) scaleY(1.005);
  }
  100% {
    transform: scaleX(1) scaleY(1);
  }
}

@keyframes vapor-rise {
  0% {
    transform: translateY(0);
    opacity: 0.5;
  }
  100% {
    transform: translateY(-26px);
    opacity: 0;
  }
}

/* ===== Ignition =====
   Runs once on the idle→active transition. Sequence: spark at
   the wick (visible briefly), then the flame scales from 0 to
   full over 600ms, while the wax recedes briefly from the top
   to suggest it was just lit. Triggered by [data-igniting="1"]
   for the 600ms duration. */
.wax-candle-meter .candle-spark {
  fill: oklch(0.95 0.18 90);
  opacity: 0;
}

.wax-candle-meter[data-igniting="1"] .candle-spark {
  animation: spark-burst 600ms ease-out forwards;
}

.wax-candle-meter[data-igniting="1"] .candle-flame {
  /* Override the steady-state flicker during ignition with a
     scale-up from 0. */
  animation: ignition-flame 600ms ease-out forwards,
             flame-flicker 1.4s ease-in-out 600ms infinite;
  opacity: 1;
}

.wax-candle-meter[data-igniting="1"] .candle-wax {
  /* Brief recession: the clip-path inset goes from 0% (full)
     to 2% (tiny gap at top) and back. We override the
     fill-based clip with an explicit inset that is briefly
     larger. */
  animation: ignition-wax-recede 600ms ease-out;
}

@keyframes spark-burst {
  0% {
    opacity: 0;
    transform: scale(0.3);
  }
  20% {
    opacity: 1;
    transform: scale(1.6);
  }
  50% {
    opacity: 0.8;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(0.6);
  }
}

@keyframes ignition-flame {
  0% {
    transform: scaleY(0) scaleX(0.5);
    opacity: 0;
  }
  40% {
    transform: scaleY(0.6) scaleX(0.9);
    opacity: 0.8;
  }
  100% {
    transform: scaleY(1) scaleX(1);
    opacity: 1;
  }
}

@keyframes ignition-wax-recede {
  0%, 100% {
    /* The fill-based clip is on this element via the
       .candle-wax base rule; the ignition animation
       rides on top via filter, not via the clip itself,
       so the steady-state fill math is preserved. */
    filter: drop-shadow(0 0 0 transparent);
  }
  40% {
    filter: drop-shadow(0 -2px 4px oklch(0.95 0.15 80 / 0.5));
  }
}

/* ===== Tankard (mobile) =====
   The tankard SVG is rendered on every viewport; the @media
   rules below swap which one is visible. The candle SVG is
   visible by default (desktop); on mobile (<=767px) the
   tankard shows instead. Both consume the same --meter-fill
   and --meter-warning vars. */
.wax-candle-meter .meter-svg--tankard {
  display: none;
}

@media (max-width: 767px) {
  .wax-candle-meter .meter-svg--candle {
    display: none;
  }
  .wax-candle-meter .meter-svg--tankard {
    display: block;
  }
}

.wax-candle-meter .tankard-ale {
  /* The ale level: clip-path inset driven by --meter-fill, same
     pattern as the candle wax. At fill=0 the inset is 100% (no
     ale); at fill=1 the inset is 0% (full to the foam line). */
  --ale-color: oklch(0.78 0.14 75);
  fill: var(--ale-color);
  clip-path: inset(calc((1 - var(--meter-fill)) * 100%) 0 0 0);
  transition: clip-path 360ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Tankard foam: the foam follows the ale surface as the
   tankard drains. The ale rect is 50 user units tall, so
   the foam translates by (1 - fill) * 50 in user units. The
   transition matches the ale clip-path so the foam stays
   glued to the surface during the 360ms easing. */
.wax-candle-meter .tankard-top {
  transform: translateY(calc((1 - var(--meter-fill)) * 50px));
  transition: transform 360ms cubic-bezier(0.22, 1, 0.36, 1);
}

.wax-candle-meter[data-warning="1"] .tankard-ale {
  --ale-color: oklch(0.55 0.22 22);
  animation: warning-pulse 2s ease-in-out infinite;
}

.wax-candle-meter .tankard-foam {
  fill: oklch(0.92 0.04 80);
  filter: drop-shadow(0 -1px 0 oklch(0.7 0.06 70));
}

.wax-candle-meter[data-warning="1"] .tankard-foam {
  fill: oklch(0.7 0.2 22);
}

.wax-candle-meter .tankard-ripple {
  fill: none;
  stroke: oklch(0.85 0.06 80 / 0.5);
  stroke-width: 1.2;
  opacity: 0;
  transform-origin: 50% 50%;
}

.wax-candle-meter[data-settle="1"] .tankard-ripple--1 {
  animation: tankard-ripple 800ms ease-out forwards;
}

.wax-candle-meter[data-settle="1"] .tankard-ripple--2 {
  animation: tankard-ripple 800ms ease-out 120ms forwards;
}

@keyframes tankard-ripple {
  0% {
    transform: scale(0.4);
    opacity: 0.7;
    stroke-width: 1.6;
  }
  100% {
    transform: scale(2.4);
    opacity: 0;
    stroke-width: 0.4;
  }
}

/* Mobile: the candle SVG is hidden and a separate tankard SVG
   shows. Both SVGs share the same flex container; only one is
   display:block at any viewport. */

/* Flicker: subtle brightness + scale wobble. The base scale is
   driven by --flame-scale on the element; we wobble around it
   with scaleY/scaleX deltas inside the keyframe. The flame also
   carries the parent transform from flame-gust during the
   9-second cycle; the flicker only changes the wobble. */
@keyframes flame-flicker {
  0%, 100% {
    opacity: 0.95;
  }
  25% {
    opacity: 1;
  }
  50% {
    opacity: 0.9;
  }
  75% {
    opacity: 0.95;
  }
}

/* Smaller-scale flicker variant: the flame wobbles more
   nervously when wax is low. We use scaleY instead of opacity
   alone so a low candle has a visibly twitchier flame, not a
   dimmer one. This keyframe is referenced from the component
   via --flame-flicker-key when --flame-scale < 0.5. */
@keyframes flame-flicker-nervous {
  0%, 100% {
    transform: scale(var(--flame-scale)) scaleY(1) scaleX(1);
    opacity: 0.9;
  }
  20% {
    transform: scale(var(--flame-scale)) scaleY(1.15) scaleX(0.92);
    opacity: 1;
  }
  40% {
    transform: scale(var(--flame-scale)) scaleY(0.9) scaleX(1.08);
    opacity: 0.8;
  }
  60% {
    transform: scale(var(--flame-scale)) scaleY(1.1) scaleX(0.95);
    opacity: 1;
  }
  80% {
    transform: scale(var(--flame-scale)) scaleY(0.92) scaleX(1.05);
    opacity: 0.85;
  }
}

@keyframes warning-pulse {
  0%, 100% {
    filter: drop-shadow(0 0 0 transparent);
  }
  50% {
    filter: drop-shadow(0 0 6px var(--candle-warn-glow));
  }
}

.session-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 1px solid;
}

.session-badge-active {
  background: oklch(0.32 0.08 145 / 0.25);
  border-color: oklch(0.5 0.12 145);
  color: oklch(0.85 0.13 145);
}

.session-badge-paused {
  background: oklch(0.32 0.1 80 / 0.25);
  border-color: oklch(0.5 0.12 80);
  color: oklch(0.88 0.13 80);
}

.admin-controls {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px dashed oklch(0.3 0.05 50);
}

.admin-button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.admin-button {
  background:
    linear-gradient(180deg, oklch(0.21 0.04 36), oklch(0.13 0.025 30));
  color: oklch(0.82 0.06 65);
  border-color: oklch(0.32 0.06 50);
  padding: 0 1rem;
  min-height: 2.4rem;
  font-size: var(--text-sm);
}

.admin-button:hover:not(:disabled) {
  background:
    linear-gradient(180deg, oklch(0.27 0.05 36), oklch(0.18 0.03 30));
  color: oklch(0.92 0.07 70);
  border-color: oklch(0.42 0.08 50);
}

.admin-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.admin-button-stop {
  margin-left: auto;
}

.queue-section-heading {
  position: relative;
  z-index: 3;
  font-family: 'IM Fell English SC', 'IM Fell English', Georgia, serif;
  font-size: 1.05rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 1.25rem 0 0.5rem;
  border-bottom: 1px solid oklch(0.25 0.04 50);
  padding-bottom: 0.25rem;
}

.queue-section-empty {
  position: relative;
  z-index: 3;
  color: var(--dim);
  font-style: italic;
  padding: 0.75rem 0;
  margin: 0;
}

.tonights-sung {
  position: relative;
  z-index: 3;
  margin-top: 1.25rem;
  border-top: 1px dashed oklch(0.25 0.04 50);
  padding-top: 0.5rem;
}

.tonights-sung-hidden {
  display: none;
}

.tonights-sung-toggle {
  background: transparent;
  border: 0;
  color: var(--dim);
  font: inherit;
  font-family: 'IM Fell English SC', 'IM Fell English', Georgia, serif;
  font-size: 1rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.4rem 0.5rem;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  cursor: pointer;
  width: 100%;
  text-align: left;
}

.tonights-sung-toggle:hover {
  color: var(--tooth);
  background: oklch(1 0 0 / 0.04);
}

.tonights-sung-chevron {
  display: inline-block;
  font-size: 0.85em;
  transition: transform 220ms cubic-bezier(0.25, 1, 0.5, 1);
}

.tonights-sung-chevron[data-open="true"] {
  transform: rotate(90deg);
}

.tonights-sung-label {
  flex: 1;
}

.tonights-sung-count {
  background: oklch(0.25 0.05 50 / 0.4);
  color: var(--dim);
  font-family: inherit;
  font-size: 0.75rem;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  letter-spacing: 0;
  text-transform: none;
}

.tonights-sung-list {
  display: none;
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
}

.tonights-sung-list[data-open="true"] {
  display: block;
}

/* Step 6: close-the-tavern button + confirm dialog + past parties
   panel. The confirm flow is intentionally a small two-step
   interaction: click to reveal the type-CLOSE input, then a second
   click on Confirm (only enabled when the input matches) submits.
   The past parties panel is a flat list with one Restore button
   per row; the per-song archive viewer is a future enhancement. */

.close-tavern {
  margin-top: 1rem;
}

.close-tavern-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.close-tavern-confirm {
  background:
    linear-gradient(180deg, oklch(0.21 0.04 36), oklch(0.13 0.025 30));
  border: 1px solid oklch(0.5 0.12 25);
  border-radius: 8px;
  padding: 0.85rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.close-tavern-warning {
  color: oklch(0.85 0.13 25);
  font-style: italic;
  margin: 0;
}

.close-tavern-label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  color: var(--dim);
  font-size: var(--text-sm);
}

.close-tavern-input {
  background: oklch(0.1 0.02 30);
  border: 1px solid oklch(0.3 0.05 50);
  border-radius: 4px;
  color: var(--tooth);
  padding: 0.4rem 0.6rem;
  font-family: monospace;
  letter-spacing: 0.06em;
}

.close-tavern-error {
  color: oklch(0.85 0.13 25);
  margin: 0;
}

.close-tavern-buttons {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
}

.past-parties {
  margin-top: 1.5rem;
}

.past-parties-list {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.past-party-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid oklch(0.25 0.05 50);
  border-radius: 6px;
  background: oklch(0.15 0.03 30 / 0.4);
}

.past-party-meta {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.past-party-meta strong {
  color: var(--tooth);
  font-family: 'IM Fell English SC', 'IM Fell English', Georgia, serif;
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: 0.04em;
}

.past-party-sub {
  color: var(--dim);
  font-size: var(--text-xs);
}
