/* The NutPub: midnight, whisky amber, cream. Poster type (Bebas Neue, SIL OFL). */
@font-face {
  font-family: "Bebas Neue";
  src: url(/fonts/BebasNeue-Regular.ttf) format("truetype");
  font-display: swap;
}
:root {
  --midnight: #0b1426;
  --deep: #050914;
  --amber: #d9953a;
  --cream: #efe3c8;
  --smoke: #8e97ad;
  --poster: "Bebas Neue", "Arial Narrow", sans-serif;
  --body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, "Roboto Mono", monospace;
  color-scheme: dark;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; } /* or a class's own display (.btn, .own) would show it anyway */
html, body { margin: 0; min-height: 100%; }
body {
  background: var(--deep);
  color: var(--cream);
  font: 17px/1.45 var(--body);
  -webkit-font-smoothing: antialiased;
  text-align: center;
  padding: 0 16px calc(24px + env(safe-area-inset-bottom));
  min-height: 100dvh;
}
main { max-width: 520px; margin: 0 auto; padding: 24px 0; }
.wordmark { font: 400 clamp(44px, 14vw, 72px)/1 var(--poster); letter-spacing: .08em; margin: 8px 0 4px; }
.tag { font: 400 18px/1 var(--poster); letter-spacing: .2em; color: var(--amber); margin: 0 0 32px; }
.checks { list-style: none; padding: 0; margin: 0 auto; text-align: left; display: inline-block; }
.checks li { padding: 6px 0; }
.checks li::before { content: "·"; color: var(--smoke); margin-right: 10px; }
.checks li.ok::before { content: "✓"; color: var(--amber); }
.checks li.bad::before { content: "✕"; color: var(--cream); }
.small { color: var(--smoke); font-size: 14px; }
code { font-family: var(--mono); font-size: .9em; }

/* ---- The setup page: a desk tool, Mac first, works on a phone */
body.setup main { max-width: 640px; text-align: left; padding-bottom: 120px; }
body.setup .wordmark, body.setup .tag { text-align: center; }
.locked { text-align: center; }
.takings .amount { font-size: 20px; margin: 0 0 10px; }
.panel { border: 1px solid rgb(239 227 200 / .14); border-radius: 6px; padding: 18px 18px 8px; margin: 0 0 16px; background: rgb(11 20 38 / .6); }
.panel h2 { font: 400 26px/1 var(--poster); letter-spacing: .1em; color: var(--amber); margin: 0 0 12px; }
.panel label, .panel .label { display: block; margin: 0 0 14px; }
.panel .label { margin-bottom: 6px; color: var(--smoke); font-size: 15px; }
.hint { color: var(--smoke); font-size: 15px; margin: -4px 0 14px; }
.panel input:not([type=checkbox]):not([type=radio]), .panel select, .panel textarea {
  display: block; width: 100%; margin-top: 6px; padding: 10px 12px;
  font: inherit; color: var(--cream); background: var(--deep);
  border: 1px solid rgb(239 227 200 / .25); border-radius: 4px;
}
.panel input:focus, .panel select:focus, .panel textarea:focus { outline: 2px solid var(--amber); outline-offset: 1px; border-color: transparent; }
.sats { display: flex; align-items: center; gap: 10px; margin-top: 6px; color: var(--smoke); }
.sats input { width: 7.5em !important; margin-top: 0 !important; display: inline-block !important; }
.choice { display: flex !important; gap: 12px; align-items: flex-start; cursor: pointer; }
.choice input { accent-color: var(--amber); width: 20px; height: 20px; margin: 2px 0 0; flex: none; }
.choice.inline { display: inline-flex !important; margin-right: 18px; align-items: center; }
.choice.inline input { margin: 0; }
.indent { margin-left: 32px !important; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
.row input, .row select { flex: 1 1 12em; margin-top: 0 !important; }
.preview { margin: 4px 0 14px; }
.site-host { white-space: nowrap; }
.sats input[data-path="page"] { width: auto !important; flex: 1; }
.share-link { font-size: 20px; margin: 0 0 14px; word-break: break-all; }
.share-link a { color: var(--cream); }
.qr { display: block; border-radius: 4px; margin: 4px 0 14px; }
.photo-preview { display: block; width: 100%; max-height: 220px; object-fit: cover; border-radius: 4px; margin: 0 0 14px; filter: brightness(.6); }
.btn {
  display: inline-block; font: 400 20px/1 var(--poster); letter-spacing: .12em; text-transform: uppercase;
  color: var(--cream); background: transparent; border: 1px solid var(--cream); border-radius: 3px;
  padding: 10px 16px 8px; cursor: pointer; text-decoration: none;
}
.btn.quiet { border-color: rgb(239 227 200 / .35); color: var(--cream); } /* cream, not grey: venues are dark rooms */
.btn.primary { background: var(--amber); border-color: var(--amber); color: var(--deep); }
.btn:disabled { opacity: .4; cursor: default; }
.savebar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; gap: 16px; align-items: center; justify-content: center;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: rgb(5 9 20 / .94); border-top: 1px solid rgb(239 227 200 / .14);
}
.savebar p { margin: 0; flex: 0 1 480px; font-size: 15px; color: var(--smoke); }
.savebar p.ok { color: var(--cream); }
.savebar p.todo { color: var(--amber); }
.savebar p.bad { color: var(--cream); font-weight: 600; }

/* ---- Wallet */
.big { font: 400 clamp(64px, 22vw, 112px)/1 var(--poster); color: var(--amber); margin: 8px 0 4px; }
.big small { font-size: .35em; color: var(--cream); letter-spacing: .1em; }
.buttons { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px; margin: 20px 0; }
body.wallet .buttons { gap: 10px; }
body.wallet .buttons .btn { padding-left: 12px; padding-right: 12px; }
/* Cream, not grey: venues are dark rooms. */
.notes { text-align: left; color: var(--cream); font-size: 16px; padding-left: 1.2em; margin: 28px 0 0; }
.notes li + li { margin-top: 14px; }
.paste { margin: 0 0 18px; }
.paste textarea { margin: 0 0 10px; }
body.wallet textarea {
  width: 100%; font: 12px/1.4 var(--mono); color: var(--cream); background: var(--deep);
  border: 1px solid rgb(239 227 200 / .25); border-radius: 4px; padding: 10px; word-break: break-all;
}
.status { min-height: 1.5em; color: var(--cream); }

/* ---- The TEST banner: on every page while the show runs on the test mint (added by the server) */
.test-banner {
  margin: 0 -16px; padding: 6px 16px calc(5px);
  padding-top: calc(6px + env(safe-area-inset-top));
  font: 400 15px/1.2 var(--poster); letter-spacing: .22em; text-transform: uppercase;
  color: var(--deep); background: var(--amber); text-align: center;
}
body.board .test-banner { margin: 0; } /* the artist's pages have no body padding to cancel: it pushed them 16 px sideways */

/* ---- The viewer page */
/* The background photo: dimmed, with a little grain, behind everything. */
.backdrop { position: fixed; inset: 0; z-index: -1; pointer-events: none; background: var(--deep); }
.backdrop i { position: absolute; inset: 0; background: center / cover no-repeat; opacity: 0; transition: opacity 1.5s; filter: brightness(.85) saturate(.9); }
.backdrop i.on { opacity: 1; }
.backdrop::before { content: ""; position: absolute; inset: 0; z-index: 1; background: linear-gradient(rgb(5 9 20 / .05), rgb(5 9 20 / .3)); }
.backdrop::after {
  content: ""; position: absolute; inset: 0; z-index: 2; opacity: .16; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
body.viewer { background: transparent; }
/* Brighter photo (Tue 6: ~70% less dim): everything over it gets a dark backing or a shadow, to stay readable. */
body.viewer .wordmark, body.viewer .tag, body.viewer .about, body.viewer .status { text-shadow: 0 1px 3px rgb(5 9 20 / .9), 0 0 18px rgb(5 9 20 / .7); }
body.viewer .purse { background: rgb(5 9 20 / .72); border-color: rgb(239 227 200 / .14); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
body.viewer .money .btn, body.viewer .own .btn:not(.primary) { background: rgb(5 9 20 / .6); }
html:has(body.viewer) { background: var(--deep); }
.about { max-width: 34em; margin: -8px auto 16px; font-size: 16px; color: var(--cream); }
.optional { color: var(--smoke); font-size: 14px; }
.small-mark { font-size: clamp(36px, 11vw, 56px); margin-top: 16px; }
body.viewer .tag { margin-bottom: 18px; }
/* The player: give it a width of its own (its children are all positioned, so it has none otherwise). */
.player { position: relative; width: 100%; aspect-ratio: 1280 / 676; background: #000; border-radius: 4px; overflow: hidden; }
/* Phones: the picture runs edge to edge. */
@media (max-width: 600px) { body.viewer .player { width: auto; margin: 0 -16px; border-radius: 0; } }
/* Video shape, from the video itself (--ratio, client/viewer.js); upright kept within the screen's height. */
.player { aspect-ratio: var(--ratio, 16 / 9); }
body[data-shape="tall"] .player { width: min(100%, calc(78svh * var(--ratio))); margin: 0 auto; border-radius: 4px; }
.player video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .25s; }
.player video.on { opacity: 1; }
/* Before the set plays, the player is see-through: the photo (and the artist's face) shows, only the controls sit on it. */
body.viewer:not(.playing) .player { background: rgb(5 9 20 / .15); box-shadow: inset 0 0 0 1px rgb(239 227 200 / .14); }
body.viewer:not(.playing) .bar { background: none; }
.big-play {
  position: absolute; inset: 0; margin: auto; width: 76px; height: 76px; border-radius: 50%; padding: 0;
  display: grid; place-items: center; cursor: pointer;
  border: 2px solid var(--amber); background: rgb(5 9 20 / .55); color: var(--amber);
}
.big-play svg { width: 34px; height: 34px; fill: currentColor; margin-left: 4px; }
body.playing .big-play { display: none; }

/* Controls on the picture, like a video site's: play/stop and the meter left, full screen right. */
.bar {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; display: flex; align-items: center; gap: 8px;
  padding: 20px 6px 4px; background: linear-gradient(transparent, rgb(5 9 20 / .85));
}
/* Amber, not cream: the controls must be found in a dark room. */
.icon { width: 44px; height: 44px; flex: none; display: grid; place-items: center; padding: 0; border: 0; background: none; color: var(--amber); cursor: pointer; }
.icon:disabled { opacity: .4; cursor: default; }
.icon svg { width: 26px; height: 26px; fill: currentColor; }
#full svg { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.i-stop, body.playing .i-play, .i-exit, body.full .i-full { display: none; }
body.playing .i-stop, body.full .i-exit { display: block; }
/* Live, Stop is a pause: nothing more is charged, and play rejoins the show. */
.i-pause, body.live-video.playing .i-stop { display: none; }
body.live-video.playing .i-pause { display: block; }
.spacer { flex: 1; }
#ov-tip { display: none; flex: none; font-size: 17px; padding: 8px 12px 6px; background: rgb(5 9 20 / .6); }
body.full #ov-tip { display: inline-block; }

/* Below the picture: what just happened, then the money buttons, compact. */
body.viewer .status { margin: 12px 0 0; }
.money { gap: 10px; margin: 12px 0; }
.money .btn { font-size: 17px; letter-spacing: .08em; padding: 9px 10px 7px; }
/* The wallet, big and amber, above the money buttons. */
/* Quiet: a hairline and a faint fill, so the eye stays on the picture. */
.purse {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 12px; margin: 14px 0 4px;
  padding: 12px 14px 10px; border: 1px solid rgb(239 227 200 / .1); border-radius: 8px; background: rgb(239 227 200 / .03);
}
.purse-sum { flex: none; display: flex; flex-direction: column; align-items: flex-start; color: var(--cream); text-decoration: none; text-align: left; }
.purse-sum b { font: 400 40px/1 var(--poster); color: var(--amber); letter-spacing: .04em; }
.budget input { width: 7ch; padding: 2px 4px; font: inherit; color: var(--cream); background: transparent; border: 1px solid rgb(239 227 200 / .3); border-radius: 3px; }
.purse-meter {
  flex: 1 0 100%; display: flex; justify-content: space-between; gap: 12px; margin: 0; padding-top: 8px;
  border-top: 1px solid rgb(239 227 200 / .08); font-size: 14px; color: var(--cream); opacity: .85;
}
.purse-sum span { font-size: 14px; white-space: nowrap; }
.purse-actions .btn { white-space: nowrap; }
/* No test top-up (a real mint): Wallet takes the right side, a bigger target. */
.purse-actions.solo { align-self: stretch; }
.purse-actions.solo #wallet-page { flex: 1; display: grid; place-items: center; font-size: 22px; max-width: 220px; }
.purse-actions { flex: 1 1 0; min-width: 0; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.btn.quiet { font-size: 16px; padding: 7px 12px 5px; }
.own { display: flex; gap: 10px; justify-content: center; align-items: stretch; margin: 0 0 12px; }
.own .btn { white-space: nowrap; }
.own input {
  width: 6em; padding: 8px 10px; -moz-appearance: textfield; appearance: textfield; font: inherit; color: var(--cream); background: var(--deep);
  border: 1px solid rgb(239 227 200 / .25); border-radius: 4px; text-align: center;
}
.own input::-webkit-inner-spin-button, .own input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.own input:focus { outline: 2px solid var(--amber); outline-offset: 1px; border-color: transparent; }

/* Full screen (the button, or a phone turned sideways): the picture fills the screen, the tip joins the controls. */
body.viewer.full { padding: 0; overflow: hidden; }
body.viewer.full main { max-width: none; padding: 0; }
body.viewer.full .player { position: fixed; inset: 0; width: auto; margin: 0; border-radius: 0; aspect-ratio: auto; z-index: 2; }
body.viewer.full .player video { object-fit: contain; }
body.viewer.full .bar {
  padding: 28px max(10px, env(safe-area-inset-right)) calc(6px + env(safe-area-inset-bottom)) max(10px, env(safe-area-inset-left));
}
/* What just happened ("wallet's empty"), over the picture at the top. */
body.viewer.full .status {
  position: fixed; z-index: 3; top: calc(44px + env(safe-area-inset-top)); left: 0; right: 0; margin: 0 auto; width: fit-content;
  max-width: 80%; min-height: 0; padding: 6px 12px; border-radius: 4px; background: rgb(5 9 20 / .75);
}
body.viewer.full .status:empty { display: none; }
/* The TEST strip shrinks to a small corner tag, so it stops covering the picture. */
body.viewer.full .test-banner {
  position: fixed; z-index: 3; top: calc(8px + env(safe-area-inset-top)); left: calc(8px + env(safe-area-inset-left));
  margin: 0; padding: 4px 8px 3px; font-size: 12px; letter-spacing: .16em; border-radius: 3px; opacity: .9;
}

/* ---- The night (Thu 29 Oct): door, welcome, free drink, chat, stage lights, closing time. */
.masthead .when { margin: -10px 0 16px; font-size: 15px; color: var(--cream); }
.card { border: 1px solid rgb(239 227 200 / .14); border-radius: 8px; padding: 16px; background: rgb(5 9 20 / .78); text-align: left; margin: 0 0 14px; }
.card-title { font: 400 26px/1.05 var(--poster); letter-spacing: .06em; margin: 0; }
.card-title #ticket-price { color: var(--amber); }
.card .hint { margin: 4px 0 12px; font-size: 14px; color: var(--smoke); }
.btn.wide { display: block; width: 100%; margin: 0 0 8px; text-align: center; }
.youre-in { font: 400 44px/1 var(--poster); letter-spacing: .08em; color: var(--amber); margin: 0 0 12px; }
.welcome { position: relative; margin: 0 -16px 14px; }
.welcome img { display: block; width: 100%; height: 220px; object-fit: cover; }
.welcome figcaption { position: absolute; left: 0; right: 0; bottom: 0; padding: 36px 18px 12px; text-align: left; font-size: 15px; background: linear-gradient(transparent, rgb(5 9 20 / .92)); }
.welcome figcaption:empty { display: none; }
.drink { display: flex; gap: 14px; align-items: center; border-color: rgb(217 149 58 / .6); }
.drink img { flex: none; border-radius: 3px; background: var(--cream); }
.doors-sign { position: absolute; inset: 0; margin: 0; display: grid; place-items: center; font: 400 30px/1 var(--poster); letter-spacing: .14em; color: var(--cream); background: rgb(5 9 20 / .55); z-index: 1; }
body[data-as="room"][data-stage="doors"] .big-play, body[data-as="room"][data-stage="doors"] .bar { display: none; }
.soon { font: 400 13px/1 var(--poster); letter-spacing: .14em; padding: 3px 6px 2px; border: 1px solid rgb(239 227 200 / .4); border-radius: 3px; }

/* The chat: newest at the bottom, like a live stream's. */
.chat { text-align: left; margin: 12px 0 0; }
.feed { list-style: none; margin: 0; padding: 0; max-height: 260px; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; }
.feed li { font-size: 14px; line-height: 1.35; padding: 4px 8px; border-radius: 6px; overflow-wrap: anywhere; }
.feed .from { color: var(--smoke); font-weight: 600; }
.feed li.tipped { background: rgb(217 149 58 / .16); }
.feed .amt { font: 400 14px/1 var(--poster); letter-spacing: .1em; color: var(--deep); background: var(--amber); border-radius: 3px; padding: 3px 6px 2px; }
.say { display: flex; gap: 8px; margin: 8px 0 0; }
.say input { flex: 1; min-width: 0; padding: 9px 10px; font: 15px var(--body); color: var(--cream); background: var(--deep); border: 1px solid rgb(239 227 200 / .25); border-radius: 4px; }
.nostr { margin: 8px 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.nostr .btn { font-size: 14px; padding: 5px 8px 3px; }
.goal { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; font-size: 13px; margin: 0 0 8px; }
.goal #goal-sum { color: var(--amber); }
.goal i { grid-column: 1 / -1; height: 8px; border-radius: 4px; background: rgb(239 227 200 / .12); overflow: hidden; }
.goal b { display: block; height: 100%; width: 0; background: var(--amber); transition: width .6s; }
#card-tip { font-size: 15px; }

/* In the room, once the set plays: the phone is the stage. Picture fills the screen upright (Insta Live, TikTok);
   the chat rises on the right from the bottom, see-through, just above the message box and the money. One column
   stacked at the bottom, so nothing floats in between and nothing covers the play button. */
body.immersive .masthead, body.immersive .nostr { display: none; }
body.immersive main { position: fixed; inset: 0; max-width: none; padding: 0 12px 10px; display: flex; flex-direction: column; justify-content: flex-end; pointer-events: none; }
body.immersive main > * { pointer-events: auto; }
body.immersive .player { position: fixed; inset: 0; width: auto; margin: 0; aspect-ratio: auto; border-radius: 0; z-index: 0; }
body.immersive .player video { object-fit: cover; }
body.immersive.live-video .player video { object-fit: contain; object-position: center; }
body.immersive .player .bar { top: 30px; bottom: auto; background: none; }
body.immersive .chat { position: relative; z-index: 2; margin: 0; align-self: flex-end; width: min(100%, 420px); pointer-events: none; }
body.immersive .chat .say, body.immersive .chat .goal { pointer-events: auto; }
body.immersive .feed { max-height: 34vh; align-items: flex-end; text-align: right; -webkit-mask-image: linear-gradient(transparent, #000 30%); mask-image: linear-gradient(transparent, #000 30%); }
body.immersive .feed li { background: none; text-shadow: 0 1px 3px rgb(0 0 0 / .9); padding: 2px 4px; }
body.immersive .feed li.tipped { background: rgb(5 9 20 / .45); }
body.immersive .say input { background: rgb(5 9 20 / .55); }
body.immersive .bottom { position: relative; z-index: 2; margin: 6px -12px -10px; padding: 18px 12px 10px; background: linear-gradient(transparent, rgb(5 9 20 / .92) 35%); }
body.immersive .money { margin: 4px 0; }
body.immersive .status { position: fixed; top: 60px; left: 0; right: 0; z-index: 2; }
body.immersive .purse { margin: 4px 0 0; padding: 6px 10px; }
body.immersive .purse-sum b { font-size: 26px; }
body.immersive .purse-meter { display: none; }
.back-link { display: inline-block; margin: 12px 0 0; font-size: 15px; color: var(--cream); text-decoration: none; opacity: .85; }
.back-link:hover { color: var(--amber); }
body.viewer:not(.immersive) main { position: relative; }
.back-row { margin: 0 0 8px; text-align: left; }

/* At home: the same full-picture view, with the title top left and the ticket above the money. */
body.immersive[data-as="home"] .masthead { display: block; position: fixed; top: 84px; left: 16px; text-align: left; z-index: 2; pointer-events: none; }
body.immersive[data-as="home"] .masthead .wordmark { font-size: 36px; margin: 0; text-shadow: 0 2px 10px rgb(5 9 20 / .8); }
body.immersive[data-as="home"] .masthead .tag { margin: 4px 0 0; text-align: left; }
body.immersive[data-as="home"] .when { margin: 4px 0 0; text-shadow: 0 1px 4px rgb(5 9 20 / .9); }
body.immersive[data-as="home"] .door { position: relative; z-index: 2; align-self: flex-start; width: min(100%, 420px); margin: 0 0 8px; }
body.immersive[data-as="home"] .doors-sign { background: rgb(5 9 20 / .35); }
body.immersive .back-link { position: fixed; top: 42px; left: 64px; z-index: 3; }

/* Stage lights: three, one by one, then they fade and the set is there. */
.lights { position: fixed; inset: 0; z-index: 9; background: #000; display: flex; justify-content: center; align-items: flex-start; gap: 18%; padding-top: 12%; }
.lights i { width: 46px; height: 46px; border-radius: 50%; background: #2a2010; box-shadow: none; }
.lights.go i { animation: lamp .4s ease-out forwards; }
.lights.go i:nth-child(2) { animation-delay: .7s; }
.lights.go i:nth-child(3) { animation-delay: 1.4s; }
.lights.go { animation: lights-out .8s 2.6s ease-in forwards; }
@keyframes lamp { to { background: #ffd27a; box-shadow: 0 0 40px 18px rgb(255 190 90 / .55), 0 260px 160px -40px rgb(255 190 90 / .18); } }
@keyframes lights-out { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .lights.go, .lights.go i { animation-duration: .01s; animation-delay: 0s; } }

/* Closing time. */
.closing { position: fixed; inset: 0; z-index: 5; display: flex; align-items: flex-end; text-align: center; }
.closing img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: brightness(.5); }
.closing div { position: relative; width: 100%; padding: 0 24px 48px; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.cheers { font: 400 72px/.9 var(--poster); color: var(--amber); margin: 0; letter-spacing: .04em; }
.zero { font: 400 24px/1 var(--poster); letter-spacing: .12em; margin: 0; padding: 8px 14px 6px; border: 1px solid var(--cream); border-radius: 3px; background: rgb(5 9 20 / .6); }

/* ---- The bar: its drinks, and the pint (from the hackathon's Pint Signal). */
.drinks { list-style: none; padding: 0; margin: 4px 0 12px; display: flex; flex-direction: column; gap: 6px; }
.drinks li { display: flex; justify-content: space-between; align-items: center; gap: 10px; font-size: 15px; }
.bar textarea { width: 100%; font: 12px/1.4 var(--mono); color: var(--cream); background: var(--deep); border: 1px solid rgb(239 227 200 / .25); border-radius: 4px; padding: 8px; word-break: break-all; }
.pint-screen { position: fixed; inset: 0; z-index: 10; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; text-align: center; padding: 16px; }
.pint-screen p { margin: 0; }
#pint-line { font: 400 44px/1 var(--poster); letter-spacing: .06em; color: var(--amber); }
.pint-screen .pint { width: min(52vw, 40vh, 240px); height: auto; overflow: visible; }
.pint-screen .fill { animation: pour 2.6s cubic-bezier(.3,.7,.4,1) forwards; transform: translateY(250px); }
.pint-screen .bubbles circle { animation: rise 2.2s linear infinite; }
.pint-screen .head { transform-origin: 100px 48px; transform: scaleY(0); animation: head .5s 2.4s ease-out forwards; }
.pint-screen.again .fill, .pint-screen.again .head { animation: none; transform: none; } /* already full: it was poured */
.pint-screen .ipa { font: 400 52px var(--poster); fill: none; stroke: #1a0f00; stroke-width: 1.6; letter-spacing: 4px; }
.pint-screen .ipa-small { font: 600 8.5px var(--body); fill: #1a0f00; letter-spacing: .6px; }
@keyframes pour { to { transform: translateY(0); } }
@keyframes rise { to { transform: translateY(-200px); opacity: 0; } }
@keyframes head { to { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) { .pint-screen .fill, .pint-screen .head { animation: none; transform: none; } }

/* ---- The setup page, desktop first (Thu 29 Oct): two columns of panels, saved as you type. */
body.setup.wide main { max-width: 1180px; padding-top: 20px; }
.setup-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px 24px; margin: 0 0 18px; }
.setup-title { font: 400 52px/1 var(--poster); letter-spacing: .06em; margin: 0; text-align: left; }
.setup-head .hint { margin: 6px 0 0; }
.who { display: flex; border: 1px solid rgb(239 227 200 / .35); border-radius: 4px; overflow: hidden; }
.who button { font: 400 18px/1 var(--poster); letter-spacing: .12em; padding: 10px 14px 8px; background: transparent; color: var(--cream); border: 0; border-left: 1px solid rgb(239 227 200 / .35); }
.who button:first-child { border-left: 0; }
.who button.on { background: var(--amber); color: var(--deep); }
.who button:disabled { color: var(--smoke); cursor: default; }
.panels { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; }
@media (max-width: 820px) { .panels { grid-template-columns: minmax(0, 1fr); } }
.panel h2 .works, .panel h2 .soon, .panel label .soon { vertical-align: middle; }
.works { font: 400 13px/1 var(--poster); letter-spacing: .14em; padding: 4px 7px 3px; border-radius: 3px; color: var(--deep); background: var(--amber); }
.two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 12px; }
.three { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 12px; }
.goal-row { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 0 12px; }
.split { border: 1px dashed rgb(217 149 58 / .6); border-radius: 4px; padding: 10px 12px; font-size: 15px; margin: 4px 0 14px; }
.split:empty { display: none; }
.poster-row { display: flex; flex-wrap: wrap; gap: 16px; align-items: flex-start; }
.poster-row > div { flex: 1 1 260px; }
.poster-row .qr { margin: 0; background: var(--cream); }
.panel input.inline-sats { display: inline-block !important; width: 3.6em !important; box-sizing: border-box; margin: 0 4px !important; padding: 4px 6px !important; }
.panel input:disabled { opacity: .55; }
body.viewer .money .btn.primary { background: var(--amber); color: var(--deep); }
.signin { max-width: 560px; margin: 24px auto; text-align: left; }
.signin input { display: block; width: 100%; padding: 10px 12px; font: 15px var(--body); color: var(--cream); background: var(--deep); border: 1px solid rgb(239 227 200 / .25); border-radius: 4px; }

/* The setup page's phone: the real show page beside the form, on screens wide enough for both. */
body.setup.wide main { max-width: 1600px; }
.setup-split { display: flex; gap: 24px; align-items: flex-start; }
.setup-split > form { flex: 1; min-width: 0; }
.preview-phone { flex: none; width: 390px; position: sticky; top: 16px; }
.preview-phone .label { text-align: center; }
.phone-frame { width: 390px; height: 780px; box-sizing: border-box; border: 10px solid #1b2131; border-radius: 48px; overflow: hidden; background: var(--deep); box-shadow: 0 30px 80px rgb(0 0 0 / .55); }
.phone-frame iframe { width: 100%; height: 100%; border: 0; display: block; }
@media (max-width: 1500px) { .setup-split .panels { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 860px) { .preview-phone { display: none; } }
.door-wallet { margin: -4px 0 12px; font-size: 16px; }
.door-wallet b { font: 400 24px/1 var(--poster); color: var(--amber); letter-spacing: .04em; }

/* The date line: in the poster face, like the rest of the brand, small enough to leave the photo alone. */
.when { font: 400 17px/1.2 var(--poster); letter-spacing: .14em; text-transform: uppercase; color: var(--cream); margin: 2px 0 14px; }
/* The wallet: what it is first, then how much. */
.purse-sum { gap: 2px; }
.purse-sum span:first-child { font: 400 15px/1 var(--poster); letter-spacing: .16em; text-transform: uppercase; }

/* Watching at home on a wide screen: a video site's page. The picture top left, the title under it, the ticket and
   the money below; the live chat in its own column on the right, full height. */
@media (min-width: 900px) {
  body[data-as="home"] main { max-width: 1320px; display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 14px 20px; align-items: start; text-align: left; padding-top: 12px; }
  body[data-as="home"] .back-link { grid-column: 1 / -1; order: 0; margin: 0; }
  body[data-as="home"] .player { grid-column: 1; order: 1; border-radius: 8px; }
  body[data-as="home"] .masthead { grid-column: 1; order: 2; }
  body[data-as="home"] .masthead .wordmark { font-size: 30px; margin: 0; text-align: left; }
  body[data-as="home"] .masthead .tag { text-align: left; margin: 4px 0 0; font-size: 20px; }
  body[data-as="home"] .when { grid-column: 1; order: 2; text-align: left; margin: -8px 0 0; }
  body[data-as="home"] .door { grid-column: 1; order: 3; margin: 0; }
  body[data-as="home"] .status { grid-column: 1; order: 4; margin: 0; }
  body[data-as="home"] .bottom { grid-column: 1; order: 5; }
  body[data-as="home"] .bottom .money { justify-content: flex-start; }
  body[data-as="home"] .chat { grid-column: 2; grid-row: 2 / span 5; margin: 0; padding: 12px; border: 1px solid rgb(239 227 200 / .14); border-radius: 8px; background: rgb(5 9 20 / .78); display: flex; flex-direction: column; min-height: 520px; }
  body[data-as="home"] .feed { flex: 1; max-height: 560px; }
}

/* The setup page's top right: the role (Artist; the others coming soon) and Doors open, the next step. */
.head-actions { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 16px; }
.who-wrap { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.coming { margin: 0; font-size: 13px; color: var(--smoke); }
.who button:disabled { color: rgb(142 151 173 / .55); background: rgb(239 227 200 / .03); }
.btn.doors { font-size: 22px; padding: 12px 20px 10px; }
/* The poster, standing under the phone. */
.preview-phone .panel { margin-top: 16px; }
.poster-col { display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center; }
.poster-col .qr { margin: 0; background: var(--cream); }
.poster-col .row { justify-content: center; }
.poster-col .share-link { font-size: 15px; margin: 0 0 10px; }

/* The room's phone before the set: the photo and the drink at the top, the goal and the tips at the very bottom,
   so the drink's QR gets the room. No wallet buttons: test sats arrive by themselves, and the ticket box says so. */
body.viewer[data-as="room"]:not(.immersive) main { min-height: calc(100dvh - 40px); display: flex; flex-direction: column; padding-bottom: 8px; }
body.viewer[data-as="room"]:not(.immersive) .chat { margin-top: auto; }
body.viewer[data-as="room"]:not(.immersive) .door ~ .status:empty { display: none; }
body[data-as="room"][data-stage="doors"] .feed, body[data-as="room"][data-stage="doors"] .say, body[data-as="room"][data-stage="doors"] .nostr { display: none; }
body[data-as="room"] .purse-actions, body[data-as="room"] .purse-meter { display: none; }
body[data-as="room"] .purse { justify-content: center; padding: 6px 10px; margin: 4px 0 0; border: 0; background: none; }
body[data-as="room"] .purse-sum { flex-direction: row; align-items: baseline; gap: 6px; }
body[data-as="room"] .purse-sum b { font-size: 22px; }
body[data-as="room"]:not(.immersive) .bottom:has(#money[hidden]) .purse { display: none; } /* at the door, the ticket box shows the wallet */
.drink { flex-direction: column; text-align: center; }
.drink img { width: 200px; height: 200px; }
.linkish { background: none; border: 0; padding: 0; margin-left: 6px; font: inherit; font-size: 14px; color: var(--amber); text-decoration: underline; cursor: pointer; }
body[data-as="room"] .welcome img { height: 150px; }
.drink img { width: 170px; height: 170px; }

/* The room's phone at the door: the artist's face in the top half (the photo behind), the date and the ticket below. */
body.viewer.at-door .when { margin-top: auto; text-shadow: 0 1px 4px rgb(5 9 20 / .9); }
body.viewer.at-door .door { margin-bottom: 0; }
@media (min-width: 900px) { body.framed[data-as="home"] .chat { grid-row: 1 / span 5; } }

/* ---- Watching at home inside page 2 (board 2): black, the video and its title left, the live chat right. */
.live-badge { position: absolute; top: 12px; left: 12px; z-index: 2; font: 400 15px/1 var(--poster); letter-spacing: .14em; color: #fff; background: #c0392b; padding: 5px 8px 4px; border-radius: 3px; }
/* The live light: glows while the artist's stream comes in. */
.live-badge.on-air { box-shadow: 0 0 10px 2px rgb(231 76 60 / .75); animation: on-air 2s ease-in-out infinite; }
@keyframes on-air { 50% { box-shadow: 0 0 3px 0 rgb(231 76 60 / .4); } }
@media (prefers-reduced-motion: reduce) { .live-badge.on-air { animation: none; } }
.chat-head, .say-buttons #say-tip, #whole { display: none; }
body[data-as="home"] .chat-head { display: flex; justify-content: space-between; align-items: center; margin: -12px -12px 8px; padding: 12px 14px; border-bottom: 1px solid rgb(239 227 200 / .14); font: 400 22px/1 var(--poster); letter-spacing: .12em; }
body[data-as="home"] #whole:not([hidden]) { display: inline-block; }
body[data-as="home"] .say { flex-wrap: wrap; }
body[data-as="home"] .say input { flex: 1 1 100%; }
body[data-as="home"] .say-buttons { display: flex; gap: 8px; flex: 1 1 100%; }
body[data-as="home"] .say-buttons .btn { flex: 1; font-size: 17px; }
body[data-as="home"] .say-buttons #say-tip { display: inline-block; }
body[data-as="home"] > main > .bottom .goal, body[data-as="home"] .bottom .goal { padding: 14px; border: 1px solid rgb(239 227 200 / .14); border-radius: 6px; margin: 14px 0 0; font-size: 15px; }
body.framed[data-as="home"] { background: #050914; padding: 0 16px; }
body.framed[data-as="home"] .backdrop { display: none; }
body.framed[data-as="home"] main { max-width: none; padding-top: 16px; }
body.framed[data-as="home"] .masthead .wordmark { display: none; }
body.framed[data-as="home"] .masthead .tag { font: 600 22px/1.25 var(--body); letter-spacing: 0; text-transform: none; color: var(--cream); margin: 0; }
body.framed[data-as="home"] .when { font: 15px/1.4 var(--body); letter-spacing: 0; text-transform: none; color: var(--smoke); margin: 2px 0 0; }
body.framed[data-as="home"] .door, body.framed[data-as="home"] .purse, body.framed[data-as="home"] .nostr .soon { }
body.framed[data-as="home"] .door, body.framed[data-as="home"] .purse { display: none; }
@media (min-width: 900px) {
  body.framed[data-as="home"] main { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
  body.framed[data-as="home"] .chat { min-height: 0; max-height: 640px; }
}
@media (min-width: 900px) { body.framed[data-as="home"] .chat { min-height: 520px; } body.framed[data-as="home"] .feed { min-height: 300px; } }
body.framed[data-as="home"] .status:empty { display: none; }
/* Inside the room at doors: one picture (the artist's welcome), on black. */
body.inside-doors .backdrop { display: none; }
body.inside-doors { background: var(--deep); }
/* The room's phone: the clip is landscape, so the upright crop shifts right of centre, where Longy stands. */
body.immersive .player video { object-position: 62% 30%; }
body.framed.takings { padding-top: 0; }
body.framed.takings .wordmark, body.framed.takings .tag + .locked ~ * .btn.quiet[href="/setup.html"], body.framed.takings p:has(> a[href="/setup.html"]) { display: none; }
body.framed.takings .tag { margin: 12px 0 14px; font-size: 22px; }
body.framed.takings main { padding-top: 0; }

/* Mute and volume on the picture. Phones show mute only: their own buttons set the level. */
.i-muted, body.muted .i-sound { display: none; }
body.muted .i-muted { display: block; }
#vol { width: 90px; accent-color: var(--amber); }
@media (max-width: 600px) { #vol { display: none; } }
body.immersive #vol { display: none; }
/* The phone's status line sat over the play/stop button at the top: lower it, and let taps through. */
body.immersive .status { top: 84px; pointer-events: none; }
body.immersive .player .bar { z-index: 3; }
/* The upright crop: show more of the left of the clip. */
body.immersive .player video { object-position: 25% 30%; }

/* In the room at doors: the artist's photo fills the phone between the date and the tips (it shares the space with
   the drink's QR when the free drink is on), so there's no empty gap. */
body.inside-doors .inside { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
body.inside-doors .welcome { flex: 1 1 240px; min-height: 200px; display: flex; margin-bottom: 12px; }
body.inside-doors .welcome img { flex: 1; width: 100%; height: auto; min-height: 0; object-fit: cover; object-position: 30% 30%; }
body.inside-doors .chat { margin-top: 0; }
/* Small wins (29 Oct): tags sit on their line; the live chat's head aligns; buttons show where focus is. */
.soon, .works { vertical-align: 2px; }
.btn:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }
.btn:not(:disabled):hover { filter: brightness(1.1); }
/* The phone shows the card button once, by the tips; the Nostr line stays on one line. */
body[data-as="room"] #card { display: none; }
.nostr { flex-wrap: nowrap; white-space: nowrap; font-size: 12px; }
.nostr .btn { font-size: 13px; padding: 4px 7px 2px; }

/* The gig page's top: our name small and gold, then the artist biggest, then the show title if there is one. */
.nutpub-line { font: 400 13px/1 var(--poster); letter-spacing: .2em; text-transform: uppercase; color: var(--amber); margin: 2px 0 10px; text-shadow: 0 1px 3px rgb(5 9 20 / .9); }
body.viewer .masthead .wordmark { margin: 0 0 4px; line-height: 1.05; }
body.viewer .masthead .tag { font: 400 24px/1.1 var(--poster); letter-spacing: .08em; color: var(--cream); margin: 0 0 4px; }
body.viewer .masthead { margin-bottom: 8px; }
body.framed[data-as="home"] .nutpub-line { display: none; }
@media (min-width: 900px) { body[data-as="home"] .nutpub-line { text-align: left; margin: 0 0 4px; } }
/* The ticket page on a phone: the words, the photo under them, and on the bottom of the photo only the ticket's buttons. */
body.viewer.at-door .when { margin-top: 0; }
body.viewer.at-door .nutpub-line { margin-top: -14px; } /* close to the top edge */
/* At the door the photo is plain, as on The show: no dimming, no gradient or grain, and its whole width. */
body.viewer.at-door .backdrop i { top: var(--door-top, 170px); background-size: 100% auto; background-position: center top; filter: none; }
body.viewer.at-door .backdrop::before, body.viewer.at-door .backdrop::after { display: none; }
body.viewer.at-door .door { margin-top: auto; margin-bottom: 0; padding: 0; border: 0; background: none; }
body.at-door #door-title, body.test-mint.at-door .door-wallet { display: none; }
body.at-door #door .hint { margin: 0; text-align: center; color: var(--cream); text-shadow: 0 1px 3px #000, 0 0 10px #000; }
body.at-door #door-home { background: rgb(5 9 20 / .72); }

/* The night's three pages on a phone: the header in two tidy rows, and the phone picture no wider than the screen. */
@media (max-width: 700px) {
  body.board .board-head { padding: 0 16px; gap: 0 10px; justify-content: space-between; }
  body.board .board-head .mark { font-size: 22px; padding: 10px 0 8px; }
  body.board .board-head .head-back, body.board .board-head .head-new { font-size: 14px; padding: 5px 8px 3px; }
  body.board .board-head .tabs { order: 3; width: 100%; flex-wrap: nowrap; gap: 0; justify-content: space-between; }
  body.board .board-head .tabs a { font-size: 17px; letter-spacing: .06em; padding: 8px 2px; white-space: nowrap; }
  body.board .page { padding: 20px 16px; }
  body.board aside { flex: 1 1 100%; width: 100%; min-width: 0; }
  body.board .phone-frame { width: min(390px, 100%); margin: 0 auto; }
  body.board aside .cap { letter-spacing: .1em; }
}

/* ---- Watching at home, on its own page: black, the picture, the show's line under it, the wallet card; the chat beside
   on a wide screen, under the line on a phone. The room's phone and The show's frame keep their own look. */
body.wallet-card { background: var(--deep); }
body.wallet-card .backdrop, body.wallet-card .money { display: none !important; }
.show-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 16px; margin: 10px 0 0; }
body.wallet-card .show-line .masthead { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; }
body.wallet-card .nutpub-line { display: none; }
body.wallet-card .masthead .wordmark { font-size: 32px; margin: 0; text-align: left; }
body.wallet-card .masthead .tag { font-size: 20px; margin: 0; text-align: left; }
body.wallet-card .when { margin: 0; text-align: left; }
/* The comment box: ₿ opens the tip's amount, £/$ waits for card payments, the arrow sends. */
.say-tools { display: none; }
body.wallet-card .say { position: relative; flex-wrap: nowrap; }
body.wallet-card .say input { flex: 1 1 auto; padding: 11px 132px 11px 12px; font-size: 16px; }
body.wallet-card .say-buttons { display: none; }
body.wallet-card .say-tools { position: absolute; right: 5px; top: 50%; transform: translateY(-50%); display: flex; gap: 4px; }
.coin { min-width: 36px; height: 32px; padding: 0 7px; font: 600 16px/1 var(--body); color: var(--amber); background: rgb(217 149 58 / .12); border: 1px solid rgb(217 149 58 / .5); border-radius: 4px; cursor: pointer; }
.coin:disabled { font-size: 14px; color: var(--smoke); background: none; border-color: rgb(239 227 200 / .2); cursor: default; }
.coin.send { color: var(--deep); background: var(--amber); border-color: var(--amber); }
body.wallet-card .chat .own { margin: 8px 0 0; }
/* The wallet card. */
.stat { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.stat small { font: 400 13px/1.1 var(--poster); letter-spacing: .14em; text-transform: uppercase; color: var(--smoke); }
.stat small.fine { font: 13px/1.2 var(--body); letter-spacing: 0; text-transform: none; }
.stat b { font: 400 26px/1 var(--poster); letter-spacing: .04em; color: var(--cream); white-space: nowrap; }
.stat #spent { color: var(--amber); }
.budget.stat > span { font-size: 15px; white-space: nowrap; }
.budget.stat input { font-size: 15px; }
body.wallet-card .purse { display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "sum actions" "meter meter" "status status" "goal goal"; align-items: start; gap: 10px 20px; margin: 12px 0 0; background: rgb(11 20 38 / .7); }
body.wallet-card .purse-sum { grid-area: sum; }
body.wallet-card .purse-actions { grid-area: actions; flex-direction: row; justify-content: flex-end; }
body.wallet-card .purse-actions .btn { font-size: 14px; padding: 6px 10px 4px; }
body.wallet-card .purse-meter { grid-area: meter; display: flex; flex-wrap: wrap; justify-content: flex-start; gap: 10px 28px; opacity: 1; padding: 10px 0 0; border-top: 1px solid rgb(239 227 200 / .08); }
body.wallet-card .purse .status { grid-area: status; margin: 0; min-height: 0; font-size: 14px; text-shadow: none; }
body.wallet-card .purse .status:empty { display: none; }
body.wallet-card .bottom .purse .goal { grid-area: goal; margin: 0; padding: 0; border: 0; font-size: 15px; background: none; }
body.wallet-card .purse { text-align: left; }
body.wallet-card .chat { margin: 12px 0 0; padding: 12px; border: 1px solid rgb(239 227 200 / .14); border-radius: 8px; background: rgb(11 20 38 / .7); }
@media (min-width: 900px) {
  /* The whole page in one window: the picture takes what the line and the wallet card leave, the chat the whole height. */
  body.wallet-card main { box-sizing: border-box; max-width: none; height: calc(100dvh - 30px); min-height: 600px; grid-template-columns: minmax(0, 1fr) 400px; grid-template-rows: minmax(200px, 1fr) auto auto; gap: 0 24px; padding: 16px clamp(0px, 6vw - 16px, 96px); }
  body.wallet-card:not(.full) .player { grid-column: 1; grid-row: 1; width: auto; height: 100%; max-width: 100%; min-height: 0; justify-self: start; }
  body.wallet-card .show-line { grid-column: 1; grid-row: 2; }
  body.wallet-card .bottom { grid-column: 1; grid-row: 3; min-width: 0; }
  body.wallet-card .chat { grid-column: 2; grid-row: 1 / span 3; align-self: stretch; min-height: 0; margin: 0; }
  body.wallet-card .feed { flex: 1 1 0; max-height: none; min-height: 0; }
  body.wallet-card .purse { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "sum meter" "actions status" "goal goal"; }
  body.wallet-card .purse-actions { justify-content: flex-start; }
  body.wallet-card .purse-meter { padding: 0; border: 0; }
}
/* A wide window: the stretch goal takes the card's right-hand side. */
@media (min-width: 1250px) {
  body.wallet-card .purse { grid-template-columns: auto minmax(0, 1.5fr) minmax(0, 1fr); grid-template-areas: "sum meter goal" "actions status goal"; }
  body.wallet-card .purse-meter { flex-wrap: nowrap; }
  body.wallet-card .bottom .purse .goal { align-self: center; padding-left: 20px; border-left: 1px solid rgb(239 227 200 / .08); }
}

/* ---- Session 8: home view fixes (Rajesh, 5 Nov evening). */
/* Once Play is pressed, and in full screen, the picture sits on black: the cover photo goes (it showed at the edges,
   and above and below the picture in full screen). */
body.viewer.playing .player, body.viewer.full.playing .player { background: #000 !important; }
/* Bitcoin orange is ₿'s alone: the ₿ and its outline, nothing else on the page. Gold stays NutPub's. */
:root { --btc: #f7931a; }
.coin.btc { color: var(--btc); background: none; border-color: var(--btc); font-size: 18px; }
.coin.btc[aria-expanded="true"] { background: rgb(247 147 26 / .14); }
/* While ₿ is open the comment goes with the tip: the arrow waits. */
.coin.send:disabled { color: var(--smoke); background: none; border-color: rgb(239 227 200 / .2); }
/* Gutters like YouTube's (24 px from the screen's edge), and a wider chat. */
@media (min-width: 900px) {
  body.wallet-card main { padding: 16px 8px; grid-template-columns: minmax(0, 1fr) clamp(380px, 30vw, 470px); }
}
/* Chat rows as YouTube's: no blocks behind them; the gold amount is the only highlight. Larger, more so on a phone. */
body[data-as="home"] .feed { gap: 6px; }
body[data-as="home"] .feed li, body[data-as="home"] .feed li.tipped { background: none; padding: 3px 2px; font-size: 16px; line-height: 1.4; }
body[data-as="home"] .feed .amt { font-size: 15px; }
@media (max-width: 600px) { body[data-as="home"] .feed li, body[data-as="home"] .feed li.tipped { font-size: 17px; } }
/* The tip row lines up under the comment box: the amount from its left edge, Tip beside it, ✕ under the arrow. */
body.wallet-card .chat .own { justify-content: stretch; align-items: stretch; gap: 4px; padding-right: 5px; }
body.wallet-card .chat .own input { flex: 1 1 auto; width: auto; min-width: 0; text-align: left; padding: 9px 12px; font-size: 16px; }
body.wallet-card .chat .own #own-pay { flex: none; font-size: 17px; padding: 9px 14px 7px; }
body.wallet-card .chat .own #own-cancel { flex: none; width: 36px; padding: 0; font: 600 16px/1 var(--body); }
/* Stretch goals: one black track from nothing to the last goal, a small notch at each goal, gold filling along it. */
.goal { grid-template-columns: 1fr auto; grid-template-areas: "head sum" "track track" "list list"; align-items: baseline; }
.goal .goal-head { grid-area: head; font: 400 13px/1.1 var(--poster); letter-spacing: .14em; text-transform: uppercase; color: var(--smoke); }
.goal #goal-sum { grid-area: sum; display: inline; width: auto; height: auto; background: none; font: 400 15px/1 var(--poster); letter-spacing: .06em; color: var(--amber); }
.goal i.track { grid-area: track; position: relative; display: block; height: 8px; border-radius: 4px; overflow: visible; background: #000; box-shadow: inset 0 0 0 1px rgb(239 227 200 / .18); }
.goal i.track #goal-bar { display: block; height: 100%; width: 0; border-radius: 4px; background: var(--amber); transition: width .6s; }
.goal .notch { position: absolute; top: -3px; bottom: -3px; width: 2px; margin-left: -1px; background: rgb(239 227 200 / .7); text-decoration: none; }
.goal .goal-list { grid-area: list; min-width: 0; font-size: 14px; color: var(--smoke); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.goal .goal-list .met { color: var(--amber); }
/* The wallet card: "Wallet balance" (a figure, not a link), bigger buttons; the goal level with the balance, spaced
   like This set and the price, with more room. */
body.wallet-card .purse-sum { cursor: default; }
body.wallet-card .purse-actions .btn { font-size: 17px; padding: 9px 14px 7px; }
body.wallet-card .bottom .purse .goal { display: grid; grid-template-areas: "head head" "sum sum" "track track" "list list"; gap: 6px 0; align-self: start; }
body.wallet-card .bottom .purse .goal #goal-sum { font-size: 26px; letter-spacing: .04em; }
@media (min-width: 1250px) {
  body.wallet-card .purse { grid-template-columns: auto auto minmax(220px, 1fr); grid-template-areas: "sum meter goal" "actions status status"; column-gap: 28px; }
  body.wallet-card .bottom .purse .goal { align-self: start; padding-left: 0; border-left: 0; }
}

/* Full screen: the TEST strip across the top, The NutPub under it as on the home page; the bottom bar with ₿ and the
   goals' readout. Playing, the bars fade after a few seconds without the mouse, as on YouTube. */
.ov-mark, .ov-btc, .ov-goal, #ov-tip, body.full #ov-tip { display: none; }
body.viewer.full .test-banner { left: 0; right: 0; top: 0; margin: 0; padding: calc(5px + env(safe-area-inset-top)) 16px 4px; font-size: 13px; letter-spacing: .22em; border-radius: 0; opacity: 1; text-align: center; }
body.viewer.full .ov-mark { display: block; position: absolute; z-index: 2; left: 0; right: 0; top: calc(30px + env(safe-area-inset-top)); margin: 0; text-align: center; font: 400 28px/1 var(--poster); letter-spacing: .08em; text-transform: uppercase; color: var(--cream); text-shadow: 0 2px 10px rgb(5 9 20 / .8); pointer-events: none; }
body.viewer.full .ov-btc { display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 12px; }
body.viewer.full .ov-btc span { font: 400 17px/1 var(--poster); letter-spacing: .12em; text-transform: uppercase; }
body.viewer.full .ov-goal:not([hidden]) { display: inline-block; margin-right: 12px; font: 400 17px/1 var(--poster); letter-spacing: .1em; color: var(--amber); white-space: nowrap; }
body.viewer.full .player .own { position: absolute; z-index: 3; right: max(10px, env(safe-area-inset-right)); bottom: calc(64px + env(safe-area-inset-bottom)); margin: 0; padding: 8px; gap: 6px; border-radius: 6px; background: rgb(5 9 20 / .85); }
body.viewer.full .bar, body.viewer.full .test-banner, body.viewer.full .ov-mark { transition: opacity .4s; }
body.viewer.full.idle .bar, body.viewer.full.idle .test-banner, body.viewer.full.idle .ov-mark { opacity: 0; pointer-events: none; }
body.viewer.full.idle, body.viewer.full.idle .player { cursor: none; }
body.viewer.full .player .own input { width: 10em; }

/* Phones in full screen: no room for the goals' readout, so ₿ Tip and the exit button stay on the screen. */
@media (max-width: 699px) { body.viewer.full .ov-goal:not([hidden]) { display: none; } }
body.viewer.full .bar > * { flex-shrink: 0; }
body.viewer.full .bar .spacer { flex: 1 1 0; min-width: 0; }
/* The date and the times: bigger, but smaller than the artist's name. */
body.wallet-card .when { font-size: 22px; letter-spacing: .1em; }
@media (max-width: 699px) { body.wallet-card .when { font-size: 18px; } }

/* Nothing shows until the first render has chosen the page: no flash of Doors before the ticket. */
body.viewer:not(.ready) main, body.viewer:not(.ready) .closing { visibility: hidden; }

/* Batch 2 (6 Nov): the wallet card. The balance fills the top of its column and the two wallet buttons the bottom,
   big, as they're the ones used most; the stats sit right next to it; the goals take the rest, top to bottom. */
.goal i.track #goal-bar { position: relative; }
/* Where the tips are now: a cream mark at the end of the gold. */
.goal i.track #goal-bar::after { content: ""; position: absolute; right: -2px; top: -5px; bottom: -5px; width: 4px; border-radius: 2px; background: var(--cream); box-shadow: 0 0 6px rgb(5 9 20 / .8); }
.goal .goal-thanks { grid-area: track; margin: 2px 0 0; font: 400 24px/1.15 var(--poster); letter-spacing: .04em; color: var(--amber); }
body.wallet-card .free-note span { display: block; margin-top: 4px; font-size: 16px; color: var(--cream); max-width: 22em; }
@media (min-width: 900px) {
  body.wallet-card .purse { grid-template-columns: clamp(300px, 24vw, 380px) auto minmax(0, 1fr); grid-template-areas: "sum meter goal" "actions status goal"; column-gap: 32px; row-gap: 14px; align-items: stretch; }
  body.wallet-card .purse-sum b { font-size: 54px; }
  body.wallet-card .purse-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; align-self: end; }
  body.wallet-card .purse-actions .btn { display: grid; place-items: center; min-height: 58px; padding: 8px 10px 6px; font-size: 18px; white-space: normal; line-height: 1.1; text-align: center; }
  body.wallet-card .purse-meter { flex-direction: column; flex-wrap: nowrap; gap: 14px; align-self: start; }
  body.wallet-card .bottom .purse .goal { align-self: stretch; padding-left: 28px; border-left: 1px solid rgb(239 227 200 / .08); grid-template-rows: auto auto auto 1fr; }
  body.wallet-card .bottom .purse .goal #goal-sum { font-size: 34px; }
  body.wallet-card .goal i.track { height: 14px; margin: 6px 0; }
  body.wallet-card .goal .goal-list { font-size: 18px; white-space: normal; }
  body.wallet-card .goal .goal-thanks { font-size: 30px; }
}

/* Full screen: no The NutPub over the picture (the TEST strip stays). */
body.viewer.full .ov-mark { display: none; }
body.viewer.full .player { cursor: pointer; }

/* The wallet card, round 2 (6 Nov): what you've given sits beside the balance, the two buttons under both, and the
   goals take the rest of the card. What just happened sits on the show's line, from the right. */
body.wallet-card .show-line .status { margin: 0 0 0 auto; min-height: 0; font: 400 22px/1.2 var(--poster); letter-spacing: .1em; text-transform: uppercase; color: var(--cream); text-shadow: none; text-align: right; }
body.wallet-card .show-line .status:empty { display: none; }
@media (max-width: 699px) { body.wallet-card .show-line .status { font-size: 18px; margin: 0; text-align: left; } }
@media (min-width: 900px) {
  body.wallet-card .purse { grid-template-columns: auto auto minmax(0, 1fr); grid-template-areas: "sum meter goal" "actions actions goal"; }
  body.wallet-card .purse-meter { padding-top: 2px; }
  body.wallet-card .bottom .purse .goal { padding-left: 32px; }
}

/* 6 Nov, round 3: the card's labels all match "Wallet balance"; the goals in the page's own lettering; a microphone
   at each goal on the track, gold once it's met. */
body.wallet-card .stat small:not(.fine), body.wallet-card .goal .goal-head { font: 400 15px/1 var(--poster); letter-spacing: .16em; color: var(--cream); }
body.wallet-card .goal .goal-list { font-family: var(--poster); letter-spacing: .08em; text-transform: uppercase; }
.goal .notch.mic { top: 50%; bottom: auto; width: 26px; height: 26px; margin: 0; transform: translate(-50%, -50%); display: grid; place-items: center; border-radius: 50%; background: #000; box-shadow: 0 0 0 1px rgb(239 227 200 / .4); color: var(--cream); z-index: 1; }
.goal .notch.mic svg { width: 16px; height: 16px; fill: currentColor; }
.goal .notch.mic.met { background: var(--amber); color: #000; box-shadow: none; }
body.wallet-card .goal i.track { margin-right: 13px; margin-left: 2px; }
body.wallet-card .goal i.track { margin-top: 12px; margin-bottom: 12px; }
/* What you've given reads as large as the goal's figures. */
@media (min-width: 900px) { body.wallet-card .purse-meter .stat b { font-size: 34px; } }

/* Opening the wallet: words, not a giant number. */
#balance.opening { font: 400 20px/1.2 var(--poster); letter-spacing: .08em; color: var(--smoke); white-space: normal; }
/* All goals met: the tips can keep coming. */
.goal .goal-more { grid-area: more; justify-self: start; margin-top: 6px; height: 40px; padding: 0 16px; font: 400 17px/1 var(--poster); letter-spacing: .1em; text-transform: uppercase; }
.goal:has(.goal-more:not([hidden])) { row-gap: 8px; }
.goal .goal-more:not([hidden]) { display: inline-flex; align-items: center; gap: 6px; }
/* What just happened, in gold so it stands out from the cream line; it fades after 10 s. */
body.wallet-card .show-line .status { color: var(--amber); transition: opacity .8s; }
body.wallet-card .show-line .status.fade { opacity: 0; }
body.wallet-card .bottom .purse .goal { grid-template-areas: "head head" "sum sum" "track track" "list list" "more more"; }

/* All goals met: the list folds away; two big buttons, ₿ and a card tip (Stripe's violet, calmed to sit with our
   midnight and gold; it does nothing yet, as with "£ with card"). */
.goal .goal-more-row { grid-area: more; display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
.goal .goal-more-row[hidden] { display: none; }
.goal .goal-more-row .goal-more { margin: 0; height: 52px; padding: 0 22px; font-size: 20px; }
.goal .goal-card { height: 52px; padding: 0 22px; border: 1px solid #7d78c8; border-radius: 6px; background: rgb(125 120 200 / .16); color: #c9c6f0; font: 400 20px/1 var(--poster); letter-spacing: .1em; text-transform: uppercase; cursor: default; }
/* A narrow window on a computer: as on a phone, the picture edge to edge and the cards 16 px in. */
@media (max-width: 899px) {
  body.wallet-card main { max-width: none; padding: 0 0 24px; } /* the body already keeps 16 px each side */
  body.wallet-card:not(.full) .player { width: auto; margin: 0 -16px; border-radius: 0; }
}

/* No up/down arrows in number boxes, anywhere (Rajesh, 7 Nov). */
input[type=number] { -moz-appearance: textfield; appearance: textfield; }
input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

/* Comments off (setup): the chat keeps the goals and the tips, without a box for words. */
body.no-comments #say-text, body.no-comments #say-send, body.no-comments #say-free { display: none !important; }

/* ---- ₿ / £ / $ for the whole page: faint drawn flags (emoji flags show as letters on Windows); orange is ₿'s alone. */
.unit { display: inline-flex; gap: 7px; flex: none; }
.unit button { position: relative; isolation: isolate; overflow: hidden; width: 48px; height: 38px; padding: 0; font: 700 20px/1 var(--body); color: var(--cream); text-shadow: 0 1px 3px #000; background: none; border: 1px solid rgb(239 227 200 / .45); border-radius: 5px; cursor: pointer; }
.unit button::before { content: ""; position: absolute; inset: 0; z-index: -1; background: center / cover no-repeat; opacity: .6; }
.unit button[data-unit="gbp"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 40' preserveAspectRatio='xMidYMid slice'%3E%3Crect width='60' height='40' fill='%23012169'/%3E%3Cpath d='M0 0L60 40M60 0L0 40' stroke='%23fff' stroke-width='8'/%3E%3Cpath d='M0 0L60 40M60 0L0 40' stroke='%23C8102E' stroke-width='3'/%3E%3Cpath d='M30 0V40M0 20H60' stroke='%23fff' stroke-width='13'/%3E%3Cpath d='M30 0V40M0 20H60' stroke='%23C8102E' stroke-width='8'/%3E%3C/svg%3E"); }
.unit button[data-unit="usd"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 40' preserveAspectRatio='xMidYMid slice'%3E%3Crect width='60' height='40' fill='%23fff'/%3E%3Cpath d='M30 0V40' stroke='%23B31942' stroke-width='60' stroke-dasharray='3.08'/%3E%3Crect width='26' height='21.5' fill='%230A3161'/%3E%3Cpath d='M3 6H24M3 15H24' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-dasharray='0 5'/%3E%3C/svg%3E"); }
.unit button[data-unit="btc"] { color: var(--btc); border-color: rgb(247 147 26 / .55); text-shadow: none; }
.unit button[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--amber); border-color: transparent; }
.unit button[aria-pressed="true"]::before { opacity: 1; }
.unit button[data-unit="btc"][aria-pressed="true"] { color: var(--deep); background: var(--btc); box-shadow: 0 0 0 2px var(--btc); }
.unit button:disabled { opacity: .4; cursor: default; }
.goal .unit { grid-area: head; justify-self: end; align-self: center; }
/* The switch has the "Stretch goals" row to itself, so a long figure can wrap without running under it. */
body:not(.wallet-card) .goal, body.wallet-card .bottom .purse .goal { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "head unit" "sum sum" "track track" "list list" "more more"; }
body:not(.wallet-card) .goal .unit, body.wallet-card .bottom .purse .goal .unit { grid-area: unit; }
.goal .goal-head { align-self: center; }
body:not(.wallet-card) .goal #goal-sum { justify-self: start; }
/* A narrowed desktop window: three columns squeezed the goals to nothing; they take a full row under the wallet instead. */
@media (min-width: 900px) and (max-width: 1449px) {
  body.wallet-card .purse { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "sum meter" "actions status" "goal goal"; column-gap: 24px; }
  body.wallet-card .purse-meter { flex-wrap: wrap; }
  body.wallet-card .bottom .purse .goal { padding: 10px 0 0; border-left: 0; border-top: 1px solid rgb(239 227 200 / .08); }
}
/* Full screen on a phone, typing a tip: the box sits at the top of what the keyboard leaves. */
body.viewer.full.tip-typing .player .own { position: fixed; left: max(8px, env(safe-area-inset-left)); right: max(8px, env(safe-area-inset-right)); bottom: auto; margin-top: env(safe-area-inset-top); z-index: 9; justify-content: stretch; }
body.viewer.full.tip-typing .player .own input { flex: 1 1 auto; width: auto; min-width: 0; }
body.viewer.full.tip-typing .test-banner, body.viewer.full.tip-typing .player .bar { visibility: hidden; }
.purse-sum .unit { margin-top: 5px; }

/* ---- Your ticket: the receipt and the one thing to do with it. See-through over the photo in the room. */
.save-ticket { box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; gap: 14px; padding: 22px 20px; text-align: center; color: var(--cream); background: rgb(5 9 20 / .85); border: 1px solid rgb(217 149 58 / .55); border-radius: 12px; }
.save-ticket h2 { margin: 0; font: 400 30px/1.05 var(--poster); letter-spacing: .06em; }
.save-ticket .receipt { margin: 0; font-size: 17px; line-height: 1.5; }
.save-ticket .btn { width: 100%; padding: 16px 12px 14px; font-size: 22px; }
.welcome { position: relative; }
/* Bought ahead of the night: only the photo and the receipt; the card sits low so the photo's subject stays clear. */
body.confirmed .chat, body.confirmed .goal, body.confirmed #money, body.confirmed .purse, body.confirmed .own, body.confirmed #doors-sign, body.confirmed .player .bar, body.confirmed #big-play, body.confirmed .status { display: none !important; }
body.confirmed .welcome { position: relative; flex: 1 1 auto; display: block; margin: 0 -16px; height: calc(100svh - 260px); min-height: 440px; }
body.confirmed .welcome img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 30% 20%; }
.welcome .save-ticket { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); width: min(90%, 360px); }
body.wallet-card.confirmed main { grid-template-columns: minmax(0, 1fr); }
body.wallet-card.confirmed .bottom { display: flex; justify-content: center; }
body.wallet-card.confirmed .bottom > .save-ticket { width: min(100%, 420px); }
.bottom > .save-ticket { margin: 12px 0 0; }

/* Flags the shape of flags, 3:2. */
.unit button { width: 57px; }
/* The wallet card on a phone: the balance, its two buttons on one line, the flags on their own line above the goals,
   the two tip buttons side by side. */
@media (max-width: 700px) {
  body.wallet-card .purse { grid-template-columns: minmax(0, 1fr); grid-template-areas: "sum" "actions" "meter" "status" "goal"; }
  body.wallet-card .purse-actions { flex-wrap: nowrap; }
  body.wallet-card .purse-actions .btn { flex: 1 1 0; min-width: 0; text-align: center; font-size: 15px; padding: 10px 4px 8px; }
  body.wallet-card .bottom .purse .goal { grid-template-columns: minmax(0, 1fr); grid-template-areas: "unit" "head" "sum" "track" "list" "more"; }
  body.wallet-card .bottom .purse .goal .unit { justify-self: start; margin-bottom: 8px; }
  .goal .goal-more-row { flex-wrap: nowrap; }
  .goal .goal-more-row > * { flex: 1 1 0; min-width: 0; height: 52px; padding: 0 6px; font-size: 17px; justify-content: center; white-space: nowrap; }
}

/* The currency switch: names only on the phone card, where the flags run the full width. */
.unit > span { display: inline-flex; }
.unit small { display: none; }
@media (max-width: 700px) {
  body.wallet-card .bottom .purse .goal .unit { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; justify-self: stretch; }
  body.wallet-card .goal .unit > span { display: grid; gap: 5px; }
  body.wallet-card .goal .unit small { display: block; font: 400 14px/1 var(--poster); letter-spacing: .14em; text-transform: uppercase; color: var(--smoke); }
  body.wallet-card .goal .unit button { width: 100%; height: auto; aspect-ratio: 3 / 2; font-size: 28px; }
}

/* Bitcoin tips in the chat are Bitcoin orange; card tips will get their own colour in the colour session. */
.feed .amt { background: var(--btc); }
/* Good news about sats: orange, with a slow shimmer. */
.status.shine { color: transparent; background: linear-gradient(100deg, var(--btc) 42%, #ffe2b8 50%, var(--btc) 58%) 0 0 / 250% 100%; -webkit-background-clip: text; background-clip: text; animation: shine 2.6s linear infinite; }
@keyframes shine { from { background-position: 125% 0; } to { background-position: -125% 0; } }
@media (prefers-reduced-motion: reduce) { .status.shine { color: var(--btc); background: none; animation: none; } }

/* The shimmer, past the show line's own colour. */
body.wallet-card .show-line .status.shine, .status.shine { color: transparent; background: linear-gradient(100deg, var(--btc) 35%, #fff 50%, var(--btc) 65%) 0 0 / 220% 100%; -webkit-background-clip: text; background-clip: text; animation: shine 1.5s linear infinite; }
@media (prefers-reduced-motion: reduce) { body.wallet-card .show-line .status.shine, .status.shine { color: var(--btc); background: none; animation: none; } }

/* The door's page: one big answer per scan. Look to be settled in the design sessions. */
.door-result { text-align: center; padding: 28px 16px; }
.door-big { font: 400 clamp(56px, 16vw, 88px)/1 var(--poster); margin: 0 0 8px; }
.door-result[data-state="in"] .door-big { color: #5fd38a; }
.door-result[data-state="already"] .door-big, .door-result[data-state="unknown"] .door-big, .door-result[data-state="online"] .door-big { color: #ff7a6b; }
