'use client' import { useDarkMode } from '@/components/interactive-demo/demo-speak' /** * T–s diagram of the Carnot cycle — canonical 2nd-law diagram. * Driven by AnimPlayerShell via `step` (0..4). SVG, transform/opacity only. * Cycle = rectangle: horizontal isotherms (Th, Tc), vertical adiabatics. */ const X0 = 110 // y-axis x const Y0 = 280 // x-axis y const S1 = 190 // entropy left const S2 = 520 // entropy right const YH = 80 // T_h line y const YC = 220 // T_c line y const EASE = 'transform 700ms cubic-bezier(0.22, 1, 0.36, 1), opacity 500ms ease' // marker position per beat (end of each phase) const MARKER = [ { x: S2, y: YH }, // b1 end: right-top { x: S2, y: YC }, // b2 end: right-bottom { x: S1, y: YC }, // b3 end: left-bottom { x: S1, y: YH }, // b4 end: left-top { x: S1, y: YH }, // b5: stay ] export function TsDiagramView({ step, lang }: { step: number; lang: string }) { const fr = lang.startsWith('fr') const dark = useDarkMode() const s = Math.min(step, 4) const ink = dark ? '#EDE7DB' : '#242422' const muted = dark ? '#A39C8D' : '#686762' const plum = dark ? '#D07AA6' : '#9F3F70' const blue = dark ? '#7FA8CC' : '#3F6F9F' const paper = dark ? '#17140F' : '#F4F0E8' const m = MARKER[s] const qhW = S2 - S1 return ( {/* axes */} s T {/* isotherm T_h */} T_h {/* isotherm T_c */} T_c {/* Q_h area (beat ≥ 0, shown from beat 0) */} = 0 ? 0.10 : 0} style={{ transition: 'opacity 600ms ease' }} /> {s === 0 ? ( Q_h ) : null} {/* Q_c area (from beat 2) */} = 2 ? 0.16 : 0} style={{ transition: 'opacity 600ms ease' }} /> {s >= 2 && s < 4 ? ( Q_c ) : null} {/* W = cycle area (beat 4) */} {s === 4 ? ( W ) : null} {/* cycle edges, drawn progressively */} {/* top: b1 (isothermal expansion) */} = 0 ? 1 : 0.15} /> = 0 ? 1 : 0.15} /> {/* right: b2 (adiabatic expansion) */} = 1 ? 1 : 0.15} style={{ transition: 'opacity 500ms ease' }} /> = 1 ? 1 : 0.15} style={{ transition: 'opacity 500ms ease' }} /> {/* bottom: b3 (isothermal compression) */} = 2 ? 1 : 0.15} style={{ transition: 'opacity 500ms ease' }} /> = 2 ? 1 : 0.15} style={{ transition: 'opacity 500ms ease' }} /> {/* left: b4 (adiabatic compression) */} = 3 ? 1 : 0.15} style={{ transition: 'opacity 500ms ease' }} /> = 3 ? 1 : 0.15} style={{ transition: 'opacity 500ms ease' }} /> {/* entropy ticks */} s₁ s₂ {/* state marker */} ) }