173 lines
6.4 KiB
HTML
173 lines
6.4 KiB
HTML
<!doctype html>
|
|
<html lang="ru">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
<title>Главный экран — Бюджет · вайрфреймы</title>
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Caveat:wght@500;600&display=swap" rel="stylesheet" />
|
|
|
|
<style>
|
|
:root {
|
|
/* Light tokens */
|
|
--paper: #f6f4ef;
|
|
--paper-2: #efece5;
|
|
--card-soft: #edeae3;
|
|
--ink: #1c1c1a;
|
|
--ink-2: #6b6b66;
|
|
--line: #d8d5cc;
|
|
--line-2: #b8b5ac;
|
|
--accent: #4a8a82;
|
|
--accent-soft:#dde9e6;
|
|
--pos: #6f8c69;
|
|
--neg: #b3675a;
|
|
--canvas-bg: #efece5;
|
|
}
|
|
[data-theme="dark"] {
|
|
--paper: #19191a;
|
|
--paper-2: #232325;
|
|
--card-soft: #232325;
|
|
--ink: #ece9e2;
|
|
--ink-2: #8d8a83;
|
|
--line: #2e2d2a;
|
|
--line-2: #4a4845;
|
|
--accent: #76b3a9;
|
|
--accent-soft:#23332f;
|
|
--pos: #92b58a;
|
|
--neg: #d18d7e;
|
|
--canvas-bg: #111112;
|
|
}
|
|
|
|
html, body { margin: 0; padding: 0; background: var(--canvas-bg); }
|
|
body {
|
|
font-family: 'DM Sans', system-ui, sans-serif;
|
|
color: var(--ink);
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
* { box-sizing: border-box; }
|
|
|
|
/* Wireframe root sets dark/light tokens for all frames */
|
|
.wf-root { color: var(--ink); }
|
|
|
|
/* Remove webkit scrollbars on hscrolls */
|
|
.wf-root *::-webkit-scrollbar { display: none; }
|
|
</style>
|
|
|
|
<!-- React + Babel -->
|
|
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
|
|
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
|
|
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
|
|
|
|
<script type="text/babel" src="design-canvas.jsx"></script>
|
|
<script type="text/babel" src="android-frame.jsx"></script>
|
|
<script type="text/babel" src="tweaks-panel.jsx"></script>
|
|
<script type="text/babel" src="common.jsx"></script>
|
|
<script type="text/babel" src="variants.jsx"></script>
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
|
|
<script type="text/babel">
|
|
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
|
|
"theme": "dark"
|
|
}/*EDITMODE-END*/;
|
|
|
|
// Custom Android frame that uses our CSS-var palette (so dark/light flows through)
|
|
function PhoneShell({ children }) {
|
|
return (
|
|
<div style={{
|
|
width: 412, height: 892, borderRadius: 18, overflow: 'hidden',
|
|
background: 'var(--paper)',
|
|
border: '8px solid var(--line-2)',
|
|
boxShadow: '0 24px 60px rgba(0,0,0,0.18)',
|
|
display: 'flex', flexDirection: 'column', boxSizing: 'border-box',
|
|
}}>
|
|
{/* Status bar */}
|
|
<div style={{
|
|
height: 32, padding: '0 16px', display: 'flex',
|
|
alignItems: 'center', justifyContent: 'space-between',
|
|
position: 'relative', fontSize: 12, color: 'var(--ink)',
|
|
fontFamily: 'DM Sans, sans-serif',
|
|
}}>
|
|
<span style={{ fontWeight: 500 }}>9:30</span>
|
|
<div style={{
|
|
position: 'absolute', left: '50%', top: 6, transform: 'translateX(-50%)',
|
|
width: 18, height: 18, borderRadius: '50%', background: 'var(--ink)',
|
|
opacity: 0.85,
|
|
}} />
|
|
<div style={{ display: 'flex', gap: 4, alignItems: 'center', opacity: 0.85 }}>
|
|
<svg width="14" height="14" viewBox="0 0 16 16"><path d="M8 13.3L.67 5.97a10.37 10.37 0 0114.66 0L8 13.3z" fill="currentColor"/></svg>
|
|
<svg width="14" height="14" viewBox="0 0 16 16"><path d="M14.67 14.67V1.33L1.33 14.67h13.34z" fill="currentColor"/></svg>
|
|
<svg width="16" height="14" viewBox="0 0 16 16"><rect x="3.75" y="2" width="8.5" height="13" rx="1.5" fill="currentColor"/><rect x="5.5" y="0.9" width="5" height="2" rx="0.5" fill="currentColor"/></svg>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div style={{ flex: 1, overflow: 'auto', position: 'relative' }}>
|
|
{children}
|
|
</div>
|
|
|
|
{/* Bottom nav */}
|
|
<BottomNav active={0} />
|
|
|
|
{/* Gesture pill */}
|
|
<div style={{ height: 18, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--paper)' }}>
|
|
<div style={{ width: 96, height: 4, borderRadius: 2, background: 'var(--ink)', opacity: 0.35 }} />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Variation meta
|
|
const VARIANTS = [
|
|
{ n: 1, title: 'Segmented account tabs',
|
|
Component: V1,
|
|
axes: ['Счёт: горизонтальные таб-пиллы', 'KPI: баланс + доходырасходы', 'Фильтр: bottom-sheet триггер', 'Список: группировка по дням'] },
|
|
];
|
|
|
|
function Stage() {
|
|
const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
|
|
|
|
React.useEffect(() => {
|
|
document.documentElement.setAttribute('data-theme', tweaks.theme);
|
|
}, [tweaks.theme]);
|
|
|
|
return (
|
|
<div className="wf-root" data-screen-label="Главный экран">
|
|
<DesignCanvas>
|
|
<DCSection id="phones" title="Главный экран">
|
|
{VARIANTS.map(v => (
|
|
<DCArtboard key={v.n}
|
|
id={`v${v.n}`}
|
|
label={`0${v.n} · ${v.title}`}
|
|
width={412} height={892}>
|
|
<PhoneShell><v.Component /></PhoneShell>
|
|
</DCArtboard>
|
|
))}
|
|
</DCSection>
|
|
</DesignCanvas>
|
|
|
|
<TweaksPanel>
|
|
<TweakSection label="Тема">
|
|
<TweakRadio
|
|
label="Режим"
|
|
value={tweaks.theme}
|
|
onChange={v => setTweak('theme', v)}
|
|
options={[
|
|
{ value: 'light', label: 'Светлая' },
|
|
{ value: 'dark', label: 'Тёмная' },
|
|
]}
|
|
/>
|
|
</TweakSection>
|
|
</TweaksPanel>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
ReactDOM.createRoot(document.getElementById('root')).render(<Stage />);
|
|
</script>
|
|
</body>
|
|
</html>
|