// cop-scenes.jsx — VikingHeat COP explainer: 9 scenes
// Globals (from video-shared.jsx + cop-elements.jsx):
//   W, H, VC, lerp, smooth, ramp, fadeWindow, useTime
//   Tag, Headline, MonoLabel, BackgroundField, Logo (from video-shared)
//   HeatPump, CopHouse, Weather, Thermostat, FlowGauge, PlotFrame, buildPath, PowerGraph

// ── Scene 1: Title (0..3.5) ───────────────────────────────────────────────
function CSceneTitle() {
  const t = useTime() * 0.6;
  if (t > 3.6) return null;
  const op = fadeWindow(t, 0.0, 0.6, 2.8, 3.4);
  const subOp = fadeWindow(t, 0.6, 1.2, 2.8, 3.4);
  const rule = smooth(ramp(t, 0.4, 1.5));
  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <div style={{
        position: 'absolute', left: '50%', top: 380, transform: 'translateX(-50%)',
        fontFamily: VC.fontMono, fontSize: 16, letterSpacing: '0.22em',
        color: VC.copper, textTransform: 'uppercase', opacity: subOp,
        display: 'flex', alignItems: 'center', gap: 14,
      }}>
        <span style={{ width: 28, height: 1, background: VC.copper }}/>
        Sådan opnår VikingHeat den højeste COP
        <span style={{ width: 28, height: 1, background: VC.copper }}/>
      </div>
      <Headline x={W/2} y={460} size={92} weight={500} align="center"
        color={VC.paper} opacity={op}>
        Lavest fremløb.{'\n'}Varmest udeluft. Lavest pris.
      </Headline>
      <div style={{
        position: 'absolute', left: '50%', top: 800, transform: 'translateX(-50%)',
        width: 480 * rule, height: 1, background: VC.copper, opacity: subOp,
      }}/>
      <MonoLabel x={W/2} y={828} align="center" size={16} color={VC.muted} opacity={subOp}>
        Det perfekte sweetspot — uden at komforten påvirkes
      </MonoLabel>
    </div>
  );
}

// ── Scene 2: System setup (3.5..8) ────────────────────────────────────────
function CSceneSetup() {
  const t = useTime() * 0.6;
  if (t < 3.4 || t > 8.4) return null;
  const op = fadeWindow(t, 3.6, 4.4, 7.6, 8.2);
  const houseT = smooth(ramp(t, 4.0, 5.4));
  const pumpOp = fadeWindow(t, 4.6, 5.2, 7.6, 8.2);
  const wxOp = fadeWindow(t, 5.0, 5.6, 7.6, 8.2);
  const thOp = fadeWindow(t, 5.4, 6.0, 7.6, 8.2);
  const capOp = fadeWindow(t, 5.8, 6.4, 7.6, 8.2);
  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <Tag x={W/2} y={120} align="center" color={VC.copper} opacity={op}>
        Systemet · Tre ydre faktorer
      </Tag>
      <Headline x={W/2} y={170} size={56} weight={500} align="center"
        color={VC.paper} opacity={op}>
        Hus, varmepumpe, vejr — og elprisen.
      </Headline>

      {/* House centre-left */}
      <CopHouse x={760} y={620} size={520} drawT={houseT} opacity={op} indoorTemp="21°"/>

      {/* Heat pump right of house */}
      <HeatPump x={1170} y={680} size={240} opacity={pumpOp} spinning />
      {/* connecting pipes */}
      <svg style={{ position: 'absolute', left: 0, top: 0, width: W, height: H, pointerEvents: 'none' }}>
        <path d="M 920 720 L 1056 720"
          fill="none" stroke={VC.copper} strokeWidth="3" opacity={pumpOp * 0.9} />
        <path d="M 920 740 L 1056 740"
          fill="none" stroke={VC.blue} strokeWidth="3" opacity={pumpOp * 0.9} />
      </svg>

      {/* Weather upper left, over the roof */}
      <Weather x={380} y={380} kind="sun" size={120} opacity={wxOp} value="+8°C UDE"/>

      {/* Thermostat lower left */}
      <Thermostat x={420} y={780} size={170} opacity={thOp} value={21}/>

      {/* Bottom caption */}
      <div style={{
        position: 'absolute', left: '50%', top: 990, transform: 'translateX(-50%)',
        fontFamily: VC.fontSans, fontSize: 22, color: VC.muted,
        opacity: capOp, textAlign: 'center', maxWidth: 1000,
      }}>
        Tre ting i konstant samspil — én algoritme finder balancen.
      </div>
    </div>
  );
}

// ── Scene 3: Klimaskærm (8..13) ───────────────────────────────────────────
function CSceneEnvelope() {
  const t = useTime() * 0.6;
  if (t < 7.8 || t > 14.6) return null;
  const op = fadeWindow(t, 8.0, 8.6, 13.8, 14.4);
  // Envelope outline draws in over time
  const envT = smooth(ramp(t, 8.6, 11.0));
  // sensor pings
  const pingT = ramp(t, 9.0, 12.6);

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <Tag x={W/2} y={120} align="center" color={VC.copper} opacity={op}>
        Trin 01 · Klimaskærmen
      </Tag>
      <Headline x={W/2} y={170} size={56} weight={500} align="center"
        color={VC.paper} opacity={op}>
        Lærer husets termiske personlighed.
      </Headline>

      {/* Top-down floor plan inside the envelope */}
      <svg style={{ position: 'absolute', left: 0, top: 0, width: W, height: H, pointerEvents: 'none' }}>
        {/* Outer floor outline (envelope = walls of the house, top-down) */}
        <rect x="660" y="380" width="600" height="500"
          fill="none" stroke={VC.copper} strokeWidth="1.6"
          strokeDasharray="6 8"
          pathLength={1} strokeDashoffset={1 - envT}
          opacity={op * 0.85} />
        {/* Inner solid wall fill (faint) — gives the rooms a sense of "floor" */}
        <rect x="660" y="380" width="600" height="500"
          fill={VC.ink2} opacity={op * 0.35} />
        {/* Interior walls — vertical with door gap, horizontal with door gap */}
        {(() => {
          const divT = smooth(ramp(t, 9.0, 10.4));
          return (
            <g opacity={op * divT}>
              {/* Vertical wall (centre) — split with a door gap from y=620..650 */}
              <line x1="960" y1="380" x2="960" y2="615"
                stroke={VC.paper} strokeWidth="2.4" strokeOpacity="0.85" />
              <line x1="960" y1="655" x2="960" y2="880"
                stroke={VC.paper} strokeWidth="2.4" strokeOpacity="0.85" />
              {/* Horizontal wall (middle) — split with a door gap from x=940..970 */}
              <line x1="660" y1="630" x2="935" y2="630"
                stroke={VC.paper} strokeWidth="2.4" strokeOpacity="0.85" />
              <line x1="985" y1="630" x2="1260" y2="630"
                stroke={VC.paper} strokeWidth="2.4" strokeOpacity="0.85" />
              {/* Front door gap on bottom wall */}
              <line x1="930" y1="880" x2="990" y2="880"
                stroke={VC.copper} strokeWidth="3" strokeOpacity="0.7" />
              {/* Door swing arc indicator */}
              <path d="M 930 880 A 60 60 0 0 1 930 820"
                fill="none" stroke={VC.copper} strokeWidth="0.8"
                strokeOpacity="0.5" strokeDasharray="2 3" />
            </g>
          );
        })()}
        {/* Heat flow vectors — both outward (loss) and inward (cold) */}
        {[
          // outward (heat escaping through walls / roof / floor)
          { x1: 660,  y1: 500, x2: 600,  y2: 500, dir: 'out' },
          { x1: 660,  y1: 760, x2: 600,  y2: 760, dir: 'out' },
          { x1: 1260, y1: 500, x2: 1320, y2: 500, dir: 'out' },
          { x1: 1260, y1: 760, x2: 1320, y2: 760, dir: 'out' },
          { x1: 800,  y1: 380, x2: 800,  y2: 320, dir: 'out' },
          { x1: 1120, y1: 380, x2: 1120, y2: 320, dir: 'out' },
          { x1: 800,  y1: 880, x2: 800,  y2: 940, dir: 'out' },
          { x1: 1120, y1: 880, x2: 1120, y2: 940, dir: 'out' },
          // inward (cold infiltration from outside)
          { x1: 540,  y1: 580, x2: 660,  y2: 580, dir: 'in' },
          { x1: 1380, y1: 580, x2: 1260, y2: 580, dir: 'in' },
          { x1: 880,  y1: 250, x2: 880,  y2: 380, dir: 'in' },
          { x1: 1040, y1: 250, x2: 1040, y2: 380, dir: 'in' },
          { x1: 880,  y1: 950, x2: 880,  y2: 880, dir: 'in' },
          { x1: 1040, y1: 950, x2: 1040, y2: 880, dir: 'in' },
        ].map((a, i) => {
          const aT = smooth(ramp(t, 10.6 + i * 0.08, 11.8 + i * 0.08));
          const x2 = a.x1 + (a.x2 - a.x1) * aT;
          const y2 = a.y1 + (a.y2 - a.y1) * aT;
          return (
            <g key={i} opacity={op * aT}>
              <line x1={a.x1} y1={a.y1} x2={x2} y2={y2}
                stroke={VC.blue} strokeWidth="1.4" strokeDasharray="4 4" />
              <circle cx={x2} cy={y2} r="3" fill={VC.blue} />
            </g>
          );
        })}
      </svg>

      {/* Outdoor temperature — cycles through values to show external variation */}
      {(() => {
        const samples = [
          { v: '+2°C', tone: 'cold' },
          { v: '+6°C', tone: 'mild' },
          { v: '+9°C', tone: 'warm' },
          { v: '+4°C', tone: 'mild' },
        ];
        const startT = 9.0, stepDur = 1.0;
        const idxRaw = Math.max(0, (t - startT) / stepDur);
        const idx = Math.min(samples.length - 1, Math.floor(idxRaw));
        const cur = samples[idx];
        const tColor = cur.tone === 'cold' ? VC.blue
                     : cur.tone === 'warm' ? VC.copper
                     : VC.muted;
        const tOp = fadeWindow(t, 9.0, 9.6, 13.8, 14.4);
        // small flash on change
        const inStep = idxRaw - idx;
        const flash = 1 - smooth(Math.min(1, inStep * 4));
        return (
          <div style={{
            position: 'absolute', left: 240, top: 380,
            opacity: tOp,
            display: 'flex', flexDirection: 'column', gap: 10,
            fontFamily: VC.fontMono,
          }}>
            <div style={{
              fontSize: 12, letterSpacing: '0.22em', color: VC.muted,
              textTransform: 'uppercase',
            }}>Udetemperatur</div>
            <div style={{
              fontFamily: VC.fontSans, fontSize: 56, fontWeight: 500,
              color: tColor, letterSpacing: '-0.02em', lineHeight: 1,
              transform: `translateX(${flash * -6}px)`,
            }}>{cur.v}</div>
            <div style={{
              fontSize: 11, letterSpacing: '0.16em', color: VC.mutedDim,
              textTransform: 'uppercase',
            }}>varierer · skifter konstant</div>
          </div>
        );
      })()}

      {/* Room labels INSIDE the envelope, in 2×2 grid */}
      {[{ x: 810, y: 505, label: 'Stue', temp: '21.2°' },
        { x: 1110, y: 505, label: 'Sove', temp: '19.8°' },
        { x: 810, y: 755, label: 'Køkken', temp: '21.5°' },
        { x: 1110, y: 755, label: 'Bad', temp: '22.0°' }].map((s, i) => {
        const sOp = fadeWindow(t, 9.4 + i * 0.2, 10.0 + i * 0.2, 13.8, 14.4);
        return (
          <div key={i} style={{
            position: 'absolute', left: s.x, top: s.y, transform: 'translate(-50%, -50%)',
            opacity: sOp,
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
          }}>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 6,
              fontFamily: VC.fontMono, fontSize: 11, color: VC.muted,
              letterSpacing: '0.18em', textTransform: 'uppercase',
            }}>
              <span style={{ width: 6, height: 6, borderRadius: 6, background: VC.copper }}/>
              {s.label}
            </div>
            <div style={{
              fontFamily: VC.fontSans, fontWeight: 500, fontSize: 26, color: VC.paper,
              letterSpacing: '-0.02em',
            }}>{s.temp}</div>
          </div>
        );
      })}

      {/* Caption */}
      <div style={{
        position: 'absolute', left: '50%', top: 990, transform: 'translateX(-50%)',
        fontFamily: VC.fontSans, fontSize: 22, color: VC.muted,
        opacity: op, textAlign: 'center', maxWidth: 1100,
      }}>
        Algoritmen lærer klimaskærmen — hvordan huset taber og holder varme.
      </div>
    </div>
  );
}

// ── Scene 3b: Solindstråling — store vinduespartier (13..18) ──────────────
function CSceneSolar() {
  const t = useTime() * 0.6 - 1.2;
  if (t < 12.8 || t > 19.6) return null;
  const op = fadeWindow(t, 13.0, 13.8, 18.8, 19.4);

  // Beat timeline (relative to scene start at t=13):
  //   13.0..14.0  plan re-establishes (envelope draws in)
  //   14.0..15.2  windows highlighted on Stue + Køkken
  //   15.0..15.8  sun rises in lower-left, clock advances 09:30 → 10:00
  //   15.8..16.8  sun rays cast through windows; solar-gain badges appear
  //   16.8..18.0  heat-demand reduction visualised; caption stable

  const envT  = smooth(ramp(t, 13.2, 14.0));
  const winT  = smooth(ramp(t, 14.0, 15.2));
  const sunT  = smooth(ramp(t, 15.0, 15.8));
  const rayT  = smooth(ramp(t, 15.8, 16.8));
  const gainT = smooth(ramp(t, 16.4, 17.2));
  const dropT = smooth(ramp(t, 17.0, 17.8));

  // Clock progresses 09:30 → 12:00 as sun rises
  const clockMin = lerp(9.5 * 60, 12 * 60, sunT);
  const hour     = Math.floor(clockMin / 60);
  const minute   = Math.floor(clockMin % 60);
  const clockStr = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;

  // Sun position — rises from below-left to upper-left (in sky outside the plan)
  const sunX = lerp(440, 480, sunT);
  const sunY = lerp(1020, 760, sunT);

  // Windows: STUE on west wall (big), KØKKEN on south wall (big).
  // Sove + Bad have small/no windows (north-side) → no solar gain.
  // Coords in the floor-plan rect (660..1260) × (380..880).
  // West wall x=660; window y=440..580 (big patio door for stue)
  // South wall y=880; window x=720..860 (big window for køkken)

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <Tag x={W/2} y={120} align="center" color={VC.copper} opacity={op}>
        Trin 01 · Solindstråling
      </Tag>
      <Headline x={W/2} y={170} size={56} weight={500} align="center"
        color={VC.paper} opacity={op}>
        Forudser solens varme.
      </Headline>

      <svg style={{ position: 'absolute', left: 0, top: 0, width: W, height: H, pointerEvents: 'none' }}>
        {/* Floor plan re-establishes */}
        <rect x="660" y="380" width="600" height="500"
          fill="none" stroke={VC.copper} strokeWidth="1.6"
          strokeDasharray="6 8" opacity={op * 0.85 * envT} />
        <rect x="660" y="380" width="600" height="500"
          fill={VC.ink2} opacity={op * 0.35 * envT} />
        {/* Interior walls */}
        <g opacity={op * envT}>
          <line x1="960" y1="380" x2="960" y2="615"
            stroke={VC.paper} strokeWidth="2.4" strokeOpacity="0.85" />
          <line x1="960" y1="655" x2="960" y2="880"
            stroke={VC.paper} strokeWidth="2.4" strokeOpacity="0.85" />
          <line x1="660" y1="630" x2="935" y2="630"
            stroke={VC.paper} strokeWidth="2.4" strokeOpacity="0.85" />
          <line x1="985" y1="630" x2="1260" y2="630"
            stroke={VC.paper} strokeWidth="2.4" strokeOpacity="0.85" />
        </g>

        {/* BIG WINDOWS — drawn as a thick gap in the wall, framed by short caps.
            STUE: west wall, y=440..580 (big patio door / picture window)
            KØKKEN: south wall, x=720..870 (big window onto garden) */}
        {/* Stue window */}
        <g opacity={op * winT}>
          {/* clear the dashed envelope where window sits */}
          <line x1="660" y1="440" x2="660" y2="580"
            stroke={VC.cream} strokeWidth="6" />
          {/* window frame caps */}
          <line x1="652" y1="440" x2="668" y2="440"
            stroke={VC.copper} strokeWidth="2.5" />
          <line x1="652" y1="580" x2="668" y2="580"
            stroke={VC.copper} strokeWidth="2.5" />
          {/* glass rendering — thin double line */}
          <line x1="657" y1="442" x2="657" y2="578"
            stroke={VC.copper} strokeWidth="1.4" strokeOpacity="0.9" />
          <line x1="663" y1="442" x2="663" y2="578"
            stroke={VC.copper} strokeWidth="1.4" strokeOpacity="0.5" />
        </g>
        {/* Køkken window */}
        <g opacity={op * winT}>
          <line x1="720" y1="880" x2="870" y2="880"
            stroke={VC.cream} strokeWidth="6" />
          <line x1="720" y1="872" x2="720" y2="888"
            stroke={VC.copper} strokeWidth="2.5" />
          <line x1="870" y1="872" x2="870" y2="888"
            stroke={VC.copper} strokeWidth="2.5" />
          <line x1="722" y1="877" x2="868" y2="877"
            stroke={VC.copper} strokeWidth="1.4" strokeOpacity="0.9" />
          <line x1="722" y1="883" x2="868" y2="883"
            stroke={VC.copper} strokeWidth="1.4" strokeOpacity="0.5" />
        </g>

        {/* Sun — disc + rays, outside the plan (sky) */}
        <g opacity={op * sunT}>
          <circle cx={sunX} cy={sunY} r="34" fill={VC.copper} opacity="0.95" />
          <circle cx={sunX} cy={sunY} r="56" fill="none"
            stroke={VC.copper} strokeWidth="1" strokeOpacity="0.4" />
          {Array.from({ length: 12 }).map((_, i) => {
            const a = (i / 12) * Math.PI * 2;
            const r1 = 44, r2 = 64;
            return (
              <line key={i}
                x1={sunX + Math.cos(a) * r1} y1={sunY + Math.sin(a) * r1}
                x2={sunX + Math.cos(a) * r2} y2={sunY + Math.sin(a) * r2}
                stroke={VC.copper} strokeWidth="2" strokeOpacity="0.7" />
            );
          })}
        </g>

        {/* Sun rays into the windows — diagonal beams */}
        {(() => {
          // 3 beams toward Stue window (hits y=460,510,560 on x=660)
          // 3 beams toward Køkken window (hits x=750,795,840 on y=880)
          const beams = [
            { tx: 660, ty: 460 }, { tx: 660, ty: 510 }, { tx: 660, ty: 560 },
            { tx: 760, ty: 880 }, { tx: 800, ty: 880 }, { tx: 845, ty: 880 },
          ];
          return beams.map((b, i) => {
            const bT = smooth(ramp(t, 15.8 + i * 0.08, 16.6 + i * 0.08));
            const x2 = lerp(sunX, b.tx, bT);
            const y2 = lerp(sunY, b.ty, bT);
            return (
              <line key={i}
                x1={sunX} y1={sunY} x2={x2} y2={y2}
                stroke={VC.copper} strokeWidth="1.6" strokeOpacity={op * bT * 0.6}
                strokeDasharray="3 5" />
            );
          });
        })()}

        {/* Solar-gain glow inside Stue + Køkken */}
        <defs>
          <radialGradient id="solar-stue" cx="0.15" cy="0.5" r="0.85">
            <stop offset="0" stopColor={VC.copper} stopOpacity="0.35" />
            <stop offset="1" stopColor={VC.copper} stopOpacity="0" />
          </radialGradient>
          <radialGradient id="solar-koekken" cx="0.3" cy="1" r="0.95">
            <stop offset="0" stopColor={VC.copper} stopOpacity="0.32" />
            <stop offset="1" stopColor={VC.copper} stopOpacity="0" />
          </radialGradient>
        </defs>
        <rect x="660" y="380" width="300" height="250"
          fill="url(#solar-stue)" opacity={op * gainT} />
        <rect x="660" y="630" width="300" height="250"
          fill="url(#solar-koekken)" opacity={op * gainT} />
      </svg>

      {/* Clock badge — bottom-left, near the sun */}
      <div style={{
        position: 'absolute', left: 200, top: 540, opacity: op * sunT,
      }}>
        <div style={{
          fontFamily: VC.fontMono, fontSize: 12, color: VC.muted,
          letterSpacing: '0.22em', textTransform: 'uppercase', marginBottom: 8,
        }}>Tid</div>
        <div style={{
          fontFamily: VC.fontMono, fontSize: 64, color: VC.copper,
          fontWeight: 500, letterSpacing: '-0.02em', lineHeight: 1,
        }}>{clockStr}</div>
        <div style={{
          fontFamily: VC.fontMono, fontSize: 11, color: VC.muted,
          letterSpacing: '0.18em', textTransform: 'uppercase', marginTop: 10,
          maxWidth: 240, lineHeight: 1.5,
        }}>Solindstråling forventet · vest- og sydvendte rum</div>
      </div>

      {/* Room labels with solar-gain status */}
      {[
        { x: 810,  y: 505, label: 'Stue',   base: 21.2, gain: true,  deltaN: 1.4 },
        { x: 1110, y: 505, label: 'Sove',   base: 19.8, gain: false, deltaN: 0   },
        { x: 810,  y: 755, label: 'Køkken', base: 21.5, gain: true,  deltaN: 1.1 },
        { x: 1110, y: 755, label: 'Bad',    base: 22.0, gain: false, deltaN: 0   },
      ].map((s, i) => {
        const sOp = fadeWindow(t, 13.6 + i * 0.15, 14.2 + i * 0.15, 18.8, 19.4);
        const badgeOp = s.gain ? smooth(ramp(t, 16.4, 17.2)) : 0;
        // Room temp rises with the sun: lerp from base → base+delta over gainT (15.8..17.4)
        const tempT = s.gain ? smooth(ramp(t, 15.8, 17.4)) : 0;
        const liveTemp = s.base + s.deltaN * tempT;
        const tempStr = liveTemp.toFixed(1) + '°';
        const deltaStr = s.gain ? `+${s.deltaN.toFixed(1)}°` : null;
        return (
          <div key={i} style={{
            position: 'absolute', left: s.x, top: s.y, transform: 'translate(-50%, -50%)',
            opacity: sOp,
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4,
          }}>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 6,
              fontFamily: VC.fontMono, fontSize: 11, color: VC.muted,
              letterSpacing: '0.18em', textTransform: 'uppercase',
            }}>
              <span style={{ width: 6, height: 6, borderRadius: 6, background: VC.copper }}/>
              {s.label}
            </div>
            <div style={{
              fontFamily: VC.fontSans, fontWeight: 500, fontSize: 26,
              color: s.gain && tempT > 0.05 ? VC.copper : VC.paper,
              letterSpacing: '-0.02em',
              transition: 'color 0.3s',
            }}>{tempStr}</div>
            {s.gain && (
              <div style={{
                opacity: badgeOp,
                marginTop: 4,
                fontFamily: VC.fontMono, fontSize: 10, color: VC.copper,
                letterSpacing: '0.16em', textTransform: 'uppercase',
                border: `1px solid ${VC.copper}55`, borderRadius: 999,
                padding: '4px 8px',
                background: `${VC.copper}12`,
              }}>
                ☀ Solgevinst {deltaStr}
              </div>
            )}
          </div>
        );
      })}

      {/* Heat-demand reduction strip — three small bars showing demand drop */}
      <div style={{
        position: 'absolute', left: 1380, top: 460, opacity: op * dropT,
        width: 360,
      }}>
        <div style={{
          fontFamily: VC.fontMono, fontSize: 11, color: VC.muted,
          letterSpacing: '0.18em', textTransform: 'uppercase', marginBottom: 14,
        }}>Varmebehov</div>
        {[
          { name: 'Stue',   before: 100, after: 60, gain: true  },
          { name: 'Sove',   before: 100, after: 100, gain: false },
          { name: 'Køkken', before: 100, after: 70, gain: true  },
          { name: 'Bad',    before: 100, after: 100, gain: false },
        ].map((b, i) => {
          const bT = smooth(ramp(t, 17.0 + i * 0.1, 17.8 + i * 0.1));
          const w = lerp(b.before, b.after, b.gain ? bT : 0);
          return (
            <div key={i} style={{ marginBottom: 12 }}>
              <div style={{
                display: 'flex', justifyContent: 'space-between',
                fontFamily: VC.fontMono, fontSize: 11, color: VC.muted,
                letterSpacing: '0.14em', textTransform: 'uppercase',
                marginBottom: 4,
              }}>
                <span>{b.name}</span>
                <span style={{ color: b.gain ? VC.copper : VC.muted }}>
                  {b.gain ? `−${b.before - Math.round(w)}%` : '—'}
                </span>
              </div>
              <div style={{
                position: 'relative', height: 4,
                background: `${VC.paper}22`, borderRadius: 4,
              }}>
                <div style={{
                  position: 'absolute', left: 0, top: 0, height: '100%',
                  width: `${w}%`, background: b.gain ? VC.copper : `${VC.paper}55`,
                  borderRadius: 4,
                }}/>
              </div>
            </div>
          );
        })}
      </div>

      {/* Caption */}
      <div style={{
        position: 'absolute', left: '50%', top: 990, transform: 'translateX(-50%)',
        fontFamily: VC.fontSans, fontSize: 22, color: VC.muted,
        letterSpacing: '-0.005em', textAlign: 'center', maxWidth: 1300,
        opacity: op,
      }}>
        Algoritmen holder igen med varmen i rum, der får solen gratis.
      </div>
    </div>
  );
}

// ── Scene 4: Lavest mulige fremløbstemperatur (shifted +5 → 17.8..30.4) ───
function CSceneFlowTemp() {
  const t = useTime() * 0.6 - 7.4;
  if (t < 12.8 || t > 26.0) return null;
  const op = fadeWindow(t, 13.0, 13.8, 25.2, 25.8);

  // Piecewise animation helper
  const piece = (segments, fallback = 0) => {
    for (let i = 0; i < segments.length; i++) {
      const s = segments[i];
      if (t < s.s) return i === 0 ? s.from : segments[i-1].to;
      if (t < s.e) return lerp(s.from, s.to, smooth(ramp(t, s.s, s.e)));
    }
    return segments[segments.length - 1].to;
  };

  // Flow temperature timeline
  const flow = piece([
    { s: 13.8, e: 15.6, from: 55, to: 32 }, // probe lower (overshoots)
    { s: 16.6, e: 17.8, from: 32, to: 34 }, // correct upward to optimal
    // settled at 34 between 17.8 and 21.0
    { s: 21.0, e: 22.4, from: 34, to: 42 }, // raise as it gets cold outside
    // settled at 42 between 22.4 and 23.6
    { s: 24.4, e: 25.0, from: 42, to: 34 }, // return to 38 as outside warms
  ]);

  // Indoor temperature (lags slightly)
  const indoor = piece([
    { s: 15.4, e: 16.8, from: 21.0, to: 20.4 }, // dips below setpoint
    { s: 17.0, e: 18.4, from: 20.4, to: 21.0 }, // recovers to setpoint
  ]);

  // Outdoor temperature
  const outdoor = piece([
    { s: 19.5, e: 21.0, from: 5,  to: -10 }, // cools to -10
    { s: 23.6, e: 24.4, from: -10, to: 5   }, // warms back
  ]);

  // Status text: which beat are we in?
  let status = 'Optimerer fremløbet';
  let statusColor = VC.muted;
  if (t < 13.8)              { status = 'Start · 55° fremløb'; statusColor = VC.muted; }
  else if (t < 15.6)         { status = 'Søger lavest mulige fremløb'; statusColor = VC.copper; }
  else if (t < 16.6)         { status = 'For lavt — komfort under sætpunkt'; statusColor = VC.blue; }
  else if (t < 17.8)         { status = 'Justerer op til optimalt sætpunkt'; statusColor = VC.copper; }
  else if (t < 19.5)         { status = 'Optimalt sætpunkt fundet · 34°'; statusColor = VC.green; }
  else if (t < 21.0)         { status = 'Udetemperatur falder mod -10°'; statusColor = VC.blue; }
  else if (t < 22.4)         { status = 'Hæver fremløb · klimaskærmen kender behovet'; statusColor = VC.copper; }
  else if (t < 23.6)         { status = 'Stabil drift · -10° ude / 42° fremløb'; statusColor = VC.green; }
  else if (t < 24.4)         { status = 'Udetemperatur stiger igen'; statusColor = VC.muted; }
  else                       { status = 'Vender tilbage til 34°'; statusColor = VC.copper; }

  // Comfort delta indicator
  const delta = indoor - 21.0;
  const indoorColor = Math.abs(delta) < 0.05 ? VC.green
                    : delta < 0 ? VC.blue : VC.copper;
  const deltaText = Math.abs(delta) < 0.05 ? 'PÅ SÆTPUNKT'
                  : (delta > 0 ? '+' : '') + delta.toFixed(1) + '° fra sætpunkt';

  // Outdoor color
  const outColor = outdoor < 0 ? VC.blue : outdoor < 4 ? VC.muted : VC.copper;

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <Tag x={W/2} y={120} align="center" color={VC.copper} opacity={op}>
        Trin 02 · Fremløbstemperatur
      </Tag>
      <Headline x={W/2} y={170} size={56} weight={500} align="center"
        color={VC.paper} opacity={op} maxWidth={1700}>
        Den lavest mulige fremløbstemperatur.
      </Headline>

      {/* Outdoor temperature badge — top-left, above house */}
      <div style={{
        position: 'absolute', left: 320, top: 360, transform: 'translateX(-50%)',
        opacity: op, display: 'flex', flexDirection: 'column',
        alignItems: 'center', gap: 6,
      }}>
        <div style={{
          fontFamily: VC.fontMono, fontSize: 12, color: VC.muted,
          letterSpacing: '0.22em', textTransform: 'uppercase',
        }}>Udetemperatur</div>
        <div style={{
          fontFamily: VC.fontSans, fontSize: 64, fontWeight: 500,
          color: outColor, letterSpacing: '-0.02em', lineHeight: 1,
        }}>{outdoor > 0 ? '+' : ''}{outdoor.toFixed(0)}°<span style={{ fontSize: 28, color: VC.mutedDim }}>C</span></div>
      </div>

      {/* House on left, with dynamic indoor temp */}
      <CopHouse x={620} y={620} size={460} drawT={1} opacity={op}
        indoorTemp={indoor.toFixed(1) + '°'}/>

      {/* Comfort delta indicator below house */}
      <div style={{
        position: 'absolute', left: 620, top: 880, transform: 'translateX(-50%)',
        opacity: op, display: 'flex', flexDirection: 'column',
        alignItems: 'center', gap: 4,
      }}>
        <div style={{
          fontFamily: VC.fontMono, fontSize: 13, color: indoorColor,
          letterSpacing: '0.18em', textTransform: 'uppercase',
        }}>Komfort · {indoor.toFixed(1)}°</div>
        <div style={{
          fontFamily: VC.fontMono, fontSize: 11, color: VC.mutedDim,
          letterSpacing: '0.16em', textTransform: 'uppercase',
        }}>{deltaText}</div>
      </div>

      {/* Connecting pipe from house to gauge */}
      <svg style={{ position: 'absolute', left: 0, top: 0, width: W, height: H, pointerEvents: 'none' }}>
        <path d="M 850 640 Q 1000 640 1100 640" fill="none"
          stroke={VC.copper} strokeWidth="3" opacity={op * 0.55} strokeDasharray="2 6"/>
      </svg>

      {/* Status caption — center, between house and gauge */}
      <div style={{
        position: 'absolute', left: 1000, top: 540, transform: 'translate(-50%, -50%)',
        opacity: op, width: 360, textAlign: 'center',
        display: 'flex', flexDirection: 'column', gap: 8,
      }}>
        <div style={{
          fontFamily: VC.fontMono, fontSize: 12, color: VC.mutedDim,
          letterSpacing: '0.22em', textTransform: 'uppercase',
        }}>Algoritmen</div>
        <div style={{
          fontFamily: VC.fontSans, fontSize: 22, fontWeight: 500, color: statusColor,
          letterSpacing: '-0.005em', lineHeight: 1.25,
        }}>{status}</div>
      </div>

      {/* Flow gauge on right */}
      <FlowGauge x={1320} y={340} height={520}
        value={flow} opacity={op}/>

      <div style={{
        position: 'absolute', left: 1320, top: 870, transform: 'translateX(-50%)',
        fontFamily: VC.fontMono, fontSize: 14, color: VC.muted,
        letterSpacing: '0.16em', textAlign: 'center', opacity: op,
      }}>
        VARMERE VAND TIL HUSET = LAVERE COP
      </div>

      <div style={{
        position: 'absolute', left: '50%', top: 990, transform: 'translateX(-50%)',
        fontFamily: VC.fontSans, fontSize: 22, color: VC.muted,
        opacity: op, textAlign: 'center', maxWidth: 1300,
      }}>
        Lavere fremløb → højere COP. Udetemperaturen ændrer regnestykket — VikingHeat justerer selv.
      </div>
    </div>
  );
}

// ── Scene 5: Udetemperatur + COP-kurve (19..24) ───────────────────────────
function CSceneOutdoor() {
  const t = useTime() * 0.6 - 14.0;
  if (t < 18.8 || t > 24.4) return null;
  const op = fadeWindow(t, 19.0, 19.6, 23.6, 24.2);
  // COP curve reveal across 19.6..22.0
  const drawT = smooth(ramp(t, 19.8, 22.4));

  // 24-hour timeline (00..24). Outdoor temp curve and COP curve.
  const plotX = 360, plotY = 380, plotW = 1200, plotH = 420;
  const N = 60;
  // Outdoor temp shape: -2 at midnight, peak ~10 at 14:00, back to 0 at 23
  const tempAt = (h) => -2 + 12 * Math.exp(-Math.pow((h - 14) / 6, 2));
  // COP shape: tracks temp, scaled
  const copAt  = (h) => 2.4 + 0.18 * tempAt(h) + 0.05 * Math.sin(h * 0.6);

  const tempPts = [], copPts = [];
  for (let i = 0; i < N; i++) {
    const h = (i / (N - 1)) * 24;
    const x = plotX + (i / (N - 1)) * plotW;
    // Map temp range -4..14 to plot bottom..middle
    const tNorm = (tempAt(h) - (-4)) / (14 - (-4));
    const yT = plotY + plotH - tNorm * plotH * 0.55 - 60;
    tempPts.push([x, yT]);
    // Map COP 1.5..5 to plot top..(middle)
    const cNorm = (copAt(h) - 1.5) / (5 - 1.5);
    const yC = plotY + plotH - cNorm * plotH * 0.85;
    copPts.push([x, yC]);
  }

  // Reveal cut
  const cut = Math.max(2, Math.floor(N * drawT));
  const tempDraw = tempPts.slice(0, cut);
  const copDraw = copPts.slice(0, cut);

  // "best window" indicator: 11..16
  const bestStart = plotX + (11 / 24) * plotW;
  const bestEnd   = plotX + (16 / 24) * plotW;
  const winOp = fadeWindow(t, 22.0, 22.6, 23.6, 24.2);

  // x ticks: 0, 6, 12, 18, 24
  const xTicks = [0, 6, 12, 18, 24].map((h) => ({
    x: (h / 24) * plotW, label: `${String(h).padStart(2, '0')}:00`,
  }));

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <Tag x={W/2} y={120} align="center" color={VC.copper} opacity={op}>
        Trin 03 · Udetemperatur
      </Tag>
      <Headline x={W/2} y={170} size={56} weight={500} align="center"
        color={VC.paper} opacity={op} maxWidth={1700}>
        Højere udeluft → højere COP.
      </Headline>

      {/* Plot frame */}
      <div style={{ position: 'absolute', left: plotX, top: plotY, opacity: op }}>
        <PlotFrame x={0} y={0} w={plotW} h={plotH}
          xLabel="DØGNETS 24 TIMER" yLeftLabel="UDETEMPERATUR" yRightLabel="COP"
          xTicks={xTicks}>
          {/* best window highlight */}
          <rect x={bestStart - plotX} y="0" width={bestEnd - bestStart} height={plotH}
            fill={VC.copper} opacity={winOp * 0.10} />
          {/* outdoor temp curve (blue) */}
          <path d={buildPath(tempDraw)} fill="none"
            stroke={VC.blue} strokeWidth="2.4" strokeOpacity="0.95"
            strokeLinejoin="round" strokeLinecap="round"
            transform={`translate(${-plotX}, ${-plotY})`} />
          {/* COP curve (copper) */}
          <path d={buildPath(copDraw)} fill="none"
            stroke={VC.copper} strokeWidth="3.2"
            strokeLinejoin="round" strokeLinecap="round"
            transform={`translate(${-plotX}, ${-plotY})`} />
        </PlotFrame>
      </div>

      {/* Best-window labels */}
      {winOp > 0 && (
        <div style={{
          position: 'absolute', left: (bestStart + bestEnd) / 2, top: plotY - 36,
          transform: 'translateX(-50%)', opacity: winOp,
          fontFamily: VC.fontMono, fontSize: 13, color: VC.copper,
          letterSpacing: '0.18em', textTransform: 'uppercase', whiteSpace: 'nowrap',
        }}>★ Varmest udeluft</div>
      )}

      {/* Legend */}
      <div style={{
        position: 'absolute', left: plotX, top: plotY + plotH + 60,
        display: 'flex', gap: 32, opacity: op,
        fontFamily: VC.fontMono, fontSize: 13, letterSpacing: '0.12em',
        color: VC.muted, textTransform: 'uppercase',
      }}>
        <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ width: 22, height: 2, background: VC.blue }}/> Udetemperatur
        </span>
        <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ width: 22, height: 3, background: VC.copper }}/> COP
        </span>
      </div>

      {/* Heat pump indicator pulses during best window */}
      <div style={{ position: 'absolute', right: 220, top: plotY - 10, opacity: op }}>
        <HeatPump x={0} y={60} size={140} opacity={1} spinning={winOp > 0.3}/>
      </div>
    </div>
  );
}

// ── Scene 6: Elprisen (24..30) ────────────────────────────────────────────
function CScenePrice() {
  const t = useTime() * 0.6 - 14.0;
  if (t < 23.8 || t > 30.4) return null;
  const op = fadeWindow(t, 24.0, 24.6, 29.6, 30.2);
  // Price curve reveal 24.6..26.6
  const drawT = smooth(ramp(t, 24.8, 27.0));

  const plotX = 360, plotY = 380, plotW = 1200, plotH = 420;
  const N = 60;
  // Price shape: high in morning peak (07..09) and evening (17..20), low at midday (solar) and night
  const priceAt = (h) => {
    const morn = 0.55 * Math.exp(-Math.pow((h - 8) / 1.6, 2));
    const eve  = 0.85 * Math.exp(-Math.pow((h - 18.5) / 2.0, 2));
    const base = 0.18;
    const midDip = 0.10 * Math.exp(-Math.pow((h - 13) / 2.5, 2));
    return Math.max(0, base + morn + eve - midDip);
  };
  // Same COP curve as previous scene
  const tempAt = (h) => -2 + 12 * Math.exp(-Math.pow((h - 14) / 6, 2));
  const copAt  = (h) => 2.4 + 0.18 * tempAt(h) + 0.05 * Math.sin(h * 0.6);

  const pricePts = [], copPts = [];
  for (let i = 0; i < N; i++) {
    const h = (i / (N - 1)) * 24;
    const x = plotX + (i / (N - 1)) * plotW;
    const pNorm = priceAt(h) / 1.4;
    const yP = plotY + plotH - pNorm * plotH * 0.85;
    pricePts.push([x, yP]);
    const cNorm = (copAt(h) - 1.5) / (5 - 1.5);
    const yC = plotY + plotH - cNorm * plotH * 0.85;
    copPts.push([x, yC]);
  }
  const cut = Math.max(2, Math.floor(N * drawT));
  const priceDraw = pricePts.slice(0, cut);

  const xTicks = [0, 6, 12, 18, 24].map((h) => ({
    x: (h / 24) * plotW, label: `${String(h).padStart(2, '0')}:00`,
  }));

  // Sweet spot — where COP is high AND price is low. Best at h=13
  const sweetH = 13;
  const sweetX = plotX + (sweetH / 24) * plotW;
  const sweetCNorm = (copAt(sweetH) - 1.5) / (5 - 1.5);
  const sweetY = plotY + plotH - sweetCNorm * plotH * 0.85;
  const sweetOp = fadeWindow(t, 27.4, 28.2, 29.6, 30.2);

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <Tag x={W/2} y={120} align="center" color={VC.copper} opacity={op}>
        Trin 04 · Elprisen
      </Tag>
      <Headline x={W/2} y={170} size={56} weight={500} align="center"
        color={VC.paper} opacity={op}>
        Lav pris × høj COP = sweet spot.
      </Headline>

      <div style={{ position: 'absolute', left: plotX, top: plotY, opacity: op }}>
        <PlotFrame x={0} y={0} w={plotW} h={plotH}
          xLabel="DØGNETS 24 TIMER" yLeftLabel="ELPRIS" yRightLabel="COP"
          xTicks={xTicks}>
          {/* COP curve (faint, persistent) */}
          <path d={buildPath(copPts)} fill="none"
            stroke={VC.copper} strokeWidth="3" strokeOpacity="0.85"
            strokeLinejoin="round" strokeLinecap="round"
            transform={`translate(${-plotX}, ${-plotY})`} />
          {/* Price curve (green, animated) */}
          <path d={buildPath(priceDraw)} fill="none"
            stroke={VC.green} strokeWidth="2.6"
            strokeLinejoin="round" strokeLinecap="round"
            transform={`translate(${-plotX}, ${-plotY})`} />
          {/* Sweet spot crosshair */}
          {sweetOp > 0 && (
            <g transform={`translate(${-plotX}, ${-plotY})`} opacity={sweetOp}>
              <line x1={sweetX} y1={plotY} x2={sweetX} y2={plotY + plotH}
                stroke={VC.copper} strokeWidth="1" strokeDasharray="3 4" opacity="0.55"/>
              <circle cx={sweetX} cy={sweetY} r="14" fill="none"
                stroke={VC.copper} strokeWidth="2" />
              <circle cx={sweetX} cy={sweetY} r="6" fill={VC.copper} />
            </g>
          )}
          {/* Money coins on price curve — progressively as the green line passes each x */}
          {(() => {
            const priceY = (h) => {
              const pNorm = priceAt(h) / 1.4;
              return plotY + plotH - pNorm * plotH * 0.85;
            };
            const groups = [
              { h: 8.0,  count: 2 },
              { h: 13.0, count: 1 },
              { h: 18.5, count: 3 },
            ];
            return (
              <g transform={`translate(${-plotX}, ${-plotY})`}>
                {groups.map((g, gi) => {
                  const x = plotX + (g.h / 24) * plotW;
                  const yBase = priceY(g.h);
                  // Appears once the green line has reached this h
                  const triggerStart = 24.8 + (g.h / 24) * 2.2;
                  return Array.from({ length: g.count }).map((_, j) => {
                    const cT = smooth(ramp(t, triggerStart + j * 0.10, triggerStart + 0.5 + j * 0.10));
                    if (cT <= 0) return null;
                    const offset = 30 + j * 30;
                    const cy = yBase - offset; // always above the curve
                    return (
                      <g key={`${gi}-${j}`} opacity={cT}
                        transform={`translate(${x}, ${cy})`}>
                        <circle r="15" fill={VC.green} />
                        <circle r="15" fill="none"
                          stroke={VC.cream} strokeWidth="1.2" strokeOpacity="0.55" />
                        <circle r="11" fill="none"
                          stroke={VC.cream} strokeWidth="0.8" strokeOpacity="0.45" />
                        <text x="0" y="6" textAnchor="middle"
                          fontFamily={VC.fontSans} fontSize="18" fontWeight="600"
                          fill={VC.cream} letterSpacing="-0.02em">€</text>
                      </g>
                    );
                  });
                })}
              </g>
            );
          })()}
          {/* COP marker dots — appear progressively along the orange curve */}
          {(() => {
            const copY = (h) => {
              const cNorm = (copAt(h) - 1.5) / (5 - 1.5);
              return plotY + plotH - cNorm * plotH * 0.85;
            };
            const dots = [
              { h: 2,  trigger: 24.6 },
              { h: 22, trigger: 28.4 },
            ];
            return (
              <g transform={`translate(${-plotX}, ${-plotY})`}>
                {dots.map((d, i) => {
                  const dT = smooth(ramp(t, d.trigger, d.trigger + 0.5));
                  if (dT <= 0) return null;
                  const x = plotX + (d.h / 24) * plotW;
                  const y = copY(d.h);
                  return <circle key={i} cx={x} cy={y} r="5"
                    fill={VC.copper} stroke={VC.cream} strokeWidth="2"
                    opacity={dT} />;
                })}
              </g>
            );
          })()}
        </PlotFrame>
      </div>

      {/* Sweet spot label */}
      {sweetOp > 0 && (
        <div style={{
          position: 'absolute', left: sweetX, top: sweetY - 70,
          transform: 'translateX(-50%)', opacity: sweetOp,
          padding: '6px 14px', background: VC.copper, color: VC.ink,
          fontFamily: VC.fontMono, fontSize: 13, letterSpacing: '0.16em',
          textTransform: 'uppercase', whiteSpace: 'nowrap', borderRadius: 2,
        }}>★ Sweet spot · 4,7 COP</div>
      )}

      {/* COP value labels at start (low), right end — appear progressively */}
      {(() => {
        const copY = (h) => {
          const cNorm = (copAt(h) - 1.5) / (5 - 1.5);
          return plotY + plotH - cNorm * plotH * 0.85;
        };
        const labels = [
          { h: 2,  val: '3,2 COP', dx: 18,  dy: -34, alignRight: false, trigger: 24.6 },
          { h: 22, val: '3,8 COP', dx: 24,  dy: -34, alignRight: false, trigger: 26.2 },
        ];
        return labels.map((l, i) => {
          const lT = fadeWindow(t, l.trigger, l.trigger + 0.6, 29.6, 30.2);
          if (lT <= 0) return null;
          const x = plotX + (l.h / 24) * plotW;
          const y = copY(l.h);
          return (
            <div key={i} style={{
              position: 'absolute', left: x + l.dx, top: y + l.dy,
              transform: l.alignRight ? 'translateX(-100%)' : 'translateX(0)',
              opacity: lT,
              fontFamily: VC.fontMono, fontSize: 16, fontWeight: 500,
              color: VC.copper, letterSpacing: '0.04em',
              padding: '4px 10px',
              background: `${VC.cream}cc`, borderRadius: 2,
              border: `1px solid ${VC.copper}55`,
              whiteSpace: 'nowrap',
            }}>{l.val}</div>
          );
        });
      })()}

      {/* Legend */}
      <div style={{
        position: 'absolute', left: plotX, top: plotY + plotH + 60,
        display: 'flex', gap: 32, opacity: op,
        fontFamily: VC.fontMono, fontSize: 13, letterSpacing: '0.12em',
        color: VC.muted, textTransform: 'uppercase',
      }}>
        <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ width: 22, height: 3, background: VC.copper }}/> COP
        </span>
        <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ width: 22, height: 2, background: VC.green }}/> Spotpris
        </span>
      </div>
    </div>
  );
}

// ── Scene 7: Formel (30..34) ──────────────────────────────────────────────
function CSceneFormula() {
  const t = useTime() * 0.6 - 14.0;
  if (t < 29.8 || t > 35.0) return null;
  const op = fadeWindow(t, 30.0, 30.6, 34.2, 34.8);
  const f1Op = fadeWindow(t, 30.4, 31.0, 34.2, 34.8);
  const eqOp = fadeWindow(t, 31.4, 32.0, 34.2, 34.8);
  const checkOp = fadeWindow(t, 32.6, 33.2, 34.2, 34.8);

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <Tag x={W/2} y={180} align="center" color={VC.copper} opacity={op}>
        Sammensætningen
      </Tag>
      <Headline x={W/2} y={240} size={56} weight={500} align="center"
        color={VC.paper} opacity={op}>
        Mange udregninger — ét sweet spot.
      </Headline>

      {/* Formula row */}
      <div style={{
        position: 'absolute', left: '50%', top: 480, transform: 'translateX(-50%)',
        display: 'flex', alignItems: 'center', gap: 32, opacity: f1Op,
        fontFamily: VC.fontSans, fontWeight: 500, color: VC.paper,
      }}>
        <FormulaTerm color={VC.copper} title="HØJESTE" value="COP"/>
        <Operator>×</Operator>
        <FormulaTerm color={VC.green} title="LAVESTE" value="ELPRIS"/>
        <span style={{ opacity: eqOp, fontSize: 80, fontWeight: 300, color: VC.muted }}>=</span>
        <FormulaTerm color={VC.paper} title="STØRSTE" value="BESPARELSE" opacity={eqOp}/>
      </div>

      {/* Constraint pill */}
      <div style={{
        position: 'absolute', left: '50%', top: 740, transform: 'translateX(-50%)',
        opacity: eqOp,
        padding: '14px 36px', border: `1px solid ${VC.line}`,
        background: 'rgba(232,123,69,0.06)', borderRadius: 999,
        fontFamily: VC.fontMono, fontSize: 14, letterSpacing: '0.18em',
        color: VC.copper, textTransform: 'uppercase', whiteSpace: 'nowrap',
      }}>
        Begrænsning · Komforten påvirkes ikke
      </div>

      {/* Sweet spot tick */}
      <div style={{
        position: 'absolute', left: '50%', top: 860, transform: 'translateX(-50%)',
        opacity: checkOp,
        display: 'flex', alignItems: 'center', gap: 14,
        fontFamily: VC.fontSans, fontSize: 28, color: VC.paper,
      }}>
        <svg width="40" height="40" viewBox="0 0 40 40">
          <circle cx="20" cy="20" r="18" fill={VC.copper}/>
          <path d="M 12 20 L 18 26 L 28 14" fill="none" stroke={VC.ink}
            strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
        <span>Sweet spot fundet — sikker drift bevaret.</span>
      </div>
    </div>
  );
}

function FormulaTerm({ color, title, value, opacity = 1 }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8, opacity }}>
      <div style={{
        fontFamily: VC.fontMono, fontSize: 13, color, letterSpacing: '0.20em',
        textTransform: 'uppercase',
      }}>{title}</div>
      <div style={{
        fontFamily: VC.fontSans, fontWeight: 500, fontSize: 56, color: VC.paper,
        letterSpacing: '-0.02em',
      }}>{value}</div>
      <div style={{ width: 40, height: 2, background: color }}/>
    </div>
  );
}

function Operator({ children }) {
  return (
    <span style={{
      fontFamily: VC.fontSans, fontWeight: 300, fontSize: 80,
      color: VC.muted, marginTop: -12,
    }}>{children}</span>
  );
}

// ── Scene 8: Prioritering (34..38) ────────────────────────────────────────
function CScenePriority() {
  const t = useTime() * 0.6 - 14.6;
  if (t < 33.8 || t > 38.4) return null;
  const op = fadeWindow(t, 34.0, 34.6, 37.6, 38.2);
  const r1Op = fadeWindow(t, 34.6, 35.2, 37.6, 38.2);
  const r2Op = fadeWindow(t, 35.6, 36.2, 37.6, 38.2);

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <Tag x={W/2} y={180} align="center" color={VC.copper} opacity={op}>
        Prioritering
      </Tag>
      <Headline x={W/2} y={240} size={56} weight={500} align="center"
        color={VC.paper} opacity={op}>
        Først komforten. Så besparelsen.
      </Headline>

      <PriorityRow
        x={W/2} y={500} index="01" title="Sikker drift & komfort"
        sub="Den ønskede temperatur holdes — under alle forhold."
        emphasis opacity={r1Op}/>

      <PriorityRow
        x={W/2} y={720} index="02" title="Størst mulig besparelse"
        sub="Når komforten er sikret, jagter algoritmen sweet spottet."
        opacity={r2Op}/>
    </div>
  );
}

function PriorityRow({ x, y, index, title, sub, emphasis = false, opacity = 1 }) {
  return (
    <div style={{
      position: 'absolute', left: x, top: y, transform: 'translateX(-50%)',
      width: 1700, opacity,
      border: `1px solid ${emphasis ? VC.copper : VC.line}`,
      background: emphasis ? 'rgba(232,123,69,0.08)' : 'rgba(255,255,255,0.02)',
      padding: '32px 48px', borderRadius: 4,
      display: 'flex', alignItems: 'center', gap: 36,
    }}>
      <div style={{
        fontFamily: VC.fontMono, fontSize: 18, color: emphasis ? VC.copper : VC.muted,
        letterSpacing: '0.18em', minWidth: 56,
      }}>{index}</div>
      <div style={{ flex: 1 }}>
        <div style={{
          fontFamily: VC.fontSans, fontWeight: 500, fontSize: emphasis ? 48 : 40,
          color: VC.paper, letterSpacing: '-0.02em', lineHeight: 1.05,
        }}>{title}</div>
        <div style={{
          fontFamily: VC.fontSans, fontSize: 20, color: VC.muted, marginTop: 10,
        }}>{sub}</div>
      </div>
      {emphasis && (
        <div style={{
          fontFamily: VC.fontMono, fontSize: 12, color: VC.copper,
          letterSpacing: '0.18em', textTransform: 'uppercase',
          padding: '8px 14px', border: `1px solid ${VC.copper}`, borderRadius: 999,
        }}>UKRÆNKELIG</div>
      )}
    </div>
  );
}

// ── Scene 9: Start-stop (38..43) ──────────────────────────────────────────
function CSceneStartStop() {
  const t = useTime() * 0.6 - 14.6;
  if (t < 37.8 || t > 44.8) return null;
  const op = fadeWindow(t, 38.0, 38.6, 44.2, 44.8);
  const drawT = smooth(ramp(t, 38.6, 41.4));
  const ppOp = fadeWindow(t, 39.0, 39.6, 44.2, 44.8);
  const benOp = fadeWindow(t, 41.6, 42.2, 44.2, 44.8);
  // Sequential highlights — box 1 → 2 → 3, then 2-sec hold before fade
  const hl1 = smooth(ramp(t, 42.4, 42.7));
  const hl2 = smooth(ramp(t, 42.7, 43.0));
  const hl3 = smooth(ramp(t, 43.0, 43.3));

  return (
    <div style={{ position: 'absolute', inset: 0 }}>
      <Tag x={W/2} y={120} align="center" color={VC.copper} opacity={op}>
        Færre start-stop
      </Tag>
      <Headline x={W/2} y={170} size={56} weight={500} align="center"
        color={VC.paper} opacity={op}>
        Hver opstart koster strøm.
      </Headline>
      <div style={{
        position: 'absolute', left: '50%', top: 250, transform: 'translateX(-50%)',
        opacity: op,
        fontFamily: VC.fontSans, fontSize: 22, color: VC.muted,
        letterSpacing: '-0.005em', textAlign: 'center', maxWidth: 1300,
        lineHeight: 1.45,
      }}>
        Trykket i kølekredsen samt stabil drift tager oftest 5–10 minutter
        fra slukket tilstand.
      </div>

      {/* Heat pump on left */}
      <HeatPump x={260} y={620} size={220} opacity={ppOp} spinning/>
      <div style={{
        position: 'absolute', left: 260, top: 770, transform: 'translateX(-50%)',
        opacity: ppOp,
        fontFamily: VC.fontMono, fontSize: 14, color: VC.muted,
        letterSpacing: '0.16em', textTransform: 'uppercase', textAlign: 'center',
      }}>STRØMFORBRUG</div>

      {/* Power graph — conventional */}
      <div style={{
        position: 'absolute', left: 460, top: 380, opacity: op,
        fontFamily: VC.fontMono, fontSize: 13, color: VC.mutedDim,
        letterSpacing: '0.16em', textTransform: 'uppercase',
      }}>Konventionel styring · mange opstart</div>
      <div style={{ position: 'absolute', left: 460, top: 414, width: 1300, height: 140, opacity: op }}>
        <PowerGraph x={0} y={0} w={1300} h={140} drawT={drawT} opacity={1}/>
      </div>

      {/* Power graph — VikingHeat */}
      <div style={{
        position: 'absolute', left: 460, top: 600, opacity: op,
        fontFamily: VC.fontMono, fontSize: 13, color: VC.copper,
        letterSpacing: '0.16em', textTransform: 'uppercase',
      }}>VikingHeat · få og blide cyklusser</div>
      <div style={{ position: 'absolute', left: 460, top: 634, width: 1300, height: 140, opacity: op }}>
        <PowerGraph x={0} y={0} w={1300} h={140} drawT={drawT} opacity={1} variant="smooth"/>
      </div>

      {/* Benefits row */}
      <div style={{
        position: 'absolute', left: '50%', top: 880, transform: 'translateX(-50%)',
        opacity: benOp, display: 'flex', gap: 28, alignItems: 'stretch',
      }}>
        {[
          { k: '↓', l: 'Lavere forbrug', hl: hl1 },
          { k: '⏱', l: 'Længere levetid', hl: hl2 },
          { k: '★', l: 'Stabil komfort', hl: hl3 },
        ].map((b, i) => (
          <div key={i} style={{
            padding: '14px 24px',
            border: `1px solid ${b.hl > 0.05 ? VC.copper : VC.line}`,
            borderRadius: 4,
            background: b.hl > 0.05
              ? `rgba(217, 119, 87, ${0.06 + b.hl * 0.16})`
              : 'rgba(255,255,255,0.03)',
            boxShadow: b.hl > 0.05
              ? `0 0 ${20 * b.hl}px rgba(217, 119, 87, ${0.25 * b.hl})`
              : 'none',
            display: 'flex', alignItems: 'center', gap: 14,
            transition: 'background 0.2s, border-color 0.2s, box-shadow 0.2s',
          }}>
            <div style={{
              fontFamily: VC.fontSans, fontSize: 28, color: VC.copper, lineHeight: 1,
            }}>{b.k}</div>
            <div style={{
              fontFamily: VC.fontSans, fontSize: 20,
              color: b.hl > 0.05 ? VC.copper : VC.paper,
              fontWeight: 500,
              transition: 'color 0.2s',
            }}>{b.l}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, {
  CSceneTitle, CSceneSetup, CSceneEnvelope, CSceneSolar, CSceneFlowTemp,
  CSceneOutdoor, CScenePrice, CSceneFormula, CScenePriority,
  CSceneStartStop,
});
