Update assumption toggle component
This commit is contained in:
Vendored
+143
-127
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+30
-5
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useRef, useState, type CSSProperties } from 'react';
|
||||
import { useEffect, useLayoutEffect, useRef, useState, type CSSProperties } from 'react';
|
||||
import frameImage from '../technoborder.png';
|
||||
import { SOUND_IDS, safeEmit, safePlaySound, safeStopSound } from './hostBridge';
|
||||
import type { GlitchComponentProps } from './types';
|
||||
@@ -326,6 +326,7 @@ export default function AssumptionToggle({
|
||||
className,
|
||||
host
|
||||
}: GlitchComponentProps) {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const [toggleState, setToggleState] = useState<ToggleState>(() => readToggleState(config.params));
|
||||
const [screen, setScreen] = useState<Screen>('splash');
|
||||
const [transitionState, setTransitionState] = useState<TransitionState>('');
|
||||
@@ -336,6 +337,7 @@ export default function AssumptionToggle({
|
||||
);
|
||||
const [completedLines, setCompletedLines] = useState<string[]>([]);
|
||||
const [activeLine, setActiveLine] = useState('');
|
||||
const [containerScale, setContainerScale] = useState(1);
|
||||
const timeoutsRef = useRef<number[]>([]);
|
||||
const hostRef = useRef(host);
|
||||
const onCompleteRef = useRef(onComplete);
|
||||
@@ -351,6 +353,29 @@ export default function AssumptionToggle({
|
||||
onProgressRef.current = onProgress;
|
||||
}, [host, onComplete, onProgress]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const node = containerRef.current;
|
||||
if (!node) return;
|
||||
|
||||
const updateScale = (width: number, height: number) => {
|
||||
const nextScale = Math.max(Math.min(width, height) / 1000, 0);
|
||||
setContainerScale((current) => (Math.abs(current - nextScale) < 0.001 ? current : nextScale));
|
||||
};
|
||||
|
||||
updateScale(node.clientWidth, node.clientHeight);
|
||||
|
||||
if (typeof ResizeObserver === 'undefined') return;
|
||||
|
||||
const observer = new ResizeObserver((entries) => {
|
||||
const entry = entries[0];
|
||||
if (!entry) return;
|
||||
updateScale(entry.contentRect.width, entry.contentRect.height);
|
||||
});
|
||||
|
||||
observer.observe(node);
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (screen !== 'processing') return;
|
||||
|
||||
@@ -506,12 +531,14 @@ export default function AssumptionToggle({
|
||||
'--gc-text': theme?.text || '#0f172a',
|
||||
'--gc-text-muted': theme?.textMuted || '#eaffd8',
|
||||
'--gc-border': theme?.border || 'rgba(255,255,255,0.12)',
|
||||
'--gc-scale': containerScale.toString(),
|
||||
'--assumption-frame-image': `url(${frameImage})`
|
||||
} as CSSProperties;
|
||||
|
||||
return (
|
||||
<div className={`gc-assumption-toggle ${className || ''}`.trim()} style={rootStyle}>
|
||||
<div className="component-shell">
|
||||
<div ref={containerRef} className="square-container">
|
||||
<div className="main-wrapper">
|
||||
<div className={`crt-screen ${showParadoxScreen ? 'paradox-errors' : ''}`}>
|
||||
<div className={`slides-wrapper ${transitionState}`}>
|
||||
@@ -617,19 +644,16 @@ export default function AssumptionToggle({
|
||||
</div>
|
||||
|
||||
<div className="result-container">
|
||||
|
||||
<div className="summary-box">
|
||||
<span className={`result-value result-${result.tone}`}>{result.outcome}</span>
|
||||
</div>
|
||||
|
||||
<div className="summary-box">
|
||||
|
||||
<div className="intermediate-result">{result.intermediate}</div>
|
||||
</div>
|
||||
|
||||
<span className="result-description">{result.description}</span>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<button
|
||||
@@ -673,5 +697,6 @@ export default function AssumptionToggle({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
+35
-65
@@ -10,8 +10,10 @@
|
||||
--panel-white: rgba(255, 255, 255, 0.92);
|
||||
--font-display: "Russo One", sans-serif;
|
||||
--font-ui: "VT323", sans-serif;
|
||||
--gc-scale: 1;
|
||||
color: var(--text-primary);
|
||||
width: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle *,
|
||||
@@ -21,17 +23,27 @@
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .component-shell {
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px 0;
|
||||
background: var(--shell-bg);
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .square-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .main-wrapper {
|
||||
width: min(100%, 1000px);
|
||||
aspect-ratio: 1000 / 678;
|
||||
width: 1000px;
|
||||
height: 678px;
|
||||
flex: 0 0 auto;
|
||||
background-image: var(--assumption-frame-image);
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
@@ -39,6 +51,8 @@
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transform: scale(var(--gc-scale));
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .crt-screen {
|
||||
@@ -97,7 +111,7 @@
|
||||
|
||||
.gc-assumption-toggle .splash-content h1 {
|
||||
margin: 0 0 18px;
|
||||
font-size: clamp(1.4rem, 2.7vw, 2.2rem);
|
||||
font-size: 35px;
|
||||
line-height: 1.3;
|
||||
color: var(--text-primary);
|
||||
font-family: var(--font-display);
|
||||
@@ -109,7 +123,7 @@
|
||||
.gc-assumption-toggle .splash-content h2 {
|
||||
margin: 0 0 42px;
|
||||
color: var(--text-secondary);
|
||||
font-size: clamp(1rem, 1.5vw, 1.2rem);
|
||||
font-size: 19px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.08em;
|
||||
font-family: var(--font-ui);
|
||||
@@ -118,7 +132,7 @@
|
||||
.gc-assumption-toggle .widget-header h1 {
|
||||
margin: 0 0 18px;
|
||||
color: var(--text-secondary);
|
||||
font-size: clamp(1.4rem, 2.5vw, 1.8rem);
|
||||
font-size: 29px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
@@ -187,7 +201,7 @@
|
||||
text-align: center;
|
||||
padding: 10px 8px;
|
||||
color: rgba(255, 255, 255, 0.62);
|
||||
font-size: clamp(0.78rem, 2.0vw, 1.4rem);
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1.15;
|
||||
@@ -211,7 +225,7 @@
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(1rem, 2vw, 1.35rem);
|
||||
font-size: 22px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.06em;
|
||||
box-shadow: 0 4px 0 rgba(0, 0, 0, 0.28);
|
||||
@@ -228,7 +242,7 @@
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .action-button.secondary {
|
||||
font-size: 1rem;
|
||||
font-size: 16px;
|
||||
padding: 7px 88px;
|
||||
color: var(--text-secondary);
|
||||
background: transparent;
|
||||
@@ -283,7 +297,7 @@
|
||||
margin: 0;
|
||||
color: #dfffe7;
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(1.05rem, 2vw, 1.3rem);
|
||||
font-size: 21px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
@@ -292,7 +306,7 @@
|
||||
.gc-assumption-toggle .processing-subtitle {
|
||||
color: rgba(182, 255, 198, 0.72);
|
||||
font-family: var(--font-ui);
|
||||
font-size: clamp(0.88rem, 1.6vw, 1rem);
|
||||
font-size: 16px;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -322,7 +336,7 @@
|
||||
min-height: 1.45em;
|
||||
color: #b7ffca;
|
||||
font-family: var(--font-ui);
|
||||
font-size: clamp(1rem, 1.8vw, 1.18rem);
|
||||
font-size: 19px;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1.35;
|
||||
word-break: break-word;
|
||||
@@ -392,7 +406,7 @@
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.84rem;
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
font-family: var(--font-display);
|
||||
@@ -401,7 +415,7 @@
|
||||
.gc-assumption-toggle .summary-value {
|
||||
display: block;
|
||||
color: var(--text-primary);
|
||||
font-size: clamp(0.9rem, 1.5vw, 1rem);
|
||||
font-size: 16px;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1.4;
|
||||
font-family: var(--font-ui);
|
||||
@@ -411,7 +425,7 @@
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-top: 4px;
|
||||
font-size: clamp(1.7rem, 3vw, 2rem);
|
||||
font-size: 32px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.05em;
|
||||
background-clip: text;
|
||||
@@ -441,7 +455,7 @@
|
||||
width: 100%;
|
||||
margin-top: 4px;
|
||||
color: black;
|
||||
font-size: clamp(0.96rem, 1.8vw, 1.08rem);
|
||||
font-size: 17px;
|
||||
letter-spacing: 0.03em;
|
||||
line-height: 1.35;
|
||||
font-family: var(--font-ui);
|
||||
@@ -450,7 +464,7 @@
|
||||
.gc-assumption-toggle .intermediate-result {
|
||||
margin-top: 14px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.76rem;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
@@ -558,7 +572,7 @@
|
||||
top: -25px;
|
||||
left: 8px;
|
||||
color: #a10356;
|
||||
font-size: 1.4rem;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
text-shadow: 0 0 10px rgba(161, 3, 86, 0.45);
|
||||
}
|
||||
@@ -749,7 +763,7 @@
|
||||
top: 12px;
|
||||
right: 16px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
font-size: 1.4rem;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -899,50 +913,6 @@
|
||||
50% { opacity: 1; transform: scale(1.08); }
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.gc-assumption-toggle .component-shell {
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .switch-group {
|
||||
gap: 12px;
|
||||
padding: 0 14px;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .toggle-track {
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .action-button {
|
||||
padding: 10px 22px;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .action-button.secondary {
|
||||
padding: 6px 36px;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .result-container {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .intermediate-result {
|
||||
margin-top: 10px;
|
||||
font-size: 0.68rem;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .slide-processing {
|
||||
padding: 18px 14px 14px;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .processing-shell {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.gc-assumption-toggle .processing-terminal {
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Result-screen overrides after interrupted migration */
|
||||
.gc-assumption-toggle .visualization-container {
|
||||
background:
|
||||
@@ -1188,7 +1158,7 @@
|
||||
|
||||
.gc-assumption-toggle .physics-question {
|
||||
color: rgba(255, 248, 210, 0.94);
|
||||
font-size: 1.2rem;
|
||||
font-size: 19px;
|
||||
font-weight: 700;
|
||||
text-shadow: 0 0 12px rgba(255, 226, 130, 0.35);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user