// evaluations.jsx
// Vintage Music Group A&R evaluation system:
// • EvaluationsBlock — Profile section listing past evals
// • EvaluationDetail — full rubric breakdown for one evaluation
// • RubricScreen — public rubric reference + A&R input mode
// • CreditsCard — Home/Profile widget showing XP → A&R credits
const { useState: useStateE, useEffect: useEffectE } = React;
const { Card, Chip, TopBar, DisplayHeading } = window.LAUNCH_SCREENS_1;
// ────────────────────────────────────────────────────────
// Quick Score Rubric — Vintage Music Group v1.0
// 5 categories × 10 pts = 50 total · 40+ unlocks rewards
// ────────────────────────────────────────────────────────
const RUBRIC = [
{ id: 'structure', label: 'SONG STRUCTURE', desc: 'Form, flow, arrangement — does the song carry the listener?' },
{ id: 'hook', label: 'TITLE / HOOK', desc: 'The line you remember after one listen. Sticky, earned, owned.' },
{ id: 'idea', label: 'IDEA', desc: 'The concept underneath the song. Specific point of view.' },
{ id: 'lyrics', label: 'LYRICS', desc: 'Word choice, imagery, payoff, rhyme craft.' },
{ id: 'melody', label: 'MELODY', desc: 'Top-line shape, intervals, singability, contour.' },
];
const REWARD_THRESHOLD = 40;
// What each score level signals — 40+ is the reward-unlock line
const SCORE_BANDS = [
{ min: 0, max: 19, label: 'FOUNDATION', sub: 'Core craft needs work', tone: '#7a7a7a' },
{ min: 20, max: 29, label: 'BUILDING', sub: 'Real ideas, rough execution', tone: '#8A6A3B' },
{ min: 30, max: 39, label: 'ALMOST THERE', sub: 'One revision from unlocking', tone: '#E8A736' },
{ min: 40, max: 44, label: 'REWARDS UNLOCKED', sub: 'Bonus XP, mentor tag, ★ badge', tone: '#4A7FD8' },
{ min: 45, max: 50, label: 'TOP CUT', sub: 'Front-of-line A&R + features', tone: '#C72820' },
];
function bandFor(total) { return SCORE_BANDS.find(b => total >= b.min && total <= b.max) || SCORE_BANDS[0]; }
// Sample stored evaluations — these would normally come from an API
const SAMPLE_EVALS = [
{
id: 'eval-001',
track: 'WINTER LIGHT',
coverPal: ['#C72820', '#7A5AE0'],
coverLbl: 'WL',
submitted: 'APR 18, 2026',
reviewer: { lbl: 'JB', name: 'Jay Brunswick', role: 'PROD · A&R VINTAGE MUSIC GROUP', color: '#C72820' },
tier: 'IN-DEPTH · $40',
scores: { structure: 9, hook: 9, idea: 8, lyrics: 8, melody: 9 },
notes: {
structure: 'Form holds across the runtime. Pre-chorus does its job — tension lands. Consider trimming the intro from 4 bars to 2 so the first hook arrives sooner.',
hook: '"Winter light bends low" is the line. Title earns its keep — make it the streaming card and the first lyric. Owns its space.',
idea: 'Clear point of view: missing a person through a season. Specific enough to feel personal, universal enough to land. Don\'t over-explain it.',
lyrics: 'Verse 2 is the strongest writing. Pre-chorus rhyme scheme feels predictable on second listen — try ending one line short. Imagery in bridge is excellent.',
melody: 'Chorus contour climbs naturally. Pre-chorus melody is the weak link — sits in one octave too long. Push one phrase up a fourth.',
},
verdict: '"Real promise. This is the closest you\'ve gotten to your sound. Cut the intro, sharpen the pre-chorus melody, and resubmit — we\'ll talk."',
},
{
id: 'eval-002',
track: 'BLUE DOORS',
coverPal: ['#4A7FD8', '#FBBF24'],
coverLbl: 'BD',
submitted: 'MAR 02, 2026',
reviewer: { lbl: 'PG', name: 'PG Banker', role: 'SONGWRITER · NASHVILLE', color: '#7A5AE0' },
tier: 'QUICK SCORE · $11',
scores: { structure: 8, hook: 9, idea: 7, lyrics: 7, melody: 8 },
notes: {
structure: 'Form is balanced. Bridge restates the chorus — bridges should reframe, not repeat. Try a left-field melodic move there.',
hook: 'Title carries the song. "Blue doors" is concrete, visual, repeatable. Don\'t bury it under the vocal layer.',
idea: 'Decent concept but the listener has to do too much work to find it. Spell the through-line one notch clearer.',
lyrics: 'Voice is the strongest asset here. Lead with it. Verse 1 line 3 is the only weak rhyme — easy fix.',
melody: 'Chorus is the sticky part. Verse melody is forgettable — too step-wise. Add one jump.',
},
verdict: '"Solid demo. You\'re writing better than you\'re producing. Lift the verse melody and the whole thing climbs."',
},
{
id: 'eval-003',
track: 'HALF SLEEP',
coverPal: ['#FBBF24', '#0A0A0A'],
coverLbl: 'HS',
submitted: 'JAN 22, 2026',
reviewer: { lbl: 'PG', name: 'PG Banker', role: 'SONGWRITER · NASHVILLE', color: '#7A5AE0' },
tier: 'QUICK SCORE · $11',
scores: { structure: 7, hook: 6, idea: 8, lyrics: 7, melody: 6 },
notes: {
structure: 'Hook arrives too late — bring it to 0:35 instead of 1:05. Listener won\'t wait.',
hook: 'Title is OK but you can do better. "Half sleep" is a phrase, not yet a hook. Find the image inside it.',
idea: 'Concept is strong. The in-between state of half-sleep is fertile ground — lean into the dream logic.',
lyrics: 'Honest writing. Verse 2 line 2 is the keeper line — build the song around it next time.',
melody: 'Familiar territory. What\'s the melodic move nobody else would make? Try the one that scares you.',
},
verdict: '"Get the hook in faster. Trust the listener less. There\'s a song here — find it in the first 30 seconds."',
},
];
// XP → credits accounting (every 100 XP = 1 evaluation credit)
const XP_TOTAL = 8372; // lifetime
const XP_PER_CREDIT = 100;
const CREDITS_USED = 80; // mock — increments per evaluation submitted
function creditsState() {
const earned = Math.floor(XP_TOTAL / XP_PER_CREDIT);
const available = earned - CREDITS_USED;
const xpToNext = XP_PER_CREDIT - (XP_TOTAL % XP_PER_CREDIT);
const pct = ((XP_TOTAL % XP_PER_CREDIT) / XP_PER_CREDIT) * 100;
return { earned, available, xpToNext, pct };
}
// ────────────────────────────────────────────────────────
// CreditsCard — XP progress to next A&R credit
// ────────────────────────────────────────────────────────
function CreditsCard({ theme, onUse, compact = false }) {
const c = creditsState();
return (