Something went wrong. Try again.
small gleam coding and persistent agent daemon with a detachable cli and a canvas ui forked from okami.mom/albedo
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306/* * Surfaces and text shades come from three seeds and a contrast, per mode, which the * settings pane edits (prefs.svelte.ts sets them on <html>): --seed-bg is the * ground, --seed-fg the ink, --seed-accent the accent, --contrast 0 to 1. * Surfaces and secondary text are mixed from them, so any three colours make * a whole theme. Semantic colours and the speaker colour can be overridden. * The fallbacks here are the defaults, madoromi's spring * (https://madoromi.moonwit.ch/), for the first paint. *//* * Every layer one component stacks against another, back to front. A window * is a stacking context of its own, so the z-indexes inside it (its header, * composer, menus) only order its own parts and never reach these. The board * is one too, so its layers never meet the app's. */:root { /* on the board */ --z-window: 0; --z-tethers: 1; --z-floats: 2; --z-window-menu: 3; --z-board-controls: 4; /* over the board */ --z-peek: 20; --z-zen: 40; --z-pane: 50; --z-docking: 60; --z-palette: 100;}
:root { color-scheme: light; --seed-bg: #f6eff8; --seed-fg: #584a5c; --seed-accent: #6928bd; --contrast: 0.45; /* how far each step goes: half as far at no contrast, half again at full */ --k: calc(0.5 + var(--contrast));
--bg: var(--seed-bg); --rail: color-mix(in oklab, var(--seed-bg), var(--seed-fg) calc(3% * var(--k))); --surface: color-mix(in oklab, var(--seed-bg), #fff 78%); --title-bar: color-mix(in oklab, var(--surface), var(--seed-fg) calc(2% * var(--k))); --well: color-mix(in oklab, var(--surface), var(--seed-fg) calc(8% * var(--k))); --field: color-mix(in oklab, var(--surface), var(--seed-fg) calc(11% * var(--k))); --bubble: color-mix(in oklab, var(--field), var(--seed-accent) 7%); --text: var(--seed-fg); --muted: color-mix(in oklab, var(--seed-fg), var(--surface) calc(28% - 20% * var(--contrast))); --faint: color-mix(in oklab, var(--seed-fg), var(--surface) calc(45% - 20% * var(--contrast))); --hover: color-mix(in oklab, var(--seed-fg) calc(5% * var(--k)), transparent); --selected: color-mix(in oklab, var(--seed-fg) calc(8% * var(--k)), transparent); --accent: var(--seed-accent); --focus-ring: color-mix(in oklab, var(--seed-accent) 45%, transparent); /* Who is speaking, as in the terminal: albedo in the accent, you opposite it. */ --agent: var(--seed-accent); --brand-from: var(--seed-accent); --brand-to: oklch(from var(--seed-accent) l c calc(h + 40)); --you: oklch(from var(--seed-accent) 0.5 0.09 calc(h - 130)); /* madoromi's young leaves (wakaba) and crimson (beni) */ --added: #5e8933; --danger: #ce2700; --scrim: color-mix(in oklab, var(--seed-bg) 60%, transparent); --dots: color-mix(in oklab, var(--seed-fg) calc(36% * var(--k)), transparent); /* The sidebar's stripes: the step the phone's stripes take from its ground, taken from the rail's. */ --rail-stripe: color-mix(in oklab, var(--rail), var(--shade) calc(3.2% * var(--k))); /* A sidebar row for a session open on the board. */ --open-tint: color-mix(in oklab, var(--rail), var(--accent) 12%); --minimap-window: var(--field); --minimap-mask: color-mix(in oklab, var(--seed-bg) 65%, transparent); --shade: color-mix(in oklab, var(--seed-fg) 70%, #000); --shadow: 0 1px 2px color-mix(in oklab, var(--shade) 7%, transparent), 0 10px 28px -8px color-mix(in oklab, var(--shade) 16%, transparent); --shadow-raised: 0 2px 4px color-mix(in oklab, var(--shade) 8%, transparent), 0 22px 48px -12px color-mix(in oklab, var(--shade) 26%, transparent); --shadow-lg: 0 4px 12px color-mix(in oklab, var(--shade) 9%, transparent), 0 32px 72px -16px color-mix(in oklab, var(--shade) 34%, transparent); /* A section's ground: sunk below the board, a tray its windows sit in, and a step toward `--section-lift` for each section round it (`--depth`). */ --section-base: 9%; --section-lift: #000; --section-step: 5%; --section-sunk: inset 0 1px 3px color-mix(in oklab, var(--shade) 14%, transparent); /* Text size, as ratios of the 13px base: every font size reads through one. The canvas follows the chrome unless the settings give it its own size. */ --ui-scale: 1; --canvas-scale: var(--ui-scale); --sans: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif; --mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; /* Faces read softest in a rounded Japanese face where there is one. */ --face: 'Hiragino Maru Gothic ProN', 'Hiragino Sans', 'Yu Gothic UI', system-ui, sans-serif;}
/* In the dark, windows lift toward the ink and chrome sinks below the ground. */:root[data-theme='dark'] { color-scheme: dark; --seed-bg: #241c26; --seed-fg: #e1d1e7; --seed-accent: #ddb3ff; --contrast: 0.5; --rail: color-mix(in oklab, var(--seed-bg), #000 calc(20% * var(--k))); --surface: color-mix(in oklab, var(--seed-bg), var(--seed-fg) calc(5% * var(--k))); --title-bar: color-mix(in oklab, var(--surface), var(--seed-fg) calc(2.5% * var(--k))); --well: color-mix(in oklab, var(--surface), #000 calc(16% * var(--k))); --field: color-mix(in oklab, var(--surface), var(--seed-fg) calc(7% * var(--k))); --bubble: color-mix(in oklab, var(--field), var(--seed-accent) 9%); --muted: color-mix(in oklab, var(--seed-fg), var(--surface) calc(42% - 20% * var(--contrast))); --faint: color-mix(in oklab, var(--seed-fg), var(--surface) calc(60% - 20% * var(--contrast))); --you: oklch(from var(--seed-accent) 0.82 0.08 calc(h - 130)); --added: #c1dd4a; --danger: #ff8b79; --dots: color-mix(in oklab, var(--seed-fg) calc(26% * var(--k)), transparent); --shade: #000; --shadow: 0 1px 2px rgb(0 0 0 / 0.4), 0 12px 32px -8px rgb(0 0 0 / 0.6); --shadow-raised: 0 2px 4px rgb(0 0 0 / 0.45), 0 24px 56px -12px rgb(0 0 0 / 0.75); --shadow-lg: 0 4px 12px rgb(0 0 0 / 0.5), 0 32px 80px -16px rgb(0 0 0 / 0.8); /* Near black every step darker looks the same, so in the dark a section in a section lifts. */ --section-base: 38%; --section-lift: var(--text); --section-step: 10%; --section-sunk: inset 0 1px 3px rgb(0 0 0 / 0.45); --rail-stripe: color-mix(in oklab, var(--rail), var(--shade) calc(19% * var(--k))); --open-tint: color-mix(in oklab, var(--rail), var(--accent) 18%);}
* { box-sizing: border-box;}
html,body,#app { height: 100%; margin: 0;}
/* A sideways two-finger swipe pans the canvas; without this the browser reads the same gesture as back/forward. */html,body { overscroll-behavior: none;}
body { overflow: hidden; color: var(--text); font-family: var(--sans); font-size: calc(13px * var(--ui-scale)); line-height: 1.45; background: var(--bg); -webkit-font-smoothing: antialiased;}
kbd { display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 5px; color: var(--muted); font-family: var(--sans); font-size: calc(11px * var(--ui-scale)); background: var(--hover); border-radius: 5px;}
button:focus-visible,input:focus-visible,[role='tab']:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px;}
/* A kaomoji: albedo's face for a turn, still or animated. */.kaomoji { font-family: var(--face); letter-spacing: -0.03em; white-space: pre;}
/* The wordmark, swept from mauve to pink as in the terminal's header. */.brand-ink { color: var(--brand-from); background: linear-gradient(90deg, var(--brand-from), var(--brand-to)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;}
/* Svelte Flow takes the app's colours. */.svelte-flow { --xy-background-color: var(--bg);}
.svelte-flow__node:focus-visible { outline: none;}
.svelte-flow__node.dragging .window { box-shadow: var(--shadow-lg);}
/* A window and the views it opened are tied by a faint line. */.svelte-flow .tether-end { width: 1px; height: 1px; min-width: 0; min-height: 0; background: transparent; border: 0; pointer-events: none;}
.svelte-flow .tether path { stroke: color-mix(in oklab, var(--accent) 40%, transparent); stroke-width: 1.5; stroke-dasharray: 4 6;}
/* Window edges and corners resize but draw nothing until hovered. */.svelte-flow .window-edge { border-color: transparent; border-width: 4px;}
.svelte-flow .window-corner { width: 14px; height: 14px; background: transparent; border: 0;}
/* A drag on an edge, a corner or a title bar is always the canvas's, never a scroll. */.svelte-flow .svelte-flow__resize-control,.svelte-flow .window-handle,.svelte-flow .note-handle { touch-action: none;}
/* A finger needs far more to aim at than a pointer: the edges and corners reach well past the window, still drawing nothing. */@media (pointer: coarse) { .svelte-flow .window-edge { border-width: 14px; } .svelte-flow .window-corner { width: 40px; height: 40px; }}
/* Above the view controls in the same corner. */.svelte-flow__minimap { margin: 14px 14px 60px; overflow: hidden; border-radius: 12px; box-shadow: var(--shadow);}
/* A section's frame, in the tiles (tiles/TileView.svelte) or a group on a canvas (nodes/SlotNode.svelte): a tray sunk below the board, and one step on for each section round it. */.tray { background: color-mix(in oklab, color-mix(in oklab, var(--bg), #000 var(--section-base)), var(--section-lift) calc(var(--depth, 0) * var(--section-step))); border-radius: 16px; box-shadow: var(--section-sunk);}/* A section in a section is edged too: its step alone is slight. */.tray.nested { box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--text) 14%, transparent), var(--section-sunk);}
/* The selected or picked pane (tiles/WindowSlot.svelte, tiles/TileView.svelte, nodes/SlotNode.svelte): its title or header in the accent and a faint ring, or a 2px outline when picked. */.window-slot.selected > .window-host header h2,.tray.selected > .section-head { color: var(--accent);}.window-slot.selected:not(.picked)::after,.tray.selected:not(.picked)::after { position: absolute; inset: 0; border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent); border-radius: inherit; content: ''; pointer-events: none;}.canvas-tile.nested.selected:not(.picked) { box-shadow: 0 0 0 1px color-mix(in oklab, var(--accent) 35%, transparent);}[data-theme='dark'] .window-slot.selected:not(.picked)::after,[data-theme='dark'] .tray.selected:not(.picked)::after { border-color: color-mix(in oklab, var(--accent) 55%, transparent);}[data-theme='dark'] .canvas-tile.nested.selected:not(.picked) { box-shadow: 0 0 0 1px color-mix(in oklab, var(--accent) 55%, transparent);}.window-slot.picked::after { position: absolute; inset: 0; border: 2px solid var(--accent); border-radius: inherit; content: ''; pointer-events: none;}.tray.picked,.canvas-tile.picked { box-shadow: 0 0 0 2px var(--accent);}