Merge branch 'dev'

This commit is contained in:
Jeff Emmett 2026-02-27 14:37:04 -08:00
commit 2ef68e7217
2 changed files with 246 additions and 14 deletions

View File

@ -1162,13 +1162,14 @@ const STYLES = `
background: rgba(34,211,238,0.1);
}
/* ── Stack view ── */
/* ── Stack view (3D) ── */
.stack-view {
padding: 12px;
overflow: auto;
max-height: 50vh;
overflow: hidden;
max-height: 60vh;
transition: max-height 0.3s ease;
position: relative;
}
:host-context([data-theme="dark"]) .stack-view {
@ -1180,21 +1181,249 @@ const STYLES = `
border-bottom: 1px solid rgba(0,0,0,0.06);
}
.stack-view svg {
display: block;
margin: 0 auto;
.stack-view-3d {
perspective-origin: 50% 40%;
width: 100%;
height: 340px;
display: flex;
align-items: center;
justify-content: center;
cursor: grab;
user-select: none;
}
.stack-layer { cursor: pointer; }
.stack-layer:hover rect { stroke-width: 2.5; }
.stack-layer--active rect { stroke-dasharray: none; }
.stack-scene {
transform-style: preserve-3d;
position: relative;
width: 320px;
height: 80px;
}
/* ── Layer planes ── */
.layer-plane {
position: absolute;
width: 320px;
min-height: 70px;
border-radius: 10px;
border: 1px solid var(--layer-color);
padding: 10px 14px;
cursor: pointer;
transition: border-color 0.2s, box-shadow 0.2s;
transform-style: preserve-3d;
backface-visibility: hidden;
}
:host-context([data-theme="dark"]) .layer-plane {
background: rgba(15,23,42,0.65);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
color: #e2e8f0;
}
:host-context([data-theme="light"]) .layer-plane {
background: rgba(255,255,255,0.7);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
color: #1e293b;
}
.layer-plane:hover {
border-width: 2px;
box-shadow: 0 0 16px color-mix(in srgb, var(--layer-color) 30%, transparent);
}
.layer-plane--active {
border-width: 2px;
box-shadow: 0 0 24px color-mix(in srgb, var(--layer-color) 40%, transparent);
}
:host-context([data-theme="dark"]) .layer-plane--active {
background: rgba(15,23,42,0.85);
}
:host-context([data-theme="light"]) .layer-plane--active {
background: rgba(255,255,255,0.9);
}
/* Drag-to-connect visual states */
.stack-layer.flow-drag-source rect { stroke-dasharray: 4 2; stroke-width: 2.5; }
.stack-layer.flow-drag-target rect { stroke-width: 3; filter: brightness(1.3); }
.layer-plane.flow-drag-source {
border-style: dashed;
border-width: 2px;
}
.layer-plane.flow-drag-target {
border-width: 3px;
box-shadow: 0 0 30px color-mix(in srgb, var(--layer-color) 50%, transparent);
}
.stack-flow { cursor: pointer; }
.stack-flow:hover path { stroke-width: 4 !important; opacity: 1 !important; }
.layer-header {
display: flex;
align-items: center;
gap: 8px;
}
.layer-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
border-radius: 5px;
font-size: 0.55rem;
font-weight: 900;
color: #0f172a;
flex-shrink: 0;
}
.layer-name {
font-size: 0.8rem;
font-weight: 600;
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Feed port indicators */
.layer-ports {
display: flex;
gap: 3px;
flex-shrink: 0;
}
.feed-port {
width: 6px;
height: 6px;
border-radius: 50%;
opacity: 0.7;
}
.feed-port--in { box-shadow: inset 0 0 0 1.5px rgba(0,0,0,0.3); }
.feed-port--out { box-shadow: 0 0 3px currentColor; }
/* Containment indicators */
.layer-contained {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-top: 6px;
}
.contained-feed {
display: inline-flex;
align-items: center;
gap: 3px;
font-size: 0.6rem;
padding: 2px 6px;
border-radius: 4px;
background: color-mix(in srgb, var(--feed-color) 10%, transparent);
border: 1px solid color-mix(in srgb, var(--feed-color) 25%, transparent);
opacity: 0.7;
}
.contained-lock {
font-size: 0.55rem;
}
/* ── Flow particles ── */
.flow-particle {
position: absolute;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--color);
box-shadow: 0 0 6px var(--color);
left: 50%;
top: 50%;
margin-left: -3px;
margin-top: -3px;
pointer-events: auto;
cursor: pointer;
animation: flow-particle var(--duration) linear var(--delay) infinite;
}
@keyframes flow-particle {
0% { transform: translateZ(var(--src-z)); opacity: 0; }
8% { opacity: 1; }
85% { opacity: 1; }
95% { opacity: 0.5; transform: translateZ(var(--tgt-z)); }
100% { transform: translateZ(var(--tgt-z)); opacity: 0; }
}
/* ── Legend ── */
.stack-legend {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
padding: 6px 0;
}
.legend-item {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 0.65rem;
opacity: 0.6;
}
.legend-dot {
width: 6px;
height: 6px;
border-radius: 50%;
flex-shrink: 0;
}
/* ── Time scrubber ── */
.time-scrubber {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 16px;
justify-content: center;
}
.scrubber-playpause {
width: 24px;
height: 24px;
border: none;
border-radius: 50%;
background: rgba(34,211,238,0.15);
color: #22d3ee;
font-size: 0.7rem;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.15s;
flex-shrink: 0;
}
.scrubber-playpause:hover { background: rgba(34,211,238,0.25); }
.scrubber-range {
flex: 1;
max-width: 200px;
accent-color: #22d3ee;
height: 4px;
}
.scrubber-label {
font-size: 0.65rem;
font-weight: 700;
opacity: 0.5;
width: 28px;
text-align: center;
flex-shrink: 0;
}
/* ── Stack hint ── */
.stack-hint {
text-align: center;
font-size: 0.6rem;
opacity: 0.35;
padding: 2px 0 4px;
}
/* ── Flow creation dialog ── */
@ -1374,6 +1603,9 @@ const STYLES = `
.tab-label { display: none; }
.tab { padding: 4px 8px; }
.stack-view { max-height: 40vh; }
.stack-view-3d { height: 260px; }
.stack-scene { width: 240px; }
.layer-plane { width: 240px; min-height: 56px; padding: 8px 10px; }
.flow-dialog { width: 240px; }
}
`;

View File

@ -1,5 +1,5 @@
import { Hono } from "hono";
import type { FlowKind } from "../lib/layer-types";
import type { FlowKind, FeedDefinition } from "../lib/layer-types";
export type { FeedDefinition } from "../lib/layer-types";
/**