feat(phys8): Phase 0 redesign foundation — CSS + JS infrastructure
Закладывает уникальный визуальный язык и engine'ы для редизайна Физики 8. CSS: - phys8-design-system.css (12 КБ): 3 темы (thermal/electric/spectrum), тематические hero-палитры, watermarks, animations (thermal-shift, electric-pulse, spectrum-drift, wm-breathe/flicker/rotate, noise overlay), staggered fade-in для виджетов, soft elevation на карточках, monospace для физ. величин, topic-aware progress bars, mobile responsive (≤768px), prefers-reduced-motion. - phys8-interactives.css (10 КБ): .p8-draggable + .p8-droptarget с hover-effects, .p8-palette (для circuit-builder), .p8-scrubber, .p8-readout табло, .p8-tooltip, .p8-sandbox canvas wrapper, .p8-thermometer + .p8-compass-needle SVG-композиции, glow-utility. JS: - phys8-anim.js (6 КБ): easing-функции (quad/cubic/expo/back/elastic/ bounce/spring), tween-engine с onUpdate/onComplete, raf-wrapper, oscillate, stagger, onVisible (IntersectionObserver). Экспорт P8Anim. - phys8-drag.js (12 КБ): универсальный drag-engine. P8Drag.attach() для DOM/SVG, P8Drag.attachCanvas() для логических объектов с hit-test, P8Drag.attachPalette() для drag-from-palette-to-drop, constraints (lockX/Y, bounds, snap-to-grid), touch + mouse + pointer. - phys8-helpers.js (18 КБ): тематические хелперы. P8Helpers.thermal (tempColor 0-1, heatFlowArrow, molecule, thermometerSVG, convectionCellParticles), .em (chargeSVG, circuitComponent для battery/resistor/lamp/ammeter/voltmeter/switch, fieldLineFrom), .optics (rayLine, lensSVG converging/diverging, mirrorPlane), .svg utils (el, create, linearGradient, radialGradient, gradientArrow, labeledText). Линковка (redesign_p8_phase0.cjs): - 2 CSS-link после katex CDN - 3 JS-link после phys.js/xp.js - body class p8-theme-thermal/electric/spectrum на ch1/ch2/ch3 - hub и lab — без темы (нейтральный пурпурный brand)
This commit is contained in:
@@ -0,0 +1,359 @@
|
||||
/* phys8-design-system.css
|
||||
* Уникальный визуальный язык «Физики 8» — 3 тематических темы.
|
||||
* Применяется на physics_8_hub.html, physics_8_ch1/ch2/ch3.html, physics_8_lab.html.
|
||||
*
|
||||
* Тематика:
|
||||
* Ch1 «жар» — угольный/оранжевый/жёлтый, дышащий градиент
|
||||
* Ch2 «искра» — индиго/бирюза/голубой, electric pulse
|
||||
* Ch3 «спектр» — глубокий синий/радуга/персик, dispersion shift
|
||||
*/
|
||||
|
||||
/* === Глобальные тематические переменные === */
|
||||
:root {
|
||||
--p8-brand: #7c3aed;
|
||||
--p8-brand-d: #5b21b6;
|
||||
--p8-brand-l: #c4b5fd;
|
||||
--p8-brand-soft: #ede9fe;
|
||||
--p8-ink: #0f172a;
|
||||
--p8-text: #1e293b;
|
||||
--p8-muted: #64748b;
|
||||
--p8-mono: 'JetBrains Mono', 'SF Mono', Consolas, monospace;
|
||||
--p8-display: 'Unbounded', 'Outfit', system-ui, sans-serif;
|
||||
--p8-body: 'Inter', system-ui, sans-serif;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
--p8-ink: #f1f5f9;
|
||||
--p8-text: #e2e8f0;
|
||||
--p8-muted: #94a3b8;
|
||||
}
|
||||
|
||||
/* === Тема Ch1 «жар» — Тепловые явления === */
|
||||
body.p8-theme-thermal {
|
||||
--th-deep: #0f172a;
|
||||
--th-mid: #f97316;
|
||||
--th-warm: #facc15;
|
||||
--th-glow: rgba(249, 115, 22, .35);
|
||||
--th-soft: #fff7ed;
|
||||
--th-card: #fffbf5;
|
||||
}
|
||||
html.dark body.p8-theme-thermal {
|
||||
--th-soft: #1a0f05;
|
||||
--th-card: #1f1408;
|
||||
}
|
||||
|
||||
/* === Тема Ch2 «искра» — Электромагнитные явления === */
|
||||
body.p8-theme-electric {
|
||||
--el-deep: #1e1b4b;
|
||||
--el-mid: #06b6d4;
|
||||
--el-cool: #7dd3fc;
|
||||
--el-glow: rgba(6, 182, 212, .35);
|
||||
--el-soft: #ecfeff;
|
||||
--el-card: #f0fbff;
|
||||
}
|
||||
html.dark body.p8-theme-electric {
|
||||
--el-soft: #061226;
|
||||
--el-card: #081530;
|
||||
}
|
||||
|
||||
/* === Тема Ch3 «спектр» — Световые явления === */
|
||||
body.p8-theme-spectrum {
|
||||
--sp-deep: #0c0a3a;
|
||||
--sp-mid-r: #ef4444;
|
||||
--sp-mid-y: #facc15;
|
||||
--sp-mid-g: #22c55e;
|
||||
--sp-mid-b: #3b82f6;
|
||||
--sp-mid-v: #a855f7;
|
||||
--sp-warm: #fb7185;
|
||||
--sp-glow: rgba(168, 85, 247, .30);
|
||||
--sp-soft: #fdf2f8;
|
||||
--sp-card: #fff5fa;
|
||||
}
|
||||
html.dark body.p8-theme-spectrum {
|
||||
--sp-soft: #0d0a1f;
|
||||
--sp-card: #110d27;
|
||||
}
|
||||
|
||||
/* === Hero (заменяет .hdr на главах) === */
|
||||
.p8-hero {
|
||||
position: relative;
|
||||
padding: 48px 28px 38px;
|
||||
color: #fff;
|
||||
overflow: hidden;
|
||||
font-family: var(--p8-display);
|
||||
border-bottom: 2px solid rgba(255,255,255,.16);
|
||||
}
|
||||
.p8-theme-thermal .p8-hero {
|
||||
background:
|
||||
radial-gradient(circle at 78% 18%, var(--th-glow), transparent 55%),
|
||||
linear-gradient(125deg, var(--th-deep) 0%, var(--th-mid) 60%, var(--th-warm) 100%);
|
||||
background-size: 220% 220%, 100% 100%;
|
||||
animation: p8-thermal-shift 14s ease-in-out infinite;
|
||||
}
|
||||
.p8-theme-electric .p8-hero {
|
||||
background:
|
||||
radial-gradient(circle at 22% 30%, var(--el-glow), transparent 50%),
|
||||
linear-gradient(115deg, var(--el-deep) 0%, var(--el-mid) 65%, var(--el-cool) 100%);
|
||||
animation: p8-electric-pulse 5s ease-in-out infinite;
|
||||
}
|
||||
.p8-theme-spectrum .p8-hero {
|
||||
background:
|
||||
linear-gradient(115deg,
|
||||
var(--sp-deep) 0%,
|
||||
var(--sp-mid-r) 20%,
|
||||
var(--sp-mid-y) 38%,
|
||||
var(--sp-mid-g) 55%,
|
||||
var(--sp-mid-b) 72%,
|
||||
var(--sp-mid-v) 88%,
|
||||
var(--sp-warm) 100%);
|
||||
background-size: 240% 100%;
|
||||
animation: p8-spectrum-drift 18s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes p8-thermal-shift {
|
||||
0%, 100% { background-position: 0% 50%, 0 0; }
|
||||
50% { background-position: 100% 50%, 0 0; }
|
||||
}
|
||||
@keyframes p8-electric-pulse {
|
||||
0%, 100% { filter: brightness(1) saturate(1); }
|
||||
35% { filter: brightness(1.12) saturate(1.18); }
|
||||
60% { filter: brightness(0.96) saturate(1.06); }
|
||||
}
|
||||
@keyframes p8-spectrum-drift {
|
||||
0% { background-position: 0% 50%; }
|
||||
100% { background-position: 200% 50%; }
|
||||
}
|
||||
|
||||
/* === Hero watermark (тематический SVG-символ справа) === */
|
||||
.p8-hero-wm {
|
||||
position: absolute;
|
||||
right: -24px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: clamp(180px, 32vw, 360px);
|
||||
aspect-ratio: 1;
|
||||
opacity: .18;
|
||||
color: #fff;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
.p8-hero-wm svg { width: 100%; height: 100%; fill: currentColor; }
|
||||
|
||||
/* Анимация дыхания watermark */
|
||||
.p8-theme-thermal .p8-hero-wm { animation: p8-wm-breathe 6s ease-in-out infinite; }
|
||||
.p8-theme-electric .p8-hero-wm { animation: p8-wm-flicker 3.2s ease-in-out infinite; }
|
||||
.p8-theme-spectrum .p8-hero-wm { animation: p8-wm-rotate 40s linear infinite; }
|
||||
@keyframes p8-wm-breathe { 0%,100% { opacity: .15; transform: translateY(-50%) scale(1); } 50% { opacity: .22; transform: translateY(-50%) scale(1.06); } }
|
||||
@keyframes p8-wm-flicker { 0%,100% { opacity: .18; } 30% { opacity: .26; } 33% { opacity: .12; } 36% { opacity: .24; } 50% { opacity: .18; } }
|
||||
@keyframes p8-wm-rotate { 0% { transform: translateY(-50%) rotate(0); } 100% { transform: translateY(-50%) rotate(360deg); } }
|
||||
|
||||
/* === Hero content === */
|
||||
.p8-hero-inner {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.p8-hero-eyebrow {
|
||||
display: inline-block;
|
||||
padding: 5px 12px;
|
||||
background: rgba(255,255,255,.18);
|
||||
border-radius: 99px;
|
||||
font-size: .72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: .12em;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 14px;
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
.p8-hero-title {
|
||||
font-family: var(--p8-display);
|
||||
font-size: clamp(1.8rem, 4vw, 2.6rem);
|
||||
font-weight: 900;
|
||||
letter-spacing: -.02em;
|
||||
line-height: 1.05;
|
||||
margin: 0 0 10px;
|
||||
text-shadow: 0 2px 16px rgba(0,0,0,.18);
|
||||
}
|
||||
.p8-hero-sub {
|
||||
font-size: clamp(.92rem, 1.4vw, 1.05rem);
|
||||
opacity: .92;
|
||||
max-width: 640px;
|
||||
font-family: var(--p8-body);
|
||||
font-weight: 500;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
/* === Live header indicator (маячок в углу хедера) === */
|
||||
.p8-hero-meter {
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 28px;
|
||||
z-index: 2;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 7px 12px;
|
||||
background: rgba(0,0,0,.28);
|
||||
backdrop-filter: blur(8px);
|
||||
border-radius: 99px;
|
||||
font-family: var(--p8-mono);
|
||||
font-size: .76rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
letter-spacing: .04em;
|
||||
}
|
||||
.p8-hero-meter::before {
|
||||
content: '';
|
||||
width: 8px; height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 0 0 currentColor;
|
||||
animation: p8-meter-pulse 1.4s ease-out infinite;
|
||||
}
|
||||
@keyframes p8-meter-pulse {
|
||||
0% { box-shadow: 0 0 0 0 rgba(255,255,255,.65); }
|
||||
70% { box-shadow: 0 0 0 12px rgba(255,255,255,0); }
|
||||
100% { box-shadow: 0 0 0 0 rgba(255,255,255,0); }
|
||||
}
|
||||
|
||||
/* === Section watermarks (тематические SVG на правой стороне каждой секции) === */
|
||||
.p8-sec-wm {
|
||||
position: absolute;
|
||||
right: -28px;
|
||||
top: 8%;
|
||||
width: clamp(140px, 22vw, 240px);
|
||||
aspect-ratio: 1;
|
||||
color: var(--p8-brand);
|
||||
opacity: .07;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
z-index: 0;
|
||||
}
|
||||
.p8-theme-thermal .p8-sec-wm { color: var(--th-mid); }
|
||||
.p8-theme-electric .p8-sec-wm { color: var(--el-mid); }
|
||||
.p8-theme-spectrum .p8-sec-wm { color: var(--sp-mid-v); }
|
||||
.p8-sec-wm svg { width: 100%; height: 100%; fill: currentColor; }
|
||||
|
||||
/* === Hover-resonance — SVG/canvas в виджетах === */
|
||||
.wg svg, .wg canvas {
|
||||
transition: filter .35s cubic-bezier(.16,1,.3,1), transform .35s cubic-bezier(.16,1,.3,1);
|
||||
}
|
||||
.wg:hover svg,
|
||||
.wg:hover canvas {
|
||||
filter: drop-shadow(0 6px 20px rgba(0,0,0,.10));
|
||||
}
|
||||
.p8-theme-thermal .wg:hover svg { filter: drop-shadow(0 6px 20px var(--th-glow)); }
|
||||
.p8-theme-electric .wg:hover svg { filter: drop-shadow(0 6px 20px var(--el-glow)); }
|
||||
.p8-theme-spectrum .wg:hover svg { filter: drop-shadow(0 6px 20px var(--sp-glow)); }
|
||||
|
||||
/* === Staggered fade-in для виджетов === */
|
||||
@keyframes p8-wg-fade-in {
|
||||
from { opacity: 0; transform: translateY(14px); }
|
||||
to { opacity: 1; transform: none; }
|
||||
}
|
||||
.sec.active .wg {
|
||||
animation: p8-wg-fade-in .45s cubic-bezier(.16,1,.3,1) backwards;
|
||||
}
|
||||
.sec.active .wg:nth-of-type(1) { animation-delay: .03s; }
|
||||
.sec.active .wg:nth-of-type(2) { animation-delay: .10s; }
|
||||
.sec.active .wg:nth-of-type(3) { animation-delay: .17s; }
|
||||
.sec.active .wg:nth-of-type(4) { animation-delay: .24s; }
|
||||
.sec.active .wg:nth-of-type(5) { animation-delay: .31s; }
|
||||
.sec.active .wg:nth-of-type(6) { animation-delay: .38s; }
|
||||
.sec.active .wg:nth-of-type(7) { animation-delay: .45s; }
|
||||
|
||||
/* === Soft elevation на карточках (2 уровня) === */
|
||||
.wg {
|
||||
box-shadow: 0 1px 3px rgba(15,23,42,.05), 0 8px 20px rgba(15,23,42,.04);
|
||||
transition: box-shadow 350ms cubic-bezier(.16,1,.3,1), transform 350ms cubic-bezier(.16,1,.3,1);
|
||||
}
|
||||
.wg:hover {
|
||||
box-shadow: 0 4px 10px rgba(15,23,42,.07), 0 18px 36px rgba(15,23,42,.10);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* === Typography rhythm: моноширинный для физических величин === */
|
||||
.p8-num, .p8-unit, .p8-mono, var.p8-var,
|
||||
.tinp[type="number"], input[type="number"].tinp {
|
||||
font-family: var(--p8-mono);
|
||||
letter-spacing: -.01em;
|
||||
}
|
||||
.p8-num { font-weight: 700; color: var(--p8-ink); }
|
||||
.p8-unit { color: var(--p8-muted); font-weight: 600; font-size: .92em; }
|
||||
|
||||
/* === Topic-aware progress bars === */
|
||||
.p8-theme-thermal .hp-fill,
|
||||
.p8-theme-thermal .po-fill,
|
||||
.p8-theme-thermal .ch-prog-fill {
|
||||
background: linear-gradient(90deg, var(--th-mid), var(--th-warm));
|
||||
}
|
||||
.p8-theme-electric .hp-fill,
|
||||
.p8-theme-electric .po-fill,
|
||||
.p8-theme-electric .ch-prog-fill {
|
||||
background: linear-gradient(90deg, var(--el-mid), var(--el-cool));
|
||||
}
|
||||
.p8-theme-spectrum .hp-fill,
|
||||
.p8-theme-spectrum .po-fill,
|
||||
.p8-theme-spectrum .ch-prog-fill {
|
||||
background: linear-gradient(90deg, var(--sp-mid-b), var(--sp-mid-v), var(--sp-warm));
|
||||
background-size: 200% 100%;
|
||||
animation: p8-spectrum-drift 8s linear infinite;
|
||||
}
|
||||
|
||||
/* === Mobile responsiveness === */
|
||||
@media (max-width: 768px) {
|
||||
.p8-hero { padding: 34px 18px 26px; }
|
||||
.p8-hero-wm { width: clamp(120px, 38vw, 200px); right: -16px; opacity: .12; }
|
||||
.p8-hero-meter { top: 14px; right: 16px; font-size: .68rem; padding: 5px 9px; }
|
||||
.p8-sec-wm { width: clamp(80px, 28vw, 140px); right: -16px; opacity: .05; }
|
||||
}
|
||||
|
||||
/* === Animated noise overlay (микро-шум на hero) === */
|
||||
.p8-hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image:
|
||||
radial-gradient(circle 1px at 25% 30%, rgba(255,255,255,.10) 0, transparent 1px),
|
||||
radial-gradient(circle 1px at 75% 60%, rgba(255,255,255,.08) 0, transparent 1px),
|
||||
radial-gradient(circle 1px at 50% 80%, rgba(255,255,255,.06) 0, transparent 1px),
|
||||
radial-gradient(circle 1px at 15% 75%, rgba(255,255,255,.09) 0, transparent 1px),
|
||||
radial-gradient(circle 1px at 85% 20%, rgba(255,255,255,.07) 0, transparent 1px);
|
||||
background-size: 80px 80px;
|
||||
opacity: .6;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
.p8-theme-thermal .p8-hero::after { animation: p8-noise-thermal 8s linear infinite; }
|
||||
.p8-theme-electric .p8-hero::after { animation: p8-noise-electric 4s linear infinite; }
|
||||
.p8-theme-spectrum .p8-hero::after { animation: p8-noise-spectrum 12s linear infinite; }
|
||||
@keyframes p8-noise-thermal { 0% { background-position: 0 0; } 100% { background-position: 80px -160px; } }
|
||||
@keyframes p8-noise-electric { 0% { background-position: 0 0; } 100% { background-position: -120px 80px; } }
|
||||
@keyframes p8-noise-spectrum { 0% { background-position: 0 0; } 100% { background-position: 80px 80px; } }
|
||||
|
||||
/* === Focus-visible для accessibility === */
|
||||
.btn:focus-visible,
|
||||
button:focus-visible,
|
||||
input:focus-visible,
|
||||
.wg [tabindex]:focus-visible {
|
||||
outline: 2px solid var(--p8-brand);
|
||||
outline-offset: 2px;
|
||||
border-radius: 9px;
|
||||
}
|
||||
.p8-theme-thermal :focus-visible { outline-color: var(--th-mid); }
|
||||
.p8-theme-electric :focus-visible { outline-color: var(--el-mid); }
|
||||
.p8-theme-spectrum :focus-visible { outline-color: var(--sp-mid-v); }
|
||||
|
||||
/* === Reduced motion === */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.p8-hero,
|
||||
.p8-hero-wm,
|
||||
.p8-hero-meter::before,
|
||||
.p8-hero::after,
|
||||
.sec.active .wg,
|
||||
.p8-theme-spectrum .ch-prog-fill {
|
||||
animation: none !important;
|
||||
}
|
||||
.wg, .wg svg, .wg canvas { transition: none !important; }
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
/* phys8-interactives.css
|
||||
* Стили для drag-and-drop виджетов, scrubbers, tooltips, badges,
|
||||
* палитр компонентов (для circuit builder), readout-табло.
|
||||
* Расширяет phys-textbook-widgets.css.
|
||||
*/
|
||||
|
||||
/* === Drag handle (cursor + микро-эффект) === */
|
||||
.p8-draggable {
|
||||
cursor: grab;
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
transition: filter .18s, transform .18s;
|
||||
}
|
||||
.p8-draggable:hover {
|
||||
filter: brightness(1.05);
|
||||
}
|
||||
.p8-draggable:active,
|
||||
.p8-draggable.is-dragging {
|
||||
cursor: grabbing;
|
||||
filter: brightness(1.12) drop-shadow(0 6px 12px rgba(0,0,0,.18));
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* === Drop target (зона приёма) === */
|
||||
.p8-droptarget {
|
||||
border: 2px dashed var(--p8-brand-l, #c4b5fd);
|
||||
border-radius: 12px;
|
||||
padding: 14px;
|
||||
background: rgba(124, 58, 237, .04);
|
||||
transition: border-color .2s, background .2s, transform .2s;
|
||||
min-height: 60px;
|
||||
position: relative;
|
||||
}
|
||||
.p8-droptarget.p8-drop-over {
|
||||
border-style: solid;
|
||||
border-color: var(--p8-brand, #7c3aed);
|
||||
background: rgba(124, 58, 237, .10);
|
||||
transform: scale(1.02);
|
||||
}
|
||||
.p8-theme-thermal .p8-droptarget.p8-drop-over { border-color: var(--th-mid); background: rgba(249,115,22,.10); }
|
||||
.p8-theme-electric .p8-droptarget.p8-drop-over { border-color: var(--el-mid); background: rgba(6,182,212,.10); }
|
||||
.p8-theme-spectrum .p8-droptarget.p8-drop-over { border-color: var(--sp-mid-v); background: rgba(168,85,247,.10); }
|
||||
|
||||
/* === Component palette (для circuit builder и т.д.) === */
|
||||
.p8-palette {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
padding: 12px;
|
||||
background: rgba(0,0,0,.04);
|
||||
border-radius: 12px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.p8-palette-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 12px;
|
||||
background: var(--p8-brand-soft, #ede9fe);
|
||||
border: 1.5px solid var(--p8-brand-l, #c4b5fd);
|
||||
border-radius: 10px;
|
||||
cursor: grab;
|
||||
font-size: .86rem;
|
||||
font-weight: 600;
|
||||
color: var(--p8-brand-d, #5b21b6);
|
||||
transition: transform .15s, box-shadow .15s, background .15s;
|
||||
touch-action: none;
|
||||
}
|
||||
.p8-palette-item:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 14px rgba(0,0,0,.10);
|
||||
background: #fff;
|
||||
}
|
||||
.p8-palette-item:active { cursor: grabbing; }
|
||||
.p8-palette-item svg { width: 22px; height: 22px; }
|
||||
|
||||
/* === Scrubber (диапазонный ползунок с подписью) === */
|
||||
.p8-scrubber {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 14px;
|
||||
background: rgba(0,0,0,.03);
|
||||
border-radius: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.p8-scrubber-label {
|
||||
font-size: .82rem;
|
||||
font-weight: 700;
|
||||
color: var(--p8-text);
|
||||
min-width: 80px;
|
||||
}
|
||||
.p8-scrubber input[type="range"] {
|
||||
flex: 1;
|
||||
accent-color: var(--p8-brand, #7c3aed);
|
||||
height: 6px;
|
||||
}
|
||||
.p8-theme-thermal .p8-scrubber input[type="range"] { accent-color: var(--th-mid); }
|
||||
.p8-theme-electric .p8-scrubber input[type="range"] { accent-color: var(--el-mid); }
|
||||
.p8-theme-spectrum .p8-scrubber input[type="range"] { accent-color: var(--sp-mid-v); }
|
||||
.p8-scrubber-value {
|
||||
font-family: var(--p8-mono);
|
||||
font-weight: 700;
|
||||
font-size: .92rem;
|
||||
color: var(--p8-ink);
|
||||
min-width: 70px;
|
||||
text-align: right;
|
||||
}
|
||||
.p8-scrubber-value .p8-unit {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
/* === Readout табло (для live-данных симуляции) === */
|
||||
.p8-readout {
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
padding: 6px 12px;
|
||||
background: var(--p8-ink, #0f172a);
|
||||
color: #f1f5f9;
|
||||
border-radius: 8px;
|
||||
font-family: var(--p8-mono);
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
letter-spacing: -.01em;
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.10);
|
||||
}
|
||||
.p8-readout-label {
|
||||
font-size: .68rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: .08em;
|
||||
text-transform: uppercase;
|
||||
color: #94a3b8;
|
||||
margin-right: 6px;
|
||||
}
|
||||
.p8-readout-value {
|
||||
color: #fff;
|
||||
font-size: 1.1em;
|
||||
min-width: 1em;
|
||||
display: inline-block;
|
||||
transition: color .2s;
|
||||
}
|
||||
.p8-readout-value.is-changing {
|
||||
color: #fde047;
|
||||
}
|
||||
.p8-readout-unit {
|
||||
color: #94a3b8;
|
||||
font-weight: 600;
|
||||
font-size: .82em;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
/* === Tooltip (всплывающие подсказки на drag-объектах) === */
|
||||
.p8-tooltip {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
padding: 6px 10px;
|
||||
background: rgba(15, 23, 42, .94);
|
||||
color: #fff;
|
||||
font-size: .76rem;
|
||||
font-weight: 600;
|
||||
border-radius: 8px;
|
||||
z-index: 100;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 6px 14px rgba(0,0,0,.20);
|
||||
opacity: 0;
|
||||
transform: translateY(4px);
|
||||
transition: opacity .15s, transform .15s;
|
||||
}
|
||||
.p8-tooltip.is-visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
.p8-tooltip::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -4px; left: 50%;
|
||||
transform: translateX(-50%) rotate(45deg);
|
||||
width: 8px; height: 8px;
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
/* === Badge (тематический значок IV-N, статус) === */
|
||||
.p8-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 4px 10px;
|
||||
border-radius: 99px;
|
||||
font-size: .68rem;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .08em;
|
||||
font-family: var(--p8-display);
|
||||
}
|
||||
.p8-badge.p8-badge-thermal { background: var(--th-soft, #fff7ed); color: var(--th-mid, #f97316); }
|
||||
.p8-badge.p8-badge-electric { background: var(--el-soft, #ecfeff); color: var(--el-mid, #06b6d4); }
|
||||
.p8-badge.p8-badge-spectrum { background: var(--sp-soft, #fdf2f8); color: var(--sp-mid-v, #a855f7); }
|
||||
|
||||
/* === Sandbox canvas (для drag-сцен) === */
|
||||
.p8-sandbox {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background:
|
||||
linear-gradient(135deg, #fafafa 0%, #f3f4f6 100%);
|
||||
border: 1.5px solid #e5e7eb;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
cursor: default;
|
||||
}
|
||||
html.dark .p8-sandbox {
|
||||
background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);
|
||||
border-color: #334155;
|
||||
}
|
||||
.p8-sandbox canvas,
|
||||
.p8-sandbox svg {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
touch-action: none;
|
||||
}
|
||||
.p8-sandbox-toolbar {
|
||||
position: absolute;
|
||||
top: 10px; left: 10px;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
z-index: 5;
|
||||
}
|
||||
.p8-sandbox-btn {
|
||||
padding: 5px 10px;
|
||||
background: rgba(255,255,255,.92);
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 7px;
|
||||
font-size: .76rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
font-family: var(--p8-body);
|
||||
transition: background .15s;
|
||||
}
|
||||
.p8-sandbox-btn:hover { background: #fff; }
|
||||
html.dark .p8-sandbox-btn { background: rgba(15,23,42,.92); border-color: #334155; color: #f1f5f9; }
|
||||
html.dark .p8-sandbox-btn:hover { background: #1e293b; }
|
||||
|
||||
/* === Snap-to-grid индикатор === */
|
||||
.p8-snap-line {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
background: var(--p8-brand, #7c3aed);
|
||||
opacity: .35;
|
||||
z-index: 4;
|
||||
transition: opacity .12s;
|
||||
}
|
||||
.p8-snap-line.horizontal { left: 0; right: 0; height: 1px; }
|
||||
.p8-snap-line.vertical { top: 0; bottom: 0; width: 1px; }
|
||||
|
||||
/* === Thermometer (вертикальный термометр для thermal sandbox) === */
|
||||
.p8-thermometer {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
.p8-thermometer-bulb {
|
||||
width: 28px; height: 28px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #ef4444, #dc2626);
|
||||
border: 2px solid #991b1b;
|
||||
box-shadow: 0 0 12px rgba(239,68,68,.45);
|
||||
}
|
||||
.p8-thermometer-tube {
|
||||
width: 10px;
|
||||
height: 90px;
|
||||
margin-bottom: -2px;
|
||||
background: linear-gradient(to top, #ef4444 var(--p8-temp, 50%), #f3f4f6 var(--p8-temp, 50%));
|
||||
border: 2px solid #475569;
|
||||
border-bottom: none;
|
||||
border-radius: 5px 5px 0 0;
|
||||
}
|
||||
.p8-thermometer-scale {
|
||||
position: absolute;
|
||||
left: 100%; top: 10px;
|
||||
margin-left: 4px;
|
||||
font-family: var(--p8-mono);
|
||||
font-size: .68rem;
|
||||
color: var(--p8-muted);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* === Compass needle (для magnetic compass) === */
|
||||
.p8-compass {
|
||||
width: 120px; height: 120px;
|
||||
position: relative;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, #fff 0%, #f1f5f9 100%);
|
||||
border: 3px solid #475569;
|
||||
box-shadow: inset 0 2px 4px rgba(0,0,0,.10), 0 4px 10px rgba(0,0,0,.10);
|
||||
}
|
||||
.p8-compass::before,
|
||||
.p8-compass::after {
|
||||
content: ''; position: absolute;
|
||||
left: 50%; top: 50%;
|
||||
background: #475569;
|
||||
transform-origin: center;
|
||||
}
|
||||
.p8-compass::before { /* N marker */
|
||||
content: 'N';
|
||||
top: 6px; left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: transparent;
|
||||
font-family: var(--p8-display);
|
||||
font-weight: 900;
|
||||
font-size: .82rem;
|
||||
color: #dc2626;
|
||||
}
|
||||
.p8-compass-needle {
|
||||
position: absolute;
|
||||
left: 50%; top: 50%;
|
||||
width: 6px;
|
||||
height: 84px;
|
||||
transform: translate(-50%, -50%) rotate(var(--p8-needle-angle, 0deg));
|
||||
transform-origin: center;
|
||||
transition: transform .35s cubic-bezier(.34, 1.56, .64, 1);
|
||||
z-index: 2;
|
||||
pointer-events: none;
|
||||
}
|
||||
.p8-compass-needle::before,
|
||||
.p8-compass-needle::after {
|
||||
content: ''; position: absolute;
|
||||
left: 0; width: 100%;
|
||||
height: 50%;
|
||||
}
|
||||
.p8-compass-needle::before {
|
||||
top: 0;
|
||||
background: linear-gradient(to bottom, #dc2626, #b91c1c);
|
||||
clip-path: polygon(50% 0, 100% 100%, 0 100%);
|
||||
}
|
||||
.p8-compass-needle::after {
|
||||
bottom: 0;
|
||||
background: linear-gradient(to top, #475569, #1e293b);
|
||||
clip-path: polygon(50% 100%, 100% 0, 0 0);
|
||||
}
|
||||
|
||||
/* === Particle Glow (для частиц газа / искр / лучей) === */
|
||||
.p8-glow {
|
||||
filter: drop-shadow(0 0 6px currentColor);
|
||||
}
|
||||
|
||||
/* === Animation utility classes === */
|
||||
.p8-anim-jitter { animation: p8-jitter .35s ease infinite alternate; }
|
||||
@keyframes p8-jitter {
|
||||
0% { transform: translate(0, 0); }
|
||||
100% { transform: translate(1px, -1px); }
|
||||
}
|
||||
.p8-anim-shimmer {
|
||||
background-image: linear-gradient(105deg, transparent 40%, rgba(255,255,255,.4) 50%, transparent 60%);
|
||||
background-size: 250% 100%;
|
||||
animation: p8-shimmer 1.4s linear infinite;
|
||||
}
|
||||
@keyframes p8-shimmer {
|
||||
0% { background-position: 250% 0; }
|
||||
100% { background-position: -150% 0; }
|
||||
}
|
||||
|
||||
/* === Reduced motion === */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.p8-draggable, .p8-droptarget, .p8-tooltip,
|
||||
.p8-compass-needle, .p8-readout-value,
|
||||
.p8-anim-jitter, .p8-anim-shimmer {
|
||||
transition: none !important;
|
||||
animation: none !important;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user