mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
fix(ui): paint the Galaxy overlays opaque so no scene label shows through
Since K29 the scene labels lie below the Galaxy overlays, but the overlays let a little of the scene through: Selection details at .95, the path panel at .94, the hierarchy key and the loading pill at .9, the menus at .98, fit view at 82 %, the agents instrument at 88 and 92 %. The path target's name and its ring still showed through Selection details. Every overlay over the scene now keeps its colour without transparency. Signed-off-by: Bernhard Jackiewicz <bj@techport.io>
This commit is contained in:
1 parent
dc931f7fe9
commit
17ec5b8f22
4 files changed
+99
-20
No files matched your search
@@ -2943,9 +2943,9 @@ export default function GalaxyPanel(props: GalaxyPanelProps): JSX.Element {
|
||||
* Das Instrument liegt IM Kasten der Szene und nicht darunter:
|
||||
* es erklaert, was auf dem Graphen zu sehen ist, und ein Kasten
|
||||
* daneben waere eine zweite Flaeche, die man zwischen Bild und
|
||||
* Text hin und her lesen muesste. Es ist halbtransparent und
|
||||
* faengt seine eigenen Klicks ab; der Rest der Flaeche bleibt
|
||||
* die Szene.
|
||||
* Text hin und her lesen muesste. Es ist deckend (Review zu
|
||||
* K29) und faengt seine eigenen Klicks ab; der Rest der Flaeche
|
||||
* bleibt die Szene.
|
||||
*/}
|
||||
{liveOn && agentsView !== undefined && props.agents !== undefined && (
|
||||
<AgentsHud
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.atlas-galaxy-search-container { position:relative; flex:1 1 12rem; min-width:9rem; max-width:32rem; }
|
||||
.atlas-galaxy-search-container > input { box-sizing:border-box; width:100%; min-height:2rem; padding:.4rem .65rem; border:1px solid #29473a; border-radius:6px; background:rgba(7,17,12,.65); color:var(--atlas-fg,#cbdbd0); font:inherit; }
|
||||
.atlas-galaxy-search-container > input:focus { outline:1px solid #6d9a84; border-color:#6d9a84; }
|
||||
.atlas-galaxy-search-results { position:absolute; top:calc(100% + .4rem); left:0; z-index:35; width:min(34rem, calc(100vw - 2rem)); padding:.5rem; border:1px solid #355246; border-radius:8px; background:rgba(13,25,19,.98); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-galaxy-search-results { position:absolute; top:calc(100% + .4rem); left:0; z-index:35; width:min(34rem, calc(100vw - 2rem)); padding:.5rem; border:1px solid #355246; border-radius:8px; background:rgb(13,25,19); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-graph-exploration label { display:flex; align-items:center; gap:.35rem; color:var(--muted, #a0b6aa); }
|
||||
.atlas-graph-exploration select { padding:.2rem .35rem; background:#102019; color:#d4ded8; border:1px solid #29473a; border-radius:5px; }
|
||||
.atlas-graph-coverage-filter { cursor:pointer; white-space:nowrap; }
|
||||
@@ -60,11 +60,11 @@
|
||||
/* Der Deckel im Scope: dieselbe Bauform wie die Kantenarten (Review-Befund G7). */
|
||||
.atlas-graph-limits { position:relative; }
|
||||
.atlas-graph-limits > summary { padding:.25rem .5rem; border:1px solid #29473a; border-radius:6px; cursor:pointer; color:#b5c9bc; white-space:nowrap; }
|
||||
.atlas-graph-limits-menu { position:absolute; top:calc(100% + .35rem); right:0; z-index:30; display:flex; flex-direction:column; align-items:flex-end; gap:.45rem; padding:.6rem; border:1px solid #355246; border-radius:8px; background:rgba(13,25,19,.98); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-graph-limits-menu { position:absolute; top:calc(100% + .35rem); right:0; z-index:30; display:flex; flex-direction:column; align-items:flex-end; gap:.45rem; padding:.6rem; border:1px solid #355246; border-radius:8px; background:rgb(13,25,19); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-graph-scope-warning { width:100%; color:#c6aa82; }
|
||||
.atlas-trace-edge-filter { position:relative; }
|
||||
.atlas-trace-edge-filter > summary { padding:.25rem .5rem; border:1px solid #29473a; border-radius:6px; cursor:pointer; color:#b5c9bc; }
|
||||
.atlas-trace-edge-menu { position:absolute; top:calc(100% + .35rem); left:0; z-index:30; width:min(20rem, calc(100vw - 3rem)); max-height:22rem; overflow:auto; padding:.65rem; border:1px solid #355246; border-radius:8px; background:rgba(13,25,19,.98); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-trace-edge-menu { position:absolute; top:calc(100% + .35rem); left:0; z-index:30; width:min(20rem, calc(100vw - 3rem)); max-height:22rem; overflow:auto; padding:.65rem; border:1px solid #355246; border-radius:8px; background:rgb(13,25,19); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-trace-edge-actions { display:flex; gap:.4rem; margin-bottom:.4rem; }
|
||||
.atlas-trace-edge-menu small { display:block; color:#95a89e; margin-bottom:.4rem; }
|
||||
.atlas-trace-edge-row { display:flex; justify-content:space-between; align-items:center; gap:.5rem; padding:.2rem 0; }
|
||||
@@ -78,7 +78,8 @@
|
||||
.atlas-galaxy-node-picker button span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:.75rem; }
|
||||
.atlas-galaxy-node-picker .atlas-graph-result-kind { min-width:3rem; color:#91b6a3; }
|
||||
|
||||
.galaxy-selection-evidence.atlas-galaxy-selection-details { top:auto; bottom:12px; right:12px; width:auto; height:auto; max-width:calc(100% - 24px); max-height:55%; padding:0; border-radius:7px; background:rgba(13, 25, 19, .95); }
|
||||
/* Review zu K29: jede Flaeche ueber der Szene ist deckend; durch .95 schienen der Name des Pfadziels und sein Ring hindurch. */
|
||||
.galaxy-selection-evidence.atlas-galaxy-selection-details { top:auto; bottom:12px; right:12px; width:auto; height:auto; max-width:calc(100% - 24px); max-height:55%; padding:0; border-radius:7px; background:rgb(13, 25, 19); }
|
||||
.galaxy-selection-evidence.atlas-galaxy-selection-details > summary { padding:.5rem .75rem; color:#b5c9bc; font-size:.8rem; cursor:pointer; }
|
||||
.galaxy-selection-evidence.atlas-galaxy-selection-details[open] { width:min(420px, calc(100% - 24px)); max-height:min(24rem, 55%); }
|
||||
.atlas-galaxy-selection-details-body { padding:0 .75rem .75rem; }
|
||||
@@ -86,7 +87,7 @@
|
||||
.galaxy-selection-evidence.atlas-galaxy-selection-details[open] { max-height:38%; }
|
||||
}
|
||||
|
||||
.atlas-graph-render-progress { position:absolute; z-index:30; top:12px; left:50%; transform:translateX(-50%); display:flex; align-items:center; gap:.5rem; max-width:calc(100% - 24px); box-sizing:border-box; padding:.45rem .75rem; border:1px solid #6c88764d; border-radius:999px; background:rgba(14,25,20,.9); color:#b9cdc1; box-shadow:0 3px 12px #0003; pointer-events:none; font:12px/1.4 var(--atlas-ui-font,system-ui,sans-serif); }
|
||||
.atlas-graph-render-progress { position:absolute; z-index:30; top:12px; left:50%; transform:translateX(-50%); display:flex; align-items:center; gap:.5rem; max-width:calc(100% - 24px); box-sizing:border-box; padding:.45rem .75rem; border:1px solid #6c88764d; border-radius:999px; background:rgb(14,25,20); color:#b9cdc1; box-shadow:0 3px 12px #0003; pointer-events:none; font:12px/1.4 var(--atlas-ui-font,system-ui,sans-serif); }
|
||||
.atlas-graph-render-progress > span:last-child { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
||||
.atlas-graph-render-spinner { width:12px; height:12px; box-sizing:border-box; flex:none; border:1.5px solid #99b7a52e; border-top-color:#a8c4b3; border-radius:50%; animation:atlas-graph-render-spin .8s linear infinite; }
|
||||
@keyframes atlas-graph-render-spin { to { transform:rotate(360deg); } }
|
||||
@@ -95,14 +96,14 @@
|
||||
/* Der Pfad: Auswahl in der Werkzeugleiste, Schrittliste in der Szene, Beschriftung und Ring an den Kanten. */
|
||||
.atlas-graph-path-picker { position:relative; }
|
||||
.atlas-graph-path-picker > summary { padding:.25rem .5rem; border:1px solid #29473a; border-radius:6px; cursor:pointer; color:#b5c9bc; white-space:nowrap; }
|
||||
.atlas-graph-path-menu { position:absolute; top:calc(100% + .35rem); left:0; z-index:30; width:min(22rem, calc(100vw - 3rem)); padding:.55rem; border:1px solid #355246; border-radius:8px; background:rgba(13,25,19,.98); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-graph-path-menu { position:absolute; top:calc(100% + .35rem); left:0; z-index:30; width:min(22rem, calc(100vw - 3rem)); padding:.55rem; border:1px solid #355246; border-radius:8px; background:rgb(13,25,19); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-graph-path-menu input { box-sizing:border-box; width:100%; padding:.35rem .5rem; border:1px solid #29473a; border-radius:5px; background:rgba(7,17,12,.65); color:var(--atlas-fg,#cbdbd0); font:inherit; }
|
||||
.atlas-graph-path-menu ul { max-height:18rem; overflow:auto; list-style:none; padding:0; margin:.45rem 0 0; }
|
||||
.atlas-graph-path-menu button { width:100%; display:flex; gap:.5rem; align-items:baseline; text-align:left; border:0; background:transparent; }
|
||||
.atlas-graph-path-menu button span { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:.72rem; color:#95a89e; }
|
||||
.atlas-graph-path-menu small { display:block; color:#95a89e; margin-top:.4rem; }
|
||||
.atlas-graph-exploration button[aria-pressed=true] { border-color:#80ac96; background:rgba(68, 112, 86, .3); }
|
||||
.atlas-galaxy-path-panel { position:absolute; z-index:25; top:12px; left:12px; display:flex; flex-direction:column; gap:.35rem; width:min(26rem, calc(100% - 24px)); max-height:min(22rem, 55%); box-sizing:border-box; padding:.55rem .65rem; border:1px solid #355246; border-radius:8px; background:rgba(13, 25, 19, .94); color:#cbdbd0; font-size:.78rem; }
|
||||
.atlas-galaxy-path-panel { position:absolute; z-index:25; top:12px; left:12px; display:flex; flex-direction:column; gap:.35rem; width:min(26rem, calc(100% - 24px)); max-height:min(22rem, 55%); box-sizing:border-box; padding:.55rem .65rem; border:1px solid #355246; border-radius:8px; background:rgb(13, 25, 19); color:#cbdbd0; font-size:.78rem; }
|
||||
.atlas-galaxy-path-panel header, .atlas-galaxy-path-panel footer { display:flex; align-items:center; justify-content:space-between; gap:.5rem; }
|
||||
.atlas-galaxy-path-panel p { margin:0; color:#c6aa82; }
|
||||
.atlas-galaxy-path-panel ol { flex:1 1 auto; min-height:0; overflow:auto; margin:0; padding:0; list-style:none; }
|
||||
@@ -129,14 +130,14 @@
|
||||
/* Zweites Review zu K5: die Ueberschrift des Bandes unter den Spalten und die Notiz, wenn Namen fehlen. */
|
||||
.atlas-hierarchy-band-label { display:flex; flex-direction:column; align-items:center; gap:1px; padding:2px 8px; border:1px dashed #6f8f80; border-radius:5px; background:rgba(13, 15, 18, .86); color:#d7e6dd; white-space:nowrap; font:600 11px/1.35 var(--atlas-ui-font, system-ui, sans-serif); }
|
||||
.atlas-hierarchy-band-label small { color:#a9bdb2; font-weight:400; font-size:10px; }
|
||||
.atlas-hierarchy-key { position:absolute; z-index:20; left:12px; bottom:12px; max-width:min(34rem, calc(100% - 24px)); margin:0; padding:.35rem .6rem; border:1px solid #355246; border-radius:6px; background:rgba(13, 25, 19, .9); color:#cbdbd0; font:12px/1.4 var(--atlas-ui-font, system-ui, sans-serif); pointer-events:none; }
|
||||
.atlas-hierarchy-key { position:absolute; z-index:20; left:12px; bottom:12px; max-width:min(34rem, calc(100% - 24px)); margin:0; padding:.35rem .6rem; border:1px solid #355246; border-radius:6px; background:rgb(13, 25, 19); color:#cbdbd0; font:12px/1.4 var(--atlas-ui-font, system-ui, sans-serif); pointer-events:none; }
|
||||
|
||||
/* Zurueck, Vor und die letzten Wurzeln (Handtest K2): klein, damit die Leiste einzeilig bleibt (K3). */
|
||||
.atlas-graph-history { display:flex; align-items:center; gap:.25rem; flex:none; }
|
||||
.atlas-graph-history > button { min-width:1.9rem; padding:.25rem .45rem; }
|
||||
.atlas-graph-recent { position:relative; }
|
||||
.atlas-graph-recent > summary { padding:.25rem .5rem; border:1px solid #29473a; border-radius:6px; cursor:pointer; color:#b5c9bc; white-space:nowrap; }
|
||||
.atlas-graph-recent-menu { position:absolute; top:calc(100% + .35rem); left:0; z-index:30; width:min(24rem, calc(100vw - 3rem)); max-height:18rem; overflow:auto; margin:0; padding:.45rem; list-style:none; border:1px solid #355246; border-radius:8px; background:rgba(13,25,19,.98); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-graph-recent-menu { position:absolute; top:calc(100% + .35rem); left:0; z-index:30; width:min(24rem, calc(100vw - 3rem)); max-height:18rem; overflow:auto; margin:0; padding:.45rem; list-style:none; border:1px solid #355246; border-radius:8px; background:rgb(13,25,19); box-shadow:0 8px 24px #0005; }
|
||||
.atlas-graph-recent-menu button { width:100%; display:flex; flex-direction:column; align-items:flex-start; gap:.1rem; text-align:left; border:0; background:transparent; }
|
||||
.atlas-graph-recent-menu button span { max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:.72rem; color:#95a89e; }
|
||||
.atlas-graph-recent-menu button[aria-current=true] { opacity:.6; }
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Handtest 2026-10-04, Review zu K29: die Namen der Szene liegen seit G1 unter
|
||||
* den Bedienflaechen der Galaxie, aber die Flaechen waren leicht durchsichtig
|
||||
* (.9 bis .98, die Schaltflaeche "fit view" 82 %). Der Name des Pfadziels und
|
||||
* sein Ring schienen darum durch "Selection details" hindurch. Hier steht, dass
|
||||
* jede Flaeche, die ueber der Szene liegt, deckend gemalt wird.
|
||||
*/
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
const read = (path: string) => readFileSync(new URL(path, import.meta.url), 'utf8').replace(/\/\*[\s\S]*?\*\//g, '');
|
||||
const SHEETS = [read('./graph-exploration.css'), read('../styles/terminal.css'), read('../styles/workspace.css')];
|
||||
|
||||
/** The background of the last rule, across the sheets, whose selector list names `selector` exactly. */
|
||||
function background(selector: string): string | undefined {
|
||||
let found: string | undefined;
|
||||
for (const css of SHEETS) {
|
||||
for (const match of css.matchAll(/([^{}]+)\{([^}]*)\}/g)) {
|
||||
if (!match[1]!.split(',').map(item => item.trim().replace(/\s+/g, ' ')).includes(selector)) continue;
|
||||
for (const part of match[2]!.split(';')) {
|
||||
const [name, ...value] = part.split(':');
|
||||
if (name && ['background', 'background-color'].includes(name.trim())) found = value.join(':').trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/** True when the colour hides everything behind it: no alpha below one. Tokens of this project are plain hex colours. */
|
||||
function opaque(value: string): boolean {
|
||||
if (/^var\(--atlas-(bg|panel|panel-raised)\)$/.test(value)) return true;
|
||||
if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(value)) return true;
|
||||
const rgb = /^rgba?\(([^)]*)\)$/.exec(value);
|
||||
if (!rgb) return false;
|
||||
const parts = rgb[1]!.split(/[\s,/]+/).filter(Boolean);
|
||||
if (parts.length === 3) return true;
|
||||
const alpha = parts[3]!;
|
||||
return alpha.endsWith('%') ? Number.parseFloat(alpha) >= 100 : Number.parseFloat(alpha) >= 1;
|
||||
}
|
||||
|
||||
const OVERLAYS = {
|
||||
'Selection details': '.galaxy-selection-evidence.atlas-galaxy-selection-details',
|
||||
'path panel': '.atlas-galaxy-path-panel',
|
||||
'hierarchy key': '.atlas-hierarchy-key',
|
||||
'fit view': '.atlas-galaxy-fit',
|
||||
'render progress': '.atlas-graph-render-progress',
|
||||
'search results': '.atlas-galaxy-search-results',
|
||||
'Path to menu': '.atlas-graph-path-menu',
|
||||
'Edge types menu': '.atlas-trace-edge-menu',
|
||||
'more and Limits menu': '.atlas-graph-limits-menu',
|
||||
'Recent menu': '.atlas-graph-recent-menu',
|
||||
'node picker': '.atlas-galaxy-node-picker',
|
||||
'agents instrument': '.atlas-agents',
|
||||
'agents follow line': '.atlas-agents-followline',
|
||||
'agents timeline': '.atlas-agents-timeline',
|
||||
'placeholder': '.atlas-galaxy-placeholder',
|
||||
'hover card': '.atlas-galaxy-card',
|
||||
'coverage hover card': '.atlas-coverage-tooltip',
|
||||
};
|
||||
|
||||
describe('K29: nothing of the scene shows through a Galaxy overlay', () => {
|
||||
for (const [name, selector] of Object.entries(OVERLAYS)) {
|
||||
it(`${name} is painted opaque`, () => {
|
||||
const value = background(selector);
|
||||
expect(value, `${selector} has no background`).toBeDefined();
|
||||
expect(opaque(value!), `${selector}: ${value}`).toBe(true);
|
||||
});
|
||||
}
|
||||
|
||||
it('reads alpha in every notation the sheets use', () => {
|
||||
expect(opaque('rgba(13, 25, 19, .95)')).toBe(false);
|
||||
expect(opaque('rgb(10 14 13 / 82%)')).toBe(false);
|
||||
expect(opaque('rgb(13, 25, 19)')).toBe(true);
|
||||
expect(opaque('#0d1913')).toBe(true);
|
||||
expect(opaque('#0d191380')).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -2369,8 +2369,8 @@ button.atlas-galaxy-legend-swatch:hover {
|
||||
/*
|
||||
* Der Weg zurueck zur eingepassten Ansicht (W10b, AC5).
|
||||
*
|
||||
* Oben rechts in der Szene, halbtransparent, in derselben Schrift wie alles
|
||||
* hier. Er liegt bewusst IM Bild und nicht im Kopf: die Kopfzeile ist bei 440
|
||||
* Oben rechts in der Szene, deckend (Review zu K29: durch 82 % schien ein
|
||||
* Name der Szene hindurch), in derselben Schrift wie alles hier. Er liegt bewusst IM Bild und nicht im Kopf: die Kopfzeile ist bei 440
|
||||
* Pixeln Breite voll (siehe .atlas-galaxy-head-row), und ein Wort mehr darin
|
||||
* haette den Zuklapper abgeschnitten. Die andere Ecke gehoert dem Instrument
|
||||
* der Agentenebene, also stehen sich die beiden nie im Weg.
|
||||
@@ -2382,7 +2382,7 @@ button.atlas-galaxy-legend-swatch:hover {
|
||||
z-index: 3;
|
||||
padding: 1px 6px;
|
||||
border: 1px solid var(--atlas-line);
|
||||
background: rgb(10 14 13 / 82%);
|
||||
background: rgb(10 14 13);
|
||||
color: var(--atlas-dim);
|
||||
font: inherit;
|
||||
font-size: 11px;
|
||||
@@ -5881,8 +5881,9 @@ button.atlas-settings-model-pick:focus-visible {
|
||||
/*
|
||||
* Das Instrument unten rechts.
|
||||
*
|
||||
* Halbtransparent ueber dem Graphen, in derselben Schrift und mit denselben
|
||||
* duennen Raendern wie der Rest der Oberflaeche. Kein Glassmorphism: keine
|
||||
* Deckend ueber dem Graphen (Review zu K29: durch eine halbtransparente
|
||||
* Flaeche schienen die Namen der Szene hindurch), in derselben Schrift und mit
|
||||
* denselben duennen Raendern wie der Rest der Oberflaeche. Kein Glassmorphism: keine
|
||||
* Weichzeichnung, kein Verlauf, kein runder Kasten. Was hier "fancy" ist, kommt
|
||||
* aus dem Licht der Koerper daneben und nicht aus der Flaeche.
|
||||
*/
|
||||
@@ -5897,7 +5898,7 @@ button.atlas-settings-model-pick:focus-visible {
|
||||
max-width: calc(100% - 16px);
|
||||
max-height: calc(100% - 16px);
|
||||
border: 1px solid var(--atlas-line);
|
||||
background: rgb(10 14 13 / 88%);
|
||||
background: rgb(10 14 13);
|
||||
color: var(--atlas-fg);
|
||||
font-family: var(--atlas-font);
|
||||
font-size: 11px;
|
||||
@@ -6342,7 +6343,7 @@ button.atlas-settings-model-pick:focus-visible {
|
||||
margin: 0 0 2px;
|
||||
padding: 2px 8px;
|
||||
border: 1px solid var(--atlas-line);
|
||||
background: rgb(10 14 13 / 88%);
|
||||
background: rgb(10 14 13);
|
||||
color: var(--atlas-agent-color, var(--atlas-fg));
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
@@ -6366,7 +6367,7 @@ button.atlas-settings-model-pick:focus-visible {
|
||||
gap: 2px;
|
||||
padding: 3px 8px 4px;
|
||||
border-top: 1px solid var(--atlas-line);
|
||||
background: rgb(10 14 13 / 92%);
|
||||
background: rgb(10 14 13);
|
||||
font-family: var(--atlas-font);
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user