{"content_mode":"html","html":"<!doctype html>\n<html lang=\"en\" data-site-base=\"{{FYNESITE_SITE_BASE}}\" data-dreamlive-spotlight=\"v1\" data-dreamlive-reference-preview=\"v1\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n  <meta name=\"theme-color\" content=\"#6f285e\">\n  <meta name=\"description\" content=\"Meet today\u2019s Dreamland performers, explore their dance repertoire, and send an Oshi cheer.\">\n  <meta name=\"apple-itunes-app\" content=\"app-id=6791316371, app-argument=https://sites.fynesite.com/dreamland-la-habra/jukebox\">\n  <link rel=\"icon\" href=\"/api/image/proxy/websites/315d5891-4d1d-46d4-a321-026b53f6f229/assets/image/dreamland/brand/bff4e13a_dreamland-mark-31a924d6192b.png\" type=\"image/png\">\n  <title>DreamLIVE Jukebox \u2014 Dreamland Anime Cafe</title>\n  <style>\n    :root {\n      color-scheme: light;\n      --plum: #6f285e;\n      --plum-deep: #4a253f;\n      --cream: #fff9ef;\n      --paper: #fffdfa;\n      --pink: #e93698;\n      --pink-dark: #bd1f72;\n      --pink-soft: #ffd7e9;\n      --sky: #cfeff4;\n      --gold: #ffd45f;\n      --brown: #4b241f;\n      --muted: #80626f;\n      --line: #ead9df;\n      --shadow-pink: 7px 8px 0 var(--pink);\n      --shadow-gold: 7px 8px 0 var(--gold);\n      --radius: 28px;\n    }\n    * { box-sizing: border-box; }\n    html { background: #251721; scroll-behavior: smooth; }\n    body { margin: 0; color: var(--plum-deep); background: #251721; font-family: ui-rounded, \"SF Pro Rounded\", \"Avenir Next\", system-ui, sans-serif; }\n    button, input { font: inherit; }\n    button, a { -webkit-tap-highlight-color: transparent; }\n    button { color: inherit; }\n    a { color: inherit; text-decoration: none; }\n    img { display: block; max-width: 100%; }\n    h1, h2, h3, p { margin-top: 0; }\n    [hidden] { display: none !important; }\n    :focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }\n    .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }\n\n    .app-shell { width: min(100%, 1180px); min-height: 100svh; margin: 0 auto; overflow: hidden; background: var(--cream); box-shadow: 0 0 70px rgba(0,0,0,.35); }\n    .stage-hero { position: relative; overflow: hidden; padding: max(24px, env(safe-area-inset-top)) clamp(22px, 6vw, 76px) clamp(40px, 7vw, 74px); color: white; background: linear-gradient(145deg, #74275f, #5a214f 70%, #431c3e); }\n    .stage-hero::before { content: \"\"; position: absolute; inset: 0; opacity: .3; pointer-events: none; background: repeating-linear-gradient(90deg, transparent 0 67px, rgba(255,255,255,.12) 68px 69px), radial-gradient(ellipse at 70% 5%, rgba(255,255,255,.25), transparent 40%), radial-gradient(ellipse at -5% 55%, rgba(233,54,152,.45), transparent 28%); }\n    .stage-hero::after { content: \"\"; position: absolute; top: 0; right: -8%; width: 31%; height: 100%; opacity: .34; border-radius: 50% 0 0 50%; background: linear-gradient(90deg, transparent, #a52d7b); }\n    .hero-top, .hero-copy { position: relative; z-index: 1; }\n    .hero-top { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: clamp(36px, 8vw, 70px); }\n    .wordmark { width: min(360px, 68vw); height: auto; filter: drop-shadow(0 2px 0 rgba(56,20,46,.45)); }\n    .hero-actions { display: flex; flex: 0 0 auto; gap: 9px; }\n    .hero-action { align-items: center; display: inline-flex; justify-content: center; min-height: 40px; padding: 0 15px; border: 1px solid rgba(255,255,255,.28); border-radius: 999px; color: white; background: rgba(62,22,50,.34); font-size: 12px; font-weight: 900; white-space: nowrap; backdrop-filter: blur(8px); }\n    .hero-action[disabled] { cursor: default; opacity: .8; }\n    .hero-kicker, .section-kicker { display: block; color: #ffd8eb; font-size: 12px; font-weight: 950; letter-spacing: .18em; text-transform: uppercase; }\n    .hero-title { margin: 14px 0 0; max-width: 800px; font-family: \"Arial Black\", Impact, sans-serif; font-size: clamp(64px, 12vw, 132px); line-height: .78; letter-spacing: -.075em; text-transform: uppercase; text-shadow: 0 8px 0 rgba(55,17,43,.28); }\n    .hero-title span { color: var(--gold); display: inline-block; }\n    .hero-date { margin: 18px 0 0; color: #f5dce9; font-size: clamp(15px, 2vw, 20px); font-weight: 800; letter-spacing: .04em; }\n    .music-note { position: absolute; z-index: 2; top: 48%; right: clamp(24px, 7vw, 90px); color: var(--gold); font: 900 clamp(36px, 6vw, 70px)/1 Georgia, serif; transform: rotate(9deg); text-shadow: 4px 5px 0 rgba(55,17,43,.32); }\n    .ticker { overflow: hidden; height: 46px; border-top: 1px solid #f0b9d3; border-bottom: 1px solid #f0b9d3; background: #ffd8e8; }\n    .ticker-track { width: max-content; display: flex; align-items: center; height: 100%; color: var(--pink-dark); font-size: 10px; font-weight: 950; letter-spacing: .18em; white-space: nowrap; animation: ticker 24s linear infinite; }\n    .ticker-copy { flex: 0 0 auto; padding-right: 22px; }\n    @keyframes ticker { to { transform: translateX(-50%); } }\n\n    .content-section { position: relative; padding: clamp(42px, 7vw, 72px) clamp(20px, 6vw, 68px); }\n    .content-section::before { content: \"\"; position: absolute; inset: 0; opacity: .35; pointer-events: none; background-image: radial-gradient(circle, rgba(233,54,152,.18) 1px, transparent 1px); background-size: 18px 18px; }\n    .performers-section { background: #fff4f8; }\n    .section-heading { position: relative; z-index: 1; display: flex; align-items: end; justify-content: space-between; gap: 20px; margin-bottom: 25px; }\n    .section-heading h2 { margin: 7px 0 0; color: var(--plum-deep); font-family: \"Arial Black\", Impact, sans-serif; font-size: clamp(42px, 5.2vw, 66px); line-height: .88; letter-spacing: -.055em; text-transform: uppercase; }\n    .section-count { color: var(--muted); font-size: 13px; white-space: nowrap; }\n    .performer-rail { position: relative; z-index: 1; display: flex; gap: 16px; overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; padding: 4px 8px 14px 2px; scroll-snap-type: x mandatory; scrollbar-width: none; }\n    .performer-rail::-webkit-scrollbar { display: none; }\n    .performer-card { flex: 0 0 164px; min-height: 225px; padding: 12px; border: 1px solid var(--line); border-radius: 24px; color: var(--plum-deep); background: white; box-shadow: 0 8px 22px rgba(74,37,63,.08); cursor: pointer; scroll-snap-align: start; transition: transform .2s, border-color .2s, box-shadow .2s; }\n    .performer-card:hover { transform: translateY(-3px); }\n    .performer-card[aria-pressed=\"true\"] { border-color: var(--pink); box-shadow: inset 0 0 0 2px var(--pink), 5px 6px 0 var(--pink-soft); transform: translateY(-3px); }\n    .performer-photo { position: relative; width: 100%; aspect-ratio: 1; overflow: hidden; border-radius: 18px; background: linear-gradient(135deg, var(--pink-soft), var(--sky)); }\n    .performer-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }\n    .portrait-fallback { width: 100%; height: 100%; display: grid; place-items: center; color: var(--pink-dark); font: 900 42px/1 Georgia, serif; }\n    .live-dot { position: absolute; right: 8px; bottom: 8px; width: 13px; height: 13px; border: 3px solid white; border-radius: 50%; background: #65d984; }\n    .performer-card strong { display: block; margin-top: 12px; font-size: 16px; text-align: center; }\n    .performer-card small { display: block; margin-top: 3px; color: var(--muted); font-size: 11px; text-align: center; }\n    .performer-heart { display: block; margin-top: 8px; color: var(--pink); font-size: 20px; text-align: center; }\n\n    .oshi-section { background: linear-gradient(145deg, #fff0f5, #fff8e9 72%, #e8f8fa); }\n    .oshi-card, .repertoire-card, .leaderboard-card, .empty-card, .message-card { position: relative; z-index: 1; border: 3px solid var(--brown); border-radius: var(--radius); background: rgba(255,253,250,.96); }\n    .oshi-card { padding: clamp(22px, 5vw, 44px); box-shadow: var(--shadow-pink); }\n    .oshi-profile { display: grid; grid-template-columns: clamp(90px, 17vw, 156px) minmax(0, 1fr); align-items: center; gap: clamp(18px, 4vw, 34px); padding-bottom: 28px; border-bottom: 1px solid var(--line); }\n    .oshi-photo { aspect-ratio: 1; overflow: hidden; border-radius: 26px; background: var(--pink-soft); }\n    .oshi-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }\n    .oshi-role { color: var(--pink-dark); font-size: 11px; font-weight: 950; letter-spacing: .14em; text-transform: uppercase; }\n    .oshi-name { margin: 7px 0 8px; color: var(--plum-deep); font-family: \"Arial Black\", Impact, sans-serif; font-size: clamp(38px, 7vw, 72px); line-height: .9; letter-spacing: -.055em; }\n    .oshi-name { margin-bottom: 14px; }\n    .oshi-tagline { color: var(--muted); line-height: 1.5; margin: 0 0 24px; }\n    .profile-button { margin-top: 12px; padding: 0; border: 0; border-bottom: 1px solid currentColor; color: var(--pink-dark); background: transparent; font-weight: 900; cursor: pointer; }\n    .oshi-hype { padding-top: 28px; }\n    .oshi-hype h3 { margin: 8px 0 10px; color: var(--plum-deep); font-size: clamp(26px, 4vw, 42px); letter-spacing: -.035em; }\n    .oshi-hype p { color: var(--muted); line-height: 1.55; }\n    .cheer-wrap { position: relative; margin-top: 24px; }\n    .cheer-button { width: 100%; min-height: 62px; border: 0; border-radius: 999px; color: white; background: linear-gradient(135deg, var(--pink), var(--pink-dark)); box-shadow: 0 7px 0 var(--brown); font-size: 15px; font-weight: 950; letter-spacing: .05em; cursor: pointer; transition: transform .12s, box-shadow .12s; }\n    .cheer-button:active { transform: translateY(5px); box-shadow: 0 2px 0 var(--brown); }\n    .cheer-count { margin: 18px 0 0; color: var(--muted); font-size: 11px; text-align: center; }\n    .burst-particle, .wota-burst { position: absolute; z-index: 8; left: 50%; top: 50%; pointer-events: none; color: var(--pink); font-style: normal; font-size: 28px; animation: burst .95s cubic-bezier(.12,.75,.25,1) forwards; }\n    .wota-burst { width: max-content; color: var(--plum-deep); font-size: clamp(17px, 4vw, 29px); font-weight: 950; letter-spacing: .04em; text-shadow: 0 2px 0 white; animation-name: wotaBurst; }\n    @keyframes burst { from { opacity: 0; transform: translate(-50%,-20%) scale(.45); } 15% { opacity: 1; } to { opacity: 0; transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) rotate(var(--r)) scale(.85); } }\n    @keyframes wotaBurst { from { opacity: 0; transform: translate(-50%,0) scale(.65) rotate(-3deg); } 15% { opacity: 1; } 70% { opacity: 1; } to { opacity: 0; transform: translate(-50%,-120px) scale(1.05) rotate(2deg); } }\n\n    .repertoire-section { background: var(--cream); }\n    .repertoire-card { padding: clamp(22px, 4vw, 38px); box-shadow: var(--shadow-gold); }\n    .repertoire-title { max-width: 760px; }\n    .dance-list { display: grid; gap: 11px; margin-top: 25px; }\n    .dance-row { display: grid; grid-template-columns: 48px minmax(0,1fr) 44px; align-items: center; gap: 15px; min-height: 82px; padding: 12px 15px; border: 1px solid var(--line); border-radius: 20px; background: white; box-shadow: 0 5px 0 #f3e8db; }\n    .dance-number { color: #a78996; font-size: 12px; font-weight: 950; text-align: center; }\n    .dance-copy { min-width: 0; }\n    .dance-copy strong { display: block; overflow: hidden; color: var(--plum-deep); font-size: 16px; text-overflow: ellipsis; white-space: nowrap; }\n    .dance-copy small { display: block; margin-top: 4px; overflow: hidden; color: var(--muted); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }\n    .dance-copy em { display: block; margin-top: 6px; color: var(--pink-dark); font-size: 9px; font-style: normal; font-weight: 950; letter-spacing: .1em; }\n    .dance-note { width: 42px; height: 42px; display: grid; place-items: center; border-radius: 14px; color: var(--pink-dark); background: var(--pink-soft); font-size: 20px; }\n    .empty-card { padding: 42px 24px; box-shadow: var(--shadow-gold); text-align: center; }\n    .empty-card strong { display: block; color: var(--plum-deep); font-family: \"Arial Black\", Impact, sans-serif; font-size: 25px; }\n    .empty-card p { margin: 12px auto 0; max-width: 520px; color: var(--muted); line-height: 1.55; }\n\n    .leaderboard-section { background: #fff0f5; }\n    .leaderboard-lede { position: relative; z-index: 1; max-width: 590px; margin: -7px 0 24px; color: var(--muted); line-height: 1.55; }\n    .leaderboard-card { padding: 8px clamp(16px, 3vw, 30px); box-shadow: var(--shadow-pink); }\n    .leaderboard-row { display: grid; grid-template-columns: 48px 56px minmax(0,1fr); align-items: center; gap: 14px; min-height: 86px; padding: 13px 0; }\n    .leaderboard-row + .leaderboard-row { border-top: 1px solid var(--line); }\n    .rank { width: 42px; height: 42px; display: grid; place-items: center; border-radius: 50%; color: var(--pink-dark); background: #fff0f7; font-size: 11px; font-weight: 950; }\n    .leader-photo { width: 54px; height: 54px; overflow: hidden; border-radius: 17px; background: var(--pink-soft); }\n    .leader-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }\n    .leader-copy strong { display: block; }\n    .leader-copy small { display: block; margin-top: 4px; color: var(--muted); }\n    .leader-note { position: relative; z-index: 1; margin: 18px 0 0; color: var(--muted); font-size: 11px; text-align: center; }\n\n    .messages-section { background: #eef9fa; }\n    .messages-grid { position: relative; z-index: 1; display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 16px; }\n    .message-card { min-height: 180px; padding: 24px; border-width: 2px; box-shadow: 5px 6px 0 #bce9ef; }\n    .message-card span { color: var(--pink-dark); font-size: 10px; font-weight: 950; letter-spacing: .13em; text-transform: uppercase; }\n    .message-card h3 { margin: 13px 0 10px; font-size: 22px; }\n    .message-card p { margin-bottom: 16px; color: var(--muted); line-height: 1.55; }\n    .message-card time { color: var(--muted); font-size: 11px; }\n\n    .primary-state { position: relative; z-index: 2; margin: 34px auto; max-width: 720px; padding: 30px; border: 2px solid var(--brown); border-radius: 24px; color: var(--plum-deep); background: white; box-shadow: var(--shadow-gold); text-align: center; }\n    .primary-state strong { font-size: 24px; }\n    .primary-state p { margin: 10px 0 0; color: var(--muted); line-height: 1.5; }\n    .primary-state button { min-height: 44px; margin-top: 18px; padding: 10px 18px; border: 2px solid var(--brown); border-radius: 999px; background: var(--pink-soft); font-weight: 900; cursor: pointer; }\n\n    .bottom-nav { position: fixed; z-index: 20; left: 50%; bottom: max(8px, env(safe-area-inset-bottom)); display: none; grid-template-columns: repeat(3,1fr); gap: 5px; width: min(460px, calc(100% - 22px)); margin: 0; padding: 6px; border: 1px solid rgba(75,36,31,.18); border-radius: 24px; background: rgba(255,253,250,.96); box-shadow: 0 8px 28px rgba(74,37,63,.18); backdrop-filter: blur(16px); transform: translateX(-50%); }\n    .bottom-nav a { min-height: 50px; display: grid; place-items: center; border-radius: 18px; color: #765c67; font-size: 13px; font-weight: 900; }\n    .bottom-nav a[aria-current=\"page\"] { color: var(--pink-dark); background: var(--pink-soft); box-shadow: inset 0 0 0 1px #f2a8ce; }\n\n    dialog { width: min(620px, calc(100% - 24px)); max-height: min(86svh, 780px); padding: 0; overflow: auto; border: 0; border-radius: 32px; color: var(--plum-deep); background: var(--paper); box-shadow: 0 28px 90px rgba(34,13,29,.45); }\n    dialog::backdrop { background: rgba(37,18,31,.65); backdrop-filter: blur(7px); }\n    .dialog-close { position: sticky; z-index: 4; float: right; top: 14px; margin: 14px 14px -60px 0; width: 46px; height: 46px; border: 2px solid var(--brown); border-radius: 50%; background: rgba(255,253,250,.92); font-size: 24px; cursor: pointer; }\n    dialog[data-profile-dialog][open] { display: grid; grid-template-columns: minmax(260px, .82fr) minmax(300px, 1fr); width: min(820px, calc(100% - 28px)); overflow: hidden; }\n    dialog[data-profile-dialog] .dialog-close { position: absolute; top: 16px; right: 16px; float: none; margin: 0; }\n    .profile-dialog-photo { min-height: 0; aspect-ratio: 3 / 4; overflow: hidden; background: linear-gradient(135deg,var(--pink-soft),var(--sky)); }\n    dialog[data-profile-dialog] .profile-dialog-photo { grid-column: 1; grid-row: 1; }\n    .profile-dialog-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }\n    .profile-dialog-body { align-content: center; display: grid; gap: 16px; padding: 30px; }\n    dialog[data-profile-dialog] .profile-dialog-body { grid-column: 2; grid-row: 1; align-self: center; }\n    .profile-dialog-body h2 { margin: 7px 0 17px; font-family: \"Arial Black\", Impact, sans-serif; font-size: clamp(42px, 9vw, 70px); line-height: .9; }\n    .profile-facts { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0,1fr)); margin: 0; }\n    .profile-fact { min-width: 0; padding: 13px; border-radius: 16px; background: #fff1f7; }\n    .profile-fact small, .profile-fact strong { display: block; }\n    .profile-fact small { color: var(--muted); font-size: 9px; font-weight: 950; letter-spacing: .1em; text-transform: uppercase; }\n    .profile-fact strong { margin-top: 5px; }\n    .profile-bio { color: var(--muted); line-height: 1.65; margin: 0; }\n    .profile-done { min-height: 46px; justify-self: start; padding: 0 18px; border: 2px solid var(--brown); border-radius: 999px; color: var(--brown); background: white; font-weight: 950; cursor: pointer; }\n    .settings-dialog { padding: 30px; }\n    .settings-dialog h2 { margin: 8px 0 7px; font-size: 34px; }\n    .settings-dialog > p { color: var(--muted); line-height: 1.5; }\n    .setting-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 18px 0; border-top: 1px solid var(--line); }\n    .setting-row strong, .setting-row small { display: block; }\n    .setting-row small { margin-top: 4px; color: var(--muted); }\n    .switch { position: relative; flex: 0 0 56px; width: 56px; height: 32px; border: 0; border-radius: 999px; background: #eadce2; cursor: pointer; }\n    .switch::after { content: \"\"; position: absolute; top: 4px; left: 4px; width: 24px; height: 24px; border-radius: 50%; background: white; box-shadow: 0 2px 5px rgba(0,0,0,.15); transition: transform .18s; }\n    .switch[aria-checked=\"true\"] { background: var(--pink); }\n    .switch[aria-checked=\"true\"]::after { transform: translateX(24px); }\n    .settings-save { width: 100%; min-height: 52px; margin-top: 18px; border: 2px solid var(--brown); border-radius: 999px; color: white; background: var(--pink-dark); box-shadow: 0 5px 0 var(--brown); font-weight: 950; cursor: pointer; }\n\n    @media (max-width: 820px) {\n      .stage-hero { padding: max(20px, env(safe-area-inset-top)) 20px 30px; }\n      .hero-top { gap: 14px; margin-bottom: 26px; }\n      .wordmark { width: min(300px, 76vw); max-width: 100%; }\n      .music-note { right: 22px; top: 54%; font-size: 38px; }\n      .hero-title { max-width: 100%; font-size: clamp(42px, 10vw, 66px); letter-spacing: -.055em; }\n      .hero-date { margin-top: 12px; }\n      .hero-top { align-items: flex-start; flex-direction: column; }\n      .hero-actions { gap: 8px; }\n      .hero-action { min-height: 36px; padding: 0 12px; font-size: 11px; }\n      .content-section { padding: 30px 20px; }\n      .performers-section { padding-bottom: 40px; }\n      .oshi-section { padding-top: 24px; }\n      .section-heading { align-items: end; flex-wrap: wrap; gap: 6px 12px; margin-bottom: 16px; }\n      .section-heading h2 { font-size: clamp(32px, 8.7vw, 44px); }\n      .section-count { margin: 0 0 4px auto; font-size: 11px; }\n      .performer-rail { align-items: start; display: grid; gap: 12px; grid-auto-columns: calc((100% - 12px) / 2); grid-auto-flow: column; margin: 0; padding: 2px 0 0; scroll-padding-inline: 0; }\n      .performer-card { display: grid; align-content: start; flex: none; gap: 0; min-height: 0; padding: 10px 10px 14px; width: 100%; border-radius: 21px; }\n      .performer-photo { aspect-ratio: 3 / 2; }\n      .performer-card strong { margin-top: 8px; }\n      .performer-heart { margin-top: 5px; }\n      .oshi-profile { grid-template-columns: 100px 1fr; }\n      .messages-grid { grid-template-columns: 1fr; }\n      .dance-row { grid-template-columns: 36px minmax(0,1fr) 40px; gap: 10px; padding: 11px 10px; }\n      .app-shell { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }\n      .bottom-nav { display: grid; }\n      dialog[data-profile-dialog][open] { display: block; width: min(520px, calc(100% - 20px)); max-height: 90svh; }\n      dialog[data-profile-dialog] .profile-dialog-photo, dialog[data-profile-dialog] .profile-dialog-body { grid-column: auto; grid-row: auto; }\n      .profile-dialog-photo { width: 100%; aspect-ratio: 4 / 5; max-height: 42svh; }\n      .profile-dialog-body { align-content: start; gap: 14px; padding: 20px; }\n      .profile-dialog-body h2 { margin: 4px 0 8px; font-size: clamp(40px, 12vw, 52px); }\n      .profile-fact { padding: 11px; }\n      .profile-bio { line-height: 1.5; }\n      .profile-done { justify-self: stretch; min-height: 44px; }\n    }\n    @media (min-width: 880px) {\n      .hero-top { margin-top: 48px; }\n      .performers-section { padding-top: 50px; padding-bottom: 54px; }\n      .performers-section .section-heading { margin-bottom: 22px; }\n      .performers-section .section-heading h2 { font-size: 56px; line-height: .88; }\n      .performers-section .section-count { margin-bottom: 7px; }\n      .performer-rail { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 13px; overflow: visible; padding: 4px 2px 10px; }\n      .performer-card { width: 100%; min-width: 0; min-height: 0; }\n    }\n    @media (prefers-reduced-motion: reduce) {\n      *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }\n    }\n  </style>\n</head>\n<body>\n  <main class=\"app-shell\">\n    <header class=\"stage-hero\">\n      <div class=\"hero-top\">\n        <a href=\"{{FYNESITE_SITE_BASE}}/#schedule\" aria-label=\"Dreamland schedule\"><img class=\"wordmark\" src=\"/api/image/proxy/websites/315d5891-4d1d-46d4-a321-026b53f6f229/assets/image/dreamland/brand/76171fd8_dreamland-anime-cafe-wordmark-cbc912840df6.png\" width=\"1080\" height=\"226\" alt=\"Dreamland Anime Cafe\"></a>\n      </div>\n      <div class=\"hero-copy\">\n        <span class=\"hero-kicker\">Welcome to</span>\n        <h1 class=\"hero-title\"><span>DreamLIVE</span><br>Jukebox!</h1>\n        <p class=\"hero-date\" data-event-date>Next DreamLIVE date loading\u2026</p>\n      </div>\n      <span class=\"music-note\" aria-hidden=\"true\">\u266a</span>\n      <span class=\"sr-only\">DreamLIVE Spotlight</span>\n      <span class=\"sr-only\">Reference preview \u00b7 Saturday service \u00b7 11 AM\u20133 PM \u00b7 5\u20139 PM</span>\n    </header>\n\n    <div class=\"ticker\" aria-hidden=\"true\"><div class=\"ticker-track\"><span class=\"ticker-copy\" data-wota-ticker-copy></span><span class=\"ticker-copy\" data-wota-ticker-copy></span></div></div>\n\n    <div class=\"primary-state\" data-primary-state role=\"status\" aria-live=\"polite\"><strong>Opening DreamLIVE</strong><p>We\u2019re checking the next confirmed service.</p></div>\n\n    <section class=\"content-section performers-section\" data-performers-section hidden>\n      <div class=\"section-heading\"><div><span class=\"section-kicker\">Let\u2019s party!</span><h2>Meet your<br>performers</h2></div><span class=\"section-count\" data-performer-count></span></div>\n      <div class=\"performer-rail\" data-performer-rail aria-label=\"DreamLIVE performers\"></div>\n    </section>\n\n    <section class=\"content-section oshi-section\" data-oshi-section hidden>\n      <article class=\"oshi-card\">\n        <div class=\"oshi-profile\">\n          <div class=\"oshi-photo\" data-oshi-photo></div>\n          <div><span class=\"oshi-role\" data-oshi-role>Maid</span><h2 class=\"oshi-name\" data-oshi-name></h2><p class=\"oshi-tagline\" data-oshi-tagline></p><button class=\"profile-button\" type=\"button\" data-profile-open>View profile</button></div>\n        </div>\n        <div class=\"oshi-hype\"><span class=\"section-kicker\">Your Oshi moment</span><h3 data-cheer-title>Cheer for your Oshi</h3></div>\n        <div class=\"cheer-wrap\"><button class=\"cheer-button\" type=\"button\" data-cheer>\u2661&nbsp;&nbsp; SEND AN OSHI CHEER</button></div>\n        <p class=\"cheer-count\"><strong data-cheer-count>0</strong> cheers this week \u00b7 refreshes Monday at midnight PT</p>\n      </article>\n    </section>\n\n    <section class=\"content-section repertoire-section\" data-repertoire-section hidden>\n      <div class=\"section-heading repertoire-title\"><div><span class=\"section-kicker\">DreamLIVE repertoire</span><h2 data-repertoire-title>Dance repertoire</h2></div></div>\n      <div class=\"repertoire-card\"><div class=\"dance-list\" data-dance-list></div><div class=\"empty-card\" data-repertoire-empty hidden><strong>Repertoire coming soon</strong><p>This performer\u2019s available dances will appear here when their repertoire is published.</p></div></div>\n      <span class=\"sr-only\">featured-songs compatibility collection</span>\n    </section>\n\n    <section class=\"content-section leaderboard-section\" data-leaderboard-section hidden>\n      <div class=\"section-heading\"><div><span class=\"section-kicker\">Fan favorites</span><h2>Weekly Oshi<br>leaderboard</h2></div><span class=\"section-count\">Updates weekly</span></div>\n      <p class=\"leaderboard-lede\" data-leaderboard-lede></p>\n      <div class=\"leaderboard-card\" data-leaderboard-list></div>\n      <div class=\"empty-card\" data-leaderboard-empty hidden><strong>Rankings coming soon</strong><p data-leaderboard-empty-copy></p></div>\n      <p class=\"leader-note\" data-leader-reset>Live totals refresh every Monday at midnight PT.</p>\n    </section>\n\n    <section class=\"content-section messages-section\" id=\"messages\" data-messages-section hidden>\n      <div class=\"section-heading\"><div><span class=\"section-kicker\">From the mansion</span><h2>Official<br>messages</h2></div></div>\n      <div class=\"messages-grid\" data-messages-grid></div>\n    </section>\n\n    <nav class=\"bottom-nav\" aria-label=\"Dreamland app\">\n      <a href=\"{{FYNESITE_SITE_BASE}}/#schedule\">Schedule</a>\n      <a href=\"{{FYNESITE_SITE_BASE}}/jukebox\" aria-current=\"page\">DreamLIVE</a>\n      <a href=\"{{FYNESITE_SITE_BASE}}/#messages\">Messages</a>\n    </nav>\n  </main>\n\n  <dialog data-profile-dialog aria-labelledby=\"profile-name\">\n    <button class=\"dialog-close\" type=\"button\" data-profile-close aria-label=\"Close profile\">\u00d7</button>\n    <div class=\"profile-dialog-photo\" data-profile-photo></div>\n    <div class=\"profile-dialog-body\"><span class=\"section-kicker\" data-profile-role>Maid</span><h2 id=\"profile-name\" data-profile-name></h2><div class=\"profile-facts\"><div class=\"profile-fact\"><small>Cafe rank</small><strong data-profile-rank>Coming soon</strong></div><div class=\"profile-fact\"><small>Birthday</small><strong data-profile-birthday>Coming soon</strong></div></div><p class=\"profile-bio\" data-profile-bio>Profile details are coming soon.</p><button class=\"profile-done\" type=\"button\" data-profile-done>Back to DreamLIVE</button></div>\n  </dialog>\n\n  <script>\n    (() => {\n      const TEMPLATE_KEYS = ['performers', 'events', 'shifts', 'featured-songs', 'repertoire', 'official-notes'];\n      const WOTA_WORDS = ['\u30bf\u30a4\u30ac\u30fc', '\u30d5\u30a1\u30a4\u30e4\u30fc', '\u30b5\u30a4\u30d0\u30fc', '\u30d5\u30a1\u30a4\u30d0\u30fc', '\u30c0\u30a4\u30d0\u30fc', '\u30d0\u30a4\u30d0\u30fc', '\u30b8\u30e3\u30fc\u30b8\u30e3\u30fc', '\u30c8\u30e9', '\u30d2', '\u30b8\u30f3\u30be\u30a6', '\u30bb\u30f3\u30a4', '\u30a2\u30de', '\u30b7\u30f3\u30c9\u30a6', '\u30ab\u30bb\u30f3'];\n      const WOTA_TICKER_COPY = `${WOTA_WORDS.join(' \u2726 ')} \u2726`;\n      const WOTA_CALLS = WOTA_WORDS.map((word) => `${word}!`);\n      document.querySelectorAll('[data-wota-ticker-copy]').forEach((copy) => { copy.textContent = WOTA_TICKER_COPY; });\n      const $ = (selector, root = document) => root.querySelector(selector);\n      const requestedShift = new URLSearchParams(location.search).get('shift') || '';\n      const state = { data: Object.fromEntries(TEMPLATE_KEYS.map((key) => [key, []])), event: null, performers: [], selectedId: null, leaderboard: [], leaderboardStatus: 'loading', resetAt: '', cheerToken: '', lastCheerAt: 0, cheerCall: 0 };\n      let sessionDeviceId = '';\n\n      function siteBase() {\n        const configured = document.documentElement.dataset.siteBase;\n        if (configured && !configured.includes('{{')) return configured.replace(/\\/$/, '');\n        if (/^\\/jukebox\\/?$/.test(location.pathname)) return '';\n        const match = location.pathname.match(/^\\/[^/]+/);\n        return match ? match[0] : '';\n      }\n      function dataUrl(key, selector = '', params = {}) {\n        const base = `${siteBase()}/_apps/jukebox/data/${encodeURIComponent(key)}`;\n        const query = new URLSearchParams(params);\n        if (!selector) return query.size ? `${base}?${query}` : base;\n        const param = key === 'events' ? 'spotlight_key' : 'event_id';\n        query.set(param, selector);\n        return `${base}?${query}`;\n      }\n      function oshiUrl(path) { return `${siteBase()}/_apps/jukebox/oshi/${path}`; }\n      function deviceId() {\n        const key = 'dreamland-oshi-device';\n        try {\n          let value = localStorage.getItem(key);\n          if (!value) { value = globalThis.crypto?.randomUUID?.() || `web-${Date.now()}-${Math.random().toString(36).slice(2)}`; sessionDeviceId = value; localStorage.setItem(key, value); }\n          sessionDeviceId = value;\n          return value;\n        } catch (_) { if (!sessionDeviceId) sessionDeviceId = `web-session-${Date.now()}-${Math.random().toString(36).slice(2)}`; return sessionDeviceId; }\n      }\n      function itemData(item) { return { id: item.id, public_revision: item.public_revision, ...(item.data || {}) }; }\n      function localDateKey(date = new Date()) { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2,'0')}-${String(date.getDate()).padStart(2,'0')}`; }\n      function formatDate(value) { if (!value) return 'Date coming soon'; return new Intl.DateTimeFormat('en-US', { weekday: 'long', month: 'long', day: 'numeric' }).format(new Date(`${value}T12:00:00`)); }\n      function portrait(performer, alt = '') { const node = performer?.portrait_url ? document.createElement('img') : document.createElement('span'); if (performer?.portrait_url) { node.src = performer.portrait_url; node.alt = alt || performer.portrait_alt || ''; node.width = 1080; node.height = 1080; node.loading = 'lazy'; } else { node.className = 'portrait-fallback'; node.textContent = (performer?.stage_name || '?').slice(0,1).toUpperCase(); node.setAttribute('aria-hidden','true'); } return node; }\n      function performerById(id) { return state.data.performers.find((performer) => performer.id === id); }\n      function selectedPerformer() { return state.performers.find((performer) => performer.id === state.selectedId) || state.performers[0] || null; }\n      function repertoireFor(performer) { return state.data.repertoire.filter((song) => song.active !== false && performer && Array.isArray(song.performer_ids) && song.performer_ids.includes(performer.id)); }\n      function performerTagline(performer) { const tagline = String(performer?.tagline || '').trim(); return /^Official Dreamland Maid Cafe cast profile$/i.test(tagline) ? '' : tagline; }\n      function setState(title, copy, retry = false) { const box = $('[data-primary-state]'); box.replaceChildren(); const strong = document.createElement('strong'); strong.textContent = title; const p = document.createElement('p'); p.textContent = copy; box.append(strong,p); box.hidden = false; box.setAttribute('role', retry ? 'alert' : 'status'); if (retry) { const button = document.createElement('button'); button.type = 'button'; button.textContent = 'Try again'; button.addEventListener('click', loadData); box.append(button); } }\n\n      function renderRail() {\n        const rail = $('[data-performer-rail]'); rail.replaceChildren();\n        state.performers.forEach((performer) => {\n          const button = document.createElement('button'); button.type = 'button'; button.className = 'performer-card'; button.dataset.performerId = performer.id; button.setAttribute('aria-pressed', String(performer.id === state.selectedId)); button.setAttribute('aria-label', `Show ${performer.stage_name}'s DreamLIVE repertoire`);\n          const photo = document.createElement('span'); photo.className = 'performer-photo'; photo.append(portrait(performer)); const dot = document.createElement('i'); dot.className = 'live-dot'; dot.setAttribute('aria-hidden','true'); photo.append(dot);\n          const name = document.createElement('strong'); name.textContent = performer.stage_name || 'Dreamland maid'; const hint = document.createElement('small'); hint.textContent = performer.id === state.selectedId ? 'Selected' : 'See repertoire'; const heart = document.createElement('span'); heart.className = 'performer-heart'; heart.textContent = performer.id === state.selectedId ? '\u2665' : '\u2661';\n          button.append(photo,name,hint,heart); button.addEventListener('click', () => { state.selectedId = performer.id; renderSelected(); [...rail.querySelectorAll('[data-performer-id]')].find((node) => node.dataset.performerId === performer.id)?.focus({ preventScroll: true }); }); rail.append(button);\n        });\n      }\n      function renderSelected() {\n        const performer = selectedPerformer(); if (!performer) return;\n        renderRail(); $('[data-oshi-photo]').replaceChildren(portrait(performer, performer.portrait_alt)); $('[data-oshi-role]').textContent = performer.role || 'Maid'; $('[data-oshi-name]').textContent = performer.stage_name || 'Dreamland maid'; $('[data-oshi-tagline]').textContent = performerTagline(performer); $('[data-oshi-tagline]').hidden = !performerTagline(performer); $('[data-cheer-title]').textContent = `Cheer for ${performer.stage_name || 'your Oshi'}`;\n        const current = state.leaderboard.find((entry) => entry.performer_id === performer.id); $('[data-cheer-count]').textContent = state.leaderboardStatus === 'ready' ? String(Number(current?.cheers || 0)) : '\u2014';\n        const cheerButton = $('[data-cheer]'); cheerButton.disabled = state.leaderboardStatus !== 'ready'; cheerButton.textContent = state.leaderboardStatus === 'error' ? 'WEEKLY COUNTER UNAVAILABLE \u2014 REFRESH' : state.leaderboardStatus === 'loading' ? 'LOADING WEEKLY COUNTER\u2026' : '\u2661  SEND AN OSHI CHEER';\n        const title = `${performer.stage_name || 'Dreamland'}\u2019s Dance Repertoire`; $('[data-repertoire-title]').textContent = title;\n        const list = $('[data-dance-list]'); const empty = $('[data-repertoire-empty]'); const songs = repertoireFor(performer); list.replaceChildren(); empty.hidden = Boolean(songs.length);\n        songs.forEach((song,index) => { const row = document.createElement('div'); row.className = 'dance-row'; const number = document.createElement('span'); number.className = 'dance-number'; number.textContent = String(index + 1).padStart(2,'0'); const copy = document.createElement('span'); copy.className = 'dance-copy'; const name = document.createElement('strong'); name.textContent = song.title || 'Song to be announced'; const artist = document.createElement('small'); artist.textContent = song.original_artist || 'Origin to be confirmed'; const meta = document.createElement('em'); meta.textContent = 'Available dance'; copy.append(name,artist,meta); const note = document.createElement('span'); note.className = 'dance-note'; note.textContent = '\u266a'; note.setAttribute('aria-hidden','true'); row.append(number,copy,note); list.append(row); });\n      }\n      function renderLeaderboard() {\n        const today = state.event?.date === localDateKey(); const list = $('[data-leaderboard-list]'); const empty = $('[data-leaderboard-empty]'); $('[data-leaderboard-lede]').textContent = today ? 'Live cheers from this week\u2019s Dreamland guests.' : 'The live Oshi board opens on the day of this DreamLIVE service.'; list.replaceChildren(); list.hidden = !today; empty.hidden = today;\n        if (!today) { $('[data-leaderboard-empty-copy]').textContent = `Check back on ${formatDate(state.event?.date)} to see the weekly board.`; return; }\n        if (state.leaderboardStatus !== 'ready') { list.hidden = true; empty.hidden = false; $('[data-leaderboard-empty-copy]').textContent = state.leaderboardStatus === 'loading' ? 'Loading the official weekly totals\u2026' : 'The official weekly totals are temporarily unavailable. Refresh to try again.'; return; }\n        const activeIds = new Set(state.performers.map((performer) => performer.id)); const entries = state.leaderboard.filter((entry) => activeIds.has(entry.performer_id));\n        entries.forEach((entry) => { const performer = performerById(entry.performer_id) || entry; const row = document.createElement('div'); row.className = 'leaderboard-row'; const rank = document.createElement('span'); rank.className = 'rank'; rank.textContent = `#${entry.rank}`; const photo = document.createElement('span'); photo.className = 'leader-photo'; photo.append(portrait(performer)); const copy = document.createElement('span'); copy.className = 'leader-copy'; const name = document.createElement('strong'); name.textContent = entry.stage_name || performer.stage_name || 'Dreamland maid'; const meta = document.createElement('small'); meta.textContent = `${entry.cheers} ${entry.cheers === 1 ? 'cheer' : 'cheers'} this week`; copy.append(name,meta); row.append(rank,photo,copy); list.append(row); });\n        if (!entries.length) { list.hidden = true; empty.hidden = false; $('[data-leaderboard-empty-copy]').textContent = 'Be the first to send an Oshi cheer this week.'; }\n      }\n      function renderMessages() {\n        const notes = state.data['official-notes'].filter((note) => note.active !== false); const section = $('[data-messages-section]'); const grid = $('[data-messages-grid]'); grid.replaceChildren(); section.hidden = false;\n        if (!notes.length) { const card = document.createElement('article'); card.className = 'message-card'; card.innerHTML = '<span>Official update</span><h3>No new messages</h3><p>Dreamland announcements will appear here.</p>'; grid.append(card); return; }\n        notes.forEach((note) => { const card = document.createElement('article'); card.className = 'message-card'; const label = document.createElement('span'); label.textContent = note.label || 'Official update'; const title = document.createElement('h3'); title.textContent = note.title || 'Dreamland update'; const body = document.createElement('p'); body.textContent = note.body || ''; const time = document.createElement('time'); time.dateTime = note.published_on || ''; time.textContent = note.published_on ? formatDate(note.published_on) : ''; card.append(label,title,body,time); grid.append(card); });\n      }\n      function performerStarRank(performer) {\n        const profileCopy = String(performer.bio || performer.tagline || '');\n        const numeric = Number(performer.star_level || performer.cafe_rank || profileCopy.match(/(?:Cafe rank\\s+)?(\\d+)\\s+stars?/i)?.[1]);\n        const glyphCount = profileCopy.match(/\u2605/g)?.length || 0;\n        const starCount = Math.min(5, Math.max(0, Math.floor(numeric || glyphCount)));\n        return starCount ? Array(starCount).fill('\u2605').join(' ') : '';\n      }\n      function performerBirthday(performer) {\n        const profileCopy = String(performer?.bio || performer?.tagline || '');\n        return performer?.birthday || profileCopy.match(/Birthday:\\s*([^.]*)/i)?.[1]?.trim() || 'Coming soon';\n      }\n      function performerProfileCopy(performer) {\n        const profileCopy = String(performer?.bio || '').trim()\n          .replace(/Cafe rank[^.]*\\.?/ig, '')\n          .replace(/Birthday:\\s*[^.]*\\.?/ig, '')\n          .replace(/\\s{2,}/g, ' ')\n          .trim();\n        if (profileCopy) return profileCopy;\n        const tagline = performerTagline(performer);\n        return tagline || 'Profile details are coming soon.';\n      }\n      function render() {\n        $('[data-primary-state]').hidden = true; $('[data-event-date]').textContent = formatDate(state.event.date); $('[data-performer-count]').textContent = `${state.performers.length} ${state.performers.length === 1 ? 'performer' : 'performers'}`;\n        ['[data-performers-section]','[data-oshi-section]','[data-repertoire-section]','[data-leaderboard-section]'].forEach((selector) => { $(selector).hidden = false; }); renderSelected(); renderLeaderboard(); renderMessages();\n      }\n      function reconcile() {\n        const allEvents = [...state.data.events].sort((a,b) => String(a.date || '').localeCompare(String(b.date || ''))); const events = allEvents.filter((event) => !['cancelled','closed'].includes(String(event.status).toLowerCase()));\n        state.event = requestedShift ? allEvents.find((event) => event.spotlight_key === requestedShift) || null : events.find((event) => event.date >= localDateKey()) || null;\n        if (!state.event) { setState('DreamLIVE date coming soon', 'The next service has not been announced yet. Check Messages for official updates.'); renderMessages(); return; }\n        if (['cancelled','closed'].includes(String(state.event.status).toLowerCase())) { $('[data-event-date]').textContent = formatDate(state.event.date); setState('This DreamLIVE service is not active', 'This date was cancelled or closed. Open Schedule for the next available service.'); renderMessages(); return; }\n        const ids = state.data.shifts.filter((shift) => shift.event_id === state.event.id && shift.status !== 'cancelled').sort((a,b) => Number(a.sort_order || 0) - Number(b.sort_order || 0)).map((shift) => shift.performer_id);\n        state.performers = [...new Set(ids)].map(performerById).filter((performer) => performer && performer.active !== false); if (!state.performers.length) { $('[data-event-date]').textContent = formatDate(state.event.date); setState('Performers coming soon', 'The service is confirmed. Dreamland will add its performer lineup here.'); renderMessages(); return; }\n        if (!state.performers.some((performer) => performer.id === state.selectedId)) state.selectedId = state.performers[0].id; render();\n      }\n      async function loadData() {\n        setState('Opening DreamLIVE', 'We\u2019re checking the next confirmed service.');\n        try {\n          const fetchCollection = async (key, selector = '', params = {}) => { const response = await fetch(dataUrl(key, selector, params), { headers: { Accept: 'application/json' }, credentials: 'same-origin' }); if (!response.ok) throw new Error(`DreamLIVE request failed (${response.status})`); const payload = await response.json(); return (Array.isArray(payload?.items) ? payload.items : []).map(itemData); };\n          const offsetDate = (days) => { const value = new Date(); value.setDate(value.getDate() + days); return localDateKey(value); };\n          const eventRequest = requestedShift ? fetchCollection('events', requestedShift) : Promise.all([fetchCollection('events', '', { from: offsetDate(0), to: offsetDate(30) }), fetchCollection('events', '', { from: offsetDate(31), to: offsetDate(60) })]).then(([first, second]) => [...new Map([...first, ...second].map((event) => [event.id, event])).values()]);\n          const leaderboardUrl = `${oshiUrl('leaderboard')}?${new URLSearchParams({ device_id: deviceId() })}`;\n          const leaderboardRequest = fetch(leaderboardUrl, { headers: { Accept: 'application/json' } }).then(async (response) => { if (!response.ok) throw new Error(`Leaderboard failed (${response.status})`); return response.json(); }).catch((error) => { console.warn('[Dreamland] Weekly Oshi totals unavailable', error); return { leaderboard_error: true }; });\n          const [performers, events, repertoire, notes, leaderboard] = await Promise.all([fetchCollection('performers'), eventRequest, fetchCollection('repertoire'), fetchCollection('official-notes'), leaderboardRequest]); Object.assign(state.data, { performers, events, repertoire, 'official-notes': notes }); state.leaderboardStatus = leaderboard.leaderboard_error ? 'error' : 'ready'; state.leaderboard = Array.isArray(leaderboard.leaderboard) ? leaderboard.leaderboard : []; state.resetAt = leaderboard.resets_at || ''; state.cheerToken = leaderboard.cheer_token || '';\n          const resolved = requestedShift ? events.find((event) => event.spotlight_key === requestedShift) : [...events].filter((event) => !['cancelled','closed'].includes(String(event.status).toLowerCase())).sort((a,b) => String(a.date || '').localeCompare(String(b.date || ''))).find((event) => event.date >= localDateKey());\n          if (resolved) { const [shifts, featured] = await Promise.all([fetchCollection('shifts', resolved.id), fetchCollection('featured-songs', resolved.id)]); Object.assign(state.data, { shifts, 'featured-songs': featured }); }\n          reconcile();\n        } catch (error) { console.error('[Dreamland] Could not load DreamLIVE data', error); setState('DreamLIVE unavailable', 'We could not load the confirmed service. Try again in a moment.', true); }\n      }\n\n      function openProfile() { const performer = selectedPerformer(); if (!performer) return; const image = portrait(performer, performer.portrait_alt); if (image.tagName === 'IMG') image.loading = 'eager'; const starRank = performerStarRank(performer); $('[data-profile-photo]').replaceChildren(image); $('[data-profile-role]').textContent = performer.role || 'Maid'; $('[data-profile-name]').textContent = performer.stage_name || 'Dreamland maid'; $('[data-profile-rank]').textContent = starRank || 'Coming soon'; $('[data-profile-birthday]').textContent = performerBirthday(performer); $('[data-profile-bio]').textContent = performerProfileCopy(performer); $('[data-profile-dialog]').showModal(); }\n      function playCheerBurst() {\n        const wrap = $('.cheer-wrap');\n        const call = document.createElement('i');\n        call.className = 'wota-burst';\n        call.textContent = WOTA_CALLS[state.cheerCall++ % WOTA_CALLS.length];\n        wrap.append(call);\n        const paths = [['-145px','-90px','-18deg','\u2665'],['-95px','-125px','12deg','\u2661'],['-45px','-145px','-10deg','\u2665'],['15px','-150px','17deg','\u2661'],['75px','-128px','-12deg','\u2665'],['130px','-92px','20deg','\u2661'],['0px','-108px','4deg','\u2665']];\n        paths.forEach(([x,y,r,glyph]) => {\n          const heart = document.createElement('i');\n          heart.className = 'burst-particle';\n          heart.textContent = glyph;\n          heart.style.setProperty('--x',x);\n          heart.style.setProperty('--y',y);\n          heart.style.setProperty('--r',r);\n          wrap.append(heart);\n          heart.addEventListener('animationend', () => heart.remove(), { once: true });\n        });\n        call.addEventListener('animationend', () => call.remove(), { once: true });\n      }\n      async function submitCheer(performer, token) {\n        const response = await fetch(oshiUrl('cheers'), {\n          method: 'POST',\n          headers: { Accept: 'application/json', 'Content-Type': 'application/json' },\n          body: JSON.stringify({ performer_id: performer.id, device_id: deviceId(), cheer_token: token }),\n        });\n        const payload = await response.json().catch(() => ({}));\n        if (!response.ok) {\n          const error = new Error(payload?.error?.message || `Cheer failed (${response.status})`);\n          error.code = payload?.error?.code || 'CHEER_FAILED';\n          error.retryAfter = Number(response.headers.get('Retry-After') || 0);\n          throw error;\n        }\n        return payload;\n      }\n      async function burstCheer() {\n        const performer = selectedPerformer();\n        const now = Date.now();\n        if (!performer || now - state.lastCheerAt < 1000) return;\n        state.lastCheerAt = now;\n        const button = $('[data-cheer]');\n        button.disabled = true;\n        button.textContent = 'SAVING CHEER\u2026';\n        let resetDelay = 1000;\n        let keepDisabled = false;\n        try {\n          if (!state.cheerToken) throw new Error('Cheer session unavailable');\n          let payload;\n          try {\n            payload = await submitCheer(performer, state.cheerToken);\n          } catch (error) {\n            if (error.code !== 'VALIDATION_ERROR') throw error;\n            const credentialResponse = await fetch(`${oshiUrl('leaderboard')}?${new URLSearchParams({ device_id: deviceId() })}`, { headers: { Accept: 'application/json' } });\n            if (!credentialResponse.ok) throw error;\n            const fresh = await credentialResponse.json();\n            state.cheerToken = fresh.cheer_token || '';\n            if (!state.cheerToken) throw error;\n            payload = await submitCheer(performer, state.cheerToken);\n          }\n          state.leaderboard = Array.isArray(payload.leaderboard) ? payload.leaderboard : [];\n          state.leaderboardStatus = 'ready';\n          state.resetAt = payload.resets_at || '';\n          state.cheerToken = payload.cheer_token || state.cheerToken;\n          $('[data-cheer-count]').textContent = String(Number(payload.performer_total || 0));\n          renderLeaderboard();\n          playCheerBurst();\n          button.textContent = 'CHEER SENT!  \u2665';\n        } catch (error) {\n          state.lastCheerAt = 0;\n          console.warn('[Dreamland] Oshi cheer was not saved', error);\n          if (error.code === 'CHEER_LIMIT') {\n            button.textContent = 'WEEKLY CHEER LIMIT REACHED';\n            keepDisabled = true;\n          } else if (error.retryAfter > 0) {\n            resetDelay = error.retryAfter * 1000;\n            button.textContent = `PLEASE WAIT ${error.retryAfter} SECONDS`;\n          } else {\n            button.textContent = 'NOT SAVED \u2014 TRY AGAIN';\n          }\n        } finally {\n          if (!keepDisabled) setTimeout(() => { button.disabled = false; button.innerHTML = '\u2661&nbsp;&nbsp; SEND AN OSHI CHEER'; }, resetDelay);\n        }\n      }\n\n      $('[data-profile-open]').addEventListener('click', openProfile); $('[data-profile-close]').addEventListener('click', () => $('[data-profile-dialog]').close()); $('[data-profile-done]').addEventListener('click', () => $('[data-profile-dialog]').close()); $('[data-profile-dialog]').addEventListener('click', (event) => { if (event.target === event.currentTarget) event.currentTarget.close(); }); $('[data-cheer]').addEventListener('click', burstCheer);\n      loadData();\n    })();\n  </script>\n</body>\n</html>\n"}
