/* DevBanjo home: a screen-printed gig poster that turns into a porch at night. */

:root {
  --paper: #f2e7d0;
  --paper-2: #e8d9b8;
  --ink: #211b15;
  --ink-soft: #5d5043;
  --red: #d4432a;
  --mustard: #e9a92d;
  --teal: #226a6c;
  --sun: #eeb23a;
  --wood: #70411f;
  --wood-dark: #3a2213;
  --board: #24160d;
  --metal: #c3bdae;
  --metal-dark: #857f71;
  --head: #f7eed8;
  --head-edge: #e0cea6;
  --string: #b9b2a2;
  --string-hot: #d4432a;
  --note-paper: #fbf6ea;
  --note-ink: #1d1a17;
  --grain-blend: multiply;
  --grain-opacity: .38;
  color-scheme: light;
}

html[data-night] {
  --paper: #14151f;
  --paper-2: #1d1e2b;
  --ink: #efe4cb;
  --ink-soft: #b3a78f;
  --red: #ff6b4a;
  --mustard: #ffc457;
  --teal: #6cc3bd;
  --sun: #efe7cf;
  --head: #eadfc4;
  --head-edge: #c9b68d;
  --string: #e9d9ae;
  --string-hot: #ffcf6a;
  --note-paper: #eee4cc;
  --grain-blend: overlay;
  --grain-opacity: .22;
  color-scheme: dark;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Fraunces", Georgia, serif;
  font-size: 18px;
  line-height: 1.5;
  overflow-x: hidden;
  transition: background-color .6s ease, color .6s ease;
}

/* Paper grain over everything, like ink on cheap poster stock. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: var(--grain-blend);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .45  0 0 0 0 .38  0 0 0 0 .3  0 0 0 .55 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

button { font: inherit; color: inherit; }

:focus-visible { outline: 3px dashed var(--red); outline-offset: 4px; }

/* ---------- poster head ---------- */

.hero {
  position: relative;
  padding: 18px clamp(16px, 4vw, 56px) 0;
  overflow: hidden;
  isolation: isolate;
}

.poster-top {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 0 110px 10px 0;
  border-bottom: 3px solid var(--ink);
  font-family: "Courier Prime", monospace;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .14em;
  text-transform: uppercase;
}

.sun {
  position: absolute;
  z-index: -1;
  width: clamp(220px, 34vw, 520px);
  aspect-ratio: 1;
  right: clamp(-60px, 4vw, 120px);
  top: 54px;
  border-radius: 50%;
  background: var(--sun);
  transition: background-color .6s ease, transform .9s cubic-bezier(.5, 0, .2, 1);
}
/* halftone fade on the lower half of the sun */
.sun::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle, var(--paper) 38%, transparent 41%) 0 0 / 11px 11px;
  -webkit-mask: linear-gradient(to bottom, transparent 45%, #000 100%);
  mask: linear-gradient(to bottom, transparent 45%, #000 100%);
  transition: background .6s ease;
}
html[data-night] .sun { transform: translate(14%, -16%) scale(.6); }
html[data-night] .sun::before {
  /* a bite out of the sun makes it a moon */
  content: "";
  position: absolute;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  top: -6%;
  left: -14%;
  background: var(--paper);
  transition: background .6s ease;
}

.title {
  margin: 18px 0 0 -0.04em;
  font-family: "Alfa Slab One", Georgia, serif;
  font-weight: 400;
  font-size: clamp(64px, 15.5vw, 236px);
  line-height: .88;
  letter-spacing: -.01em;
  color: var(--ink);
  text-shadow: .045em .035em 0 var(--red);
  user-select: none;
  white-space: nowrap;
}
.title .ch {
  display: inline-block;
  cursor: default;
  transition: color .2s ease;
}
.title .ch.boing { animation: boing .55s cubic-bezier(.3, 1.6, .5, 1); color: var(--teal); }
@keyframes boing {
  0% { transform: translateY(0); }
  30% { transform: translateY(-.14em) rotate(-4deg); }
  100% { transform: translateY(0); }
}


/* ---------- porch light ---------- */

.porch {
  position: absolute;
  top: 0;
  right: clamp(8px, 3vw, 44px);
  width: 90px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  z-index: 5;
  -webkit-tap-highlight-color: transparent;
}
.porch svg { display: block; width: 90px; height: auto; overflow: visible; }
.lamp-cord { stroke: var(--ink); stroke-width: 3; }
.lamp-cap { fill: var(--ink); }
.lamp-glass { fill: color-mix(in srgb, var(--paper) 70%, #fff); stroke: var(--ink); stroke-width: 3; transition: fill .4s; }
.lamp-cage { stroke: var(--ink); stroke-width: 2; fill: none; opacity: .75; }
.lamp-bulb { fill: #d8cfba; stroke: var(--ink); stroke-width: 1.5; transition: fill .3s; }
.lamp-halo { opacity: 0; transition: opacity .4s; }
.chain-beads { stroke: var(--metal-dark); stroke-width: 4; stroke-linecap: round; stroke-dasharray: .1 7; }
.chain-pull { fill: var(--red); stroke: var(--ink); stroke-width: 2; }
.lamp-chain { transition: transform .18s cubic-bezier(.3, 1.5, .5, 1); }
.porch.tug .lamp-chain { transform: translateY(14px); transition-duration: .08s; }
.porch:hover .lamp-chain { transform: translateY(3px); }
html[data-night] .lamp-bulb { fill: #ffe9a6; }
html[data-night] .lamp-halo { opacity: 1; }
html[data-night] .lamp-glass { fill: #ffe9a655; }
.porch-note {
  position: absolute;
  left: 70px;
  top: 196px;
  font-family: "Permanent Marker", cursive;
  font-size: 15px;
  color: var(--red);
  transform: rotate(8deg);
  pointer-events: none;
}

/* the warm pool of light under the porch lamp at night */
html[data-night] body {
  background-image: radial-gradient(circle 760px at calc(100% - 70px) 110px, #ffc45724, #ffb04a0c 55%, transparent 100%);
  background-repeat: no-repeat;
}

/* ---------- the banjo ---------- */

.stage { position: relative; overflow-x: clip; }

.banjo-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 1600 / 560;
  margin-top: -2vw;
  outline-offset: -8px;
}
.banjo-wrap svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

.strum-zone {
  position: absolute;
  left: 0;
  right: 0;
  touch-action: none;
}

@media (max-width: 760px) {
  .banjo-wrap { aspect-ratio: 1.22; margin-top: 4px; overflow: hidden; }
  .banjo-wrap svg { overflow: hidden; }
}

.banjo .wood { fill: var(--wood); }
.banjo .wood-dark { fill: var(--wood-dark); }
.banjo .board { fill: var(--board); }
.banjo .metal { fill: var(--metal); stroke: var(--metal-dark); stroke-width: 2; }
.banjo .hook { stroke: var(--metal-dark); stroke-width: 7; stroke-linecap: round; }
.banjo .hook-hi { stroke: var(--metal); stroke-width: 3; stroke-linecap: round; }
.banjo .fret { stroke: var(--metal); stroke-width: 3.5; }
.banjo .inlay { fill: #efe6d2; opacity: .9; }
.banjo .head { fill: url(#headGrad); stroke: var(--metal-dark); stroke-width: 2; cursor: pointer; }
.banjo .rim-text { font-family: "Alfa Slab One", serif; font-size: 21px; letter-spacing: 3.4px; fill: var(--ink); opacity: .7; }
html[data-night] .banjo .rim-text { fill: #2a2118; }
.banjo .head-mark { color: var(--red); pointer-events: none; }
.banjo .head-small { font-family: "Courier Prime", monospace; font-weight: 700; font-size: 15px; letter-spacing: 3px; fill: #3a2f25; opacity: .65; }
.banjo .bone { fill: #efe7d4; stroke: #8f8571; stroke-width: 1.5; }
.banjo .bridge { fill: #c99a5c; stroke: #5a3a1c; stroke-width: 2; }
.banjo .peg { fill: #efe7d4; stroke: var(--ink); stroke-width: 2; }
.banjo .str, .banjo .str-tail { stroke: var(--string); fill: none; stroke-linecap: round; transition: stroke .5s; }
.banjo .str.hot { stroke: var(--string-hot); transition: stroke .05s; }
.banjo .ghost { stroke: var(--string); fill: none; opacity: .35; }
.banjo .finger { fill: var(--red); stroke: var(--paper); stroke-width: 3; transform-box: fill-box; transform-origin: center; animation: pop .25s cubic-bezier(.3, 1.7, .5, 1); }
@keyframes pop { from { transform: scale(0); } }
.banjo .hint { font-family: "Permanent Marker", cursive; font-size: 34px; fill: var(--red); transition: opacity .8s; }
.banjo .hint-arrow { stroke: var(--red); stroke-width: 4; fill: none; stroke-linecap: round; stroke-linejoin: round; transition: opacity .8s; }
.banjo.played .hint, .banjo.played .hint-arrow { opacity: 0; }

/* ---------- controls ---------- */

.controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 28px;
  padding: 6px clamp(16px, 4vw, 56px) 0;
}

.chords { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.label {
  font-family: "Courier Prime", monospace;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin-right: 2px;
}

.stamp {
  min-width: 58px;
  height: 52px;
  padding: 0 12px;
  border: 3px solid var(--red);
  border-radius: 6px;
  background: transparent;
  color: var(--red);
  font-family: "Alfa Slab One", serif;
  font-size: 22px;
  cursor: pointer;
  transform: rotate(var(--r, -2deg));
  transition: transform .15s ease, background .15s ease, color .15s ease;
}
.stamp:nth-of-type(2) { --r: 1.5deg; }
.stamp:nth-of-type(3) { --r: -1deg; }
.stamp:nth-of-type(4) { --r: 2.5deg; }
.stamp:hover { transform: rotate(0) scale(1.06); }
.stamp[aria-pressed="true"] { background: var(--red); color: var(--paper); }

.roll {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  height: 52px;
  padding: 0 20px 0 14px;
  border: 3px solid var(--ink);
  border-radius: 999px;
  background: var(--mustard);
  color: #1d1a17;
  font-weight: 600;
  font-size: 18px;
  cursor: pointer;
  box-shadow: 4px 4px 0 var(--ink);
  transition: transform .1s ease, box-shadow .1s ease;
}
.roll:hover { transform: translate(-1px, -1px); box-shadow: 5px 5px 0 var(--ink); }
.roll:active { transform: translate(3px, 3px); box-shadow: 1px 1px 0 var(--ink); }
.roll-icon {
  width: 0; height: 0;
  border-left: 14px solid #1d1a17;
  border-top: 9px solid transparent;
  border-bottom: 9px solid transparent;
}
.roll.playing .roll-icon { width: 14px; height: 16px; border: 0; border-left: 5px solid #1d1a17; border-right: 5px solid #1d1a17; }


.tab { margin: 22px clamp(16px, 4vw, 56px) 0; }
.tab figcaption {
  font-family: "Courier Prime", monospace;
  font-size: 14px;
  color: var(--ink-soft);
}
.tab pre {
  margin: 6px 0 0;
  padding: 0;
  font-family: "Courier Prime", monospace;
  font-size: 16px;
  line-height: 1.25;
  color: var(--ink-soft);
  overflow: hidden;
  white-space: pre;
}
.tab pre b { color: var(--red); font-weight: 700; }

/* ---------- setlist and ticket ---------- */

.gig {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: clamp(32px, 6vw, 90px);
  align-items: start;
  max-width: 1240px;
  margin: 0 auto;
  overflow-x: clip;
  padding: clamp(56px, 8vw, 110px) clamp(16px, 4vw, 56px) 40px;
}
@media (max-width: 860px) {
  .gig { grid-template-columns: 1fr; }
}

.setlist {
  position: relative;
  padding: 46px clamp(22px, 4vw, 48px) 40px;
  background: var(--note-paper);
  color: var(--note-ink);
  transform: rotate(-1.6deg);
  box-shadow: 0 1px 0 #0000000d, 0 18px 30px -12px #2a1c0f55;
  /* a slightly torn bottom edge */
  clip-path: polygon(-40px -40px, calc(100% + 40px) -40px, calc(100% + 40px) 60px, 100% 60px, 100% 97%, 94% 99%, 86% 97.5%, 77% 99.6%, 66% 98%, 55% 100%, 44% 98.2%, 33% 99.5%, 21% 97.8%, 10% 99.4%, 0 98%, 0 60px, -40px 60px);
}
.tape {
  position: absolute;
  top: -12px;
  width: 120px;
  height: 34px;
  background: #e9d7a6cc;
  box-shadow: 0 1px 2px #0002;
}
.tape-l { left: -18px; transform: rotate(-24deg); }
.tape-r { right: -20px; transform: rotate(18deg); }
.ring {
  /* a coffee ring, because every setlist has one */
  position: absolute;
  width: 150px;
  height: 150px;
  right: 6%;
  bottom: 8%;
  border-radius: 50%;
  border: 7px solid #8a5a2a1c;
  box-shadow: inset 0 0 0 2px #8a5a2a12;
  transform: scaleX(1.05) rotate(20deg);
  pointer-events: none;
}

.setlist h2 {
  margin: 0;
  font-family: "Permanent Marker", cursive;
  font-weight: 400;
  font-size: clamp(42px, 6vw, 64px);
  line-height: 1;
  text-transform: uppercase;
}
.sl-when { margin: 6px 0 26px; font-family: "Permanent Marker", cursive; font-size: 17px; color: #6c6155; }

.tunes { list-style: none; margin: 0; padding: 0; counter-reset: tune; }
.tunes li { counter-increment: tune; margin: 0 0 18px; }

.tune {
  position: relative;
  display: grid;
  grid-template-columns: 2.1ch 56px 1fr auto;
  column-gap: 14px;
  align-items: baseline;
  color: inherit;
  text-decoration: none;
  padding: 4px 6px;
}
.tune::before {
  content: counter(tune) ".";
  font-family: "Permanent Marker", cursive;
  font-size: 26px;
  color: #6c6155;
}
.tune-name {
  font-family: "Permanent Marker", cursive;
  font-size: clamp(30px, 4vw, 42px);
  line-height: 1.05;
}
.tune-key { font-family: "Permanent Marker", cursive; font-size: 17px; color: #6c6155; white-space: nowrap; }
.tune-note { grid-column: 3 / 5; grid-row: 2; font-size: 17px; line-height: 1.35; margin-top: 2px; }
/* fixed places, so the icon can sit beside both the name and the note */
.tune::before { grid-column: 1; grid-row: 1; }
.tune-name { grid-column: 3; grid-row: 1; }
.tune-key { grid-column: 4; grid-row: 1; }

/* each app's own icon, like it's stuck to the setlist */
.tune-icon {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: start;
  width: 56px;
  height: 56px;
  margin-top: 4px;
  border-radius: 13px;
  box-shadow: 0 1px 0 #00000026, 0 8px 14px -8px #2a1c0f80;
  transform: rotate(-3deg);
  transition: transform .2s cubic-bezier(.3, 1.6, .5, 1);
}
.tunes li:nth-child(even) .tune-icon { transform: rotate(2.5deg); }
a.tune:hover .tune-icon, a.tune:focus-visible .tune-icon { transform: rotate(0) scale(1.08); }
.tune-icon.pixel { image-rendering: pixelated; }
.tune-icon.blank {
  display: grid;
  place-items: center;
  border: 2px dashed #1d1a1755;
  box-shadow: none;
  font-family: "Permanent Marker", cursive;
  font-size: 28px;
  color: #7b7064;
}
.tune-go { font-family: "Courier Prime", monospace; font-weight: 700; font-size: 13px; letter-spacing: .12em; text-transform: uppercase; color: #b83820; }
.tune-badge {
  display: inline-block;
  margin-left: 10px;
  padding: 1px 8px;
  border: 2px solid currentColor;
  border-radius: 4px;
  font-family: "Courier Prime", monospace;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  vertical-align: middle;
  transform: rotate(-3deg);
}
.tune-badge.live { color: #1f6d5d; }
.tune-badge.solo { color: #b83820; }

.scribble {
  position: absolute;
  inset: -8px -14px -6px -14px;
  width: calc(100% + 28px);
  height: calc(100% + 14px);
  pointer-events: none;
  overflow: visible;
}
.scribble path {
  fill: none;
  stroke: #c63d24;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset .45s ease;
}
a.tune:hover .scribble path, a.tune:focus-visible .scribble path { stroke-dashoffset: 0; }
a.tune:focus-visible { outline: none; }

.tunes li.writing .tune { color: #7b7064; }
.tunes li.writing .tune-name s { text-decoration-thickness: 3px; text-decoration-color: #1d1a17aa; }
.tunes li.solo .tune-name { text-decoration: line-through 3px #1d1a17aa; }

.encore {
  margin: 30px 0 0;
  padding-top: 18px;
  border-top: 2px dashed #1d1a1733;
  font-family: "Permanent Marker", cursive;
  font-size: 22px;
}
.encore span { color: #b83820; text-transform: uppercase; }

.ticket {
  display: flex;
  margin-top: 24px;
  transform: rotate(2deg);
  color: #1d1a17;
  filter: drop-shadow(0 16px 18px #2a1c0f40);
}
.ticket-main {
  flex: 1;
  padding: 26px 26px 24px;
  background: var(--mustard);
  border-radius: 10px 0 0 10px;
  /* notches where the stub tears off */
  -webkit-mask: radial-gradient(circle at 100% 0, transparent 14px, #000 15px) top / 100% 51% no-repeat, radial-gradient(circle at 100% 100%, transparent 14px, #000 15px) bottom / 100% 51% no-repeat;
  mask: radial-gradient(circle at 100% 0, transparent 14px, #000 15px) top / 100% 51% no-repeat, radial-gradient(circle at 100% 100%, transparent 14px, #000 15px) bottom / 100% 51% no-repeat;
}
.ticket-stub {
  position: relative;
  width: 78px;
  flex: none;
  background: var(--mustard);
  border-left: 3px dashed #1d1a1766;
  border-radius: 0 10px 10px 0;
  -webkit-mask: radial-gradient(circle at 0 0, transparent 14px, #000 15px) top / 100% 51% no-repeat, radial-gradient(circle at 0 100%, transparent 14px, #000 15px) bottom / 100% 51% no-repeat;
  mask: radial-gradient(circle at 0 0, transparent 14px, #000 15px) top / 100% 51% no-repeat, radial-gradient(circle at 0 100%, transparent 14px, #000 15px) bottom / 100% 51% no-repeat;
}
.stub-no, .stub-admit {
  position: absolute;
  left: 50%;
  top: 50%;
  white-space: nowrap;
  font-family: "Courier Prime", monospace;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.stub-no { font-size: 15px; transform: translate(-50%, -50%) rotate(-90deg) translateY(-12px); }
.stub-admit { font-size: 12px; transform: translate(-50%, -50%) rotate(-90deg) translateY(14px); opacity: .7; }
.admit {
  margin: 0;
  font-family: "Courier Prime", monospace;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .2em;
  text-transform: uppercase;
}
.ticket h2 {
  margin: 4px 0 12px;
  font-family: "Alfa Slab One", serif;
  font-weight: 400;
  font-size: clamp(30px, 3.4vw, 40px);
  line-height: 1;
  color: #a8331d;
}
.ticket p { margin: 0 0 12px; font-size: 17px; line-height: 1.45; }
.ticket-facts {
  display: flex;
  gap: 22px;
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 2px solid #1d1a1733;
}
.ticket-facts dt { font-family: "Courier Prime", monospace; font-weight: 700; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; opacity: .7; }
.ticket-facts dd { margin: 0; font-weight: 600; }

/* ---------- footer ---------- */

.foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
  margin: 40px clamp(16px, 4vw, 56px) 0;
  padding: 16px 0 40px;
  border-top: 3px solid var(--ink);
  font-family: "Courier Prime", monospace;
  font-size: 14px;
}
.foot p { margin: 0; }
.foot-mark { display: inline-flex; align-items: center; gap: 10px; }
.foot-mark img { width: 22px; height: auto; }
kbd {
  display: inline-block;
  min-width: 1.6em;
  margin: 0 2px;
  padding: 0 4px;
  border: 2px solid var(--ink);
  border-radius: 4px;
  text-align: center;
  font: inherit;
  font-weight: 700;
}

/* ---------- sound button and hint ---------- */

.sound {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 55;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 48px;
  min-width: 48px;
  padding: 0 12px;
  border: 3px solid var(--ink);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
  font-weight: 600;
  font-size: 16px;
  transition: transform .1s ease, box-shadow .1s ease, background-color .3s ease;
}
.sound:hover { transform: translate(-1px, -1px); box-shadow: 4px 4px 0 var(--ink); }
.sound:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 var(--ink); }
.sound svg { width: 24px; height: 24px; flex: none; }
.sound .spk { fill: currentColor; }
.sound .waves, .sound .cross { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
.sound .cross { display: none; }
.sound[data-state="locked"] .waves, .sound[data-state="muted"] .waves { display: none; }
.sound[data-state="locked"] .cross, .sound[data-state="muted"] .cross { display: inline; }
/* blocked by the browser: make the first tap obvious */
.sound[data-state="locked"] { background: var(--mustard); color: #1d1a17; animation: nudge 2.8s ease-in-out 1.5s infinite; }
/* once it's on (or muted on purpose) it shrinks to just the speaker */
.sound[data-state="on"] .sound-label, .sound[data-state="muted"] .sound-label {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.sound[data-state="on"], .sound[data-state="muted"] { padding: 0; justify-content: center; width: 48px; }
.sound[data-state="muted"] { color: var(--ink-soft); }
@keyframes nudge {
  0%, 80%, 100% { transform: rotate(0); }
  84% { transform: rotate(-6deg); }
  88% { transform: rotate(5deg); }
  92% { transform: rotate(-3deg); }
}

.bubble {
  position: fixed;
  z-index: 65;
  padding: 6px 14px 4px;
  border: 3px solid #1d1a17;
  border-radius: 12px;
  background: var(--note-paper);
  color: #1d1a17;
  font-family: "Permanent Marker", cursive;
  font-size: 18px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -100%) scale(.6) rotate(-3deg);
  transition: opacity .25s ease, transform .25s ease;
}
.bubble::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -10px;
  width: 14px;
  height: 14px;
  margin-left: -7px;
  background: var(--note-paper);
  border-right: 3px solid #1d1a17;
  border-bottom: 3px solid #1d1a17;
  transform: rotate(45deg);
}
.bubble.show { opacity: 1; transform: translate(-50%, -100%) scale(1) rotate(-3deg); transition-timing-function: cubic-bezier(.3, 1.6, .5, 1); }

/* ---------- fireflies, jar, picks ---------- */

.flies { position: fixed; inset: 0; z-index: 40; pointer-events: none; }
.fly {
  position: absolute;
  left: 0;
  top: 0;
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  pointer-events: auto;
  cursor: pointer;
}
.fly::after {
  content: "";
  position: absolute;
  inset: 13px;
  border-radius: 50%;
  background: #f8f39a;
  box-shadow: 0 0 10px 4px #e8f06a99, 0 0 24px 8px #d9e85a44;
  animation: blink var(--blink, 3s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
}
@keyframes blink {
  0%, 100% { opacity: .1; }
  40%, 60% { opacity: 1; }
}
.fly.caught { transition: transform .7s cubic-bezier(.5, 0, .3, 1), opacity .7s; opacity: 0; pointer-events: none; }

.jar {
  position: fixed;
  left: 14px;
  bottom: 14px;
  z-index: 45;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  font-family: "Permanent Marker", cursive;
  color: var(--ink);
  pointer-events: none;
}
.jar[hidden] { display: none; }
.jar svg { width: 46px; height: auto; }
.jar-lid { fill: var(--metal-dark); }
.jar-glass { fill: #ffffff14; stroke: var(--ink); stroke-width: 2.5; }
.jar-fly { fill: #f8f39a; filter: drop-shadow(0 0 3px #e8f06a); }
.jar-count { font-size: 15px; padding-bottom: 6px; }

.picks { position: fixed; inset: 0; z-index: 70; pointer-events: none; overflow: hidden; }
.pick {
  position: absolute;
  top: -60px;
  width: 34px;
  animation: fall var(--dur, 2.6s) cubic-bezier(.35, .1, .7, 1) forwards;
}
@keyframes fall {
  to { transform: translate(var(--dx, 0), 115vh) rotate(var(--rot, 540deg)); }
}

@media (max-width: 600px) {
  body { font-size: 17px; }
  .hide-sm { display: none; }
  .poster-top { font-size: 11px; padding-right: 80px; }
  .porch, .porch svg { width: 56px; }
  .porch-note { left: 30px; top: 136px; font-size: 13px; }
  .sun { width: 150px; top: 96px; right: -30px; }
  .title { font-size: min(13vw, 64px); margin-top: 22px; }
  .tab pre { font-size: 14px; }
  .tune { grid-template-columns: 2.1ch 44px 1fr auto; column-gap: 10px; }
  .tune-icon { width: 44px; height: 44px; border-radius: 10px; }
  .stamp { min-width: 50px; height: 46px; font-size: 19px; }
  .roll { height: 46px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  .fly::after { opacity: .8; }
}
