diff --git a/docs/reports/2026-09-12-ui-visual-review-delivery.md b/docs/reports/2026-09-12-ui-visual-review-delivery.md index 4270bdbc..9984c5b4 100644 --- a/docs/reports/2026-09-12-ui-visual-review-delivery.md +++ b/docs/reports/2026-09-12-ui-visual-review-delivery.md @@ -75,6 +75,18 @@ assoluti. Sulle larghezze ridotte gli stati continuano a disporsi senza sovrappo Passati 9 scenari Playwright, con assert geometrici sugli allineamenti richiesti. Pubblicazione limitata al frontend Docker del worktree di revisione, nessun merge. +## Follow-up: margini esterni e assi interni (2026-09-13) + +La verifica geometrica iniziale rilevava 20 px di differenza fra il bordo sinistro +del riepilogo e quello della tabella. In accordo con Impeccable, introdotti due token: +margine esterno condiviso di 20 px e padding interno di 16 px. Catalog summary, +navigazione Databases e tabella hanno bordi sinistro/destro coincidenti; riepilogo, +Tables, Databases e Workspace databases condividono l'asse testuale a 36 px. +Header, toolbar azioni e stati seguono lo stesso asse. Conservato l'allineamento +Metadata updated/Description coverage e Operations al punto medio sui layout ampi. +Passati 9 scenari Playwright con assert geometrici a 390, 649, 768, 1280 e 1600 px. +Nessuna modifica funzionale; aggiornamento Docker limitato al frontend di revisione. + ## Verifica | Verifica | Esito | diff --git a/frontend/e2e/ui-visual-review.spec.ts b/frontend/e2e/ui-visual-review.spec.ts index 7cd60b87..456d35e4 100644 --- a/frontend/e2e/ui-visual-review.spec.ts +++ b/frontend/e2e/ui-visual-review.spec.ts @@ -155,6 +155,19 @@ for (const width of [390, 649, 768, 1280, 1600]) { const operations = await statuses.nth(1).boundingBox(); const metadata = await statuses.nth(2).boundingBox(); const summary = await page.locator(".thot-fleet-ledger__kpi-section > h2").boundingBox(); + const summaryBlock = await page.locator(".thot-fleet-ledger__kpi-section").boundingBox(); + const navigationBlock = await page.locator(".thot-fleet-ledger__navigation").boundingBox(); + const gridBlock = await page.locator(".thot-fleet-ledger__content").boundingBox(); + const databasesLabel = await page.locator(".thot-fleet-ledger__navigation").getByText("Databases", { exact: true }).boundingBox(); + const tablesLabel = await page.locator(".thot-fleet-ledger__kpi-label").getByText("Tables", { exact: true }).boundingBox(); + expect(Math.abs(summaryBlock!.x - gridBlock!.x)).toBeLessThan(1); + expect(Math.abs(navigationBlock!.x - gridBlock!.x)).toBeLessThan(1); + expect(Math.abs(summary!.x - databasesLabel!.x)).toBeLessThan(1); + expect(Math.abs(summary!.x - tablesLabel!.x)).toBeLessThan(1); + const gridLabel = await page.locator(".thot-fleet-grid-toolbar").getByText("Workspace databases", { exact: true }).boundingBox(); + expect(Math.abs(summary!.x - gridLabel!.x)).toBeLessThan(1); + expect(Math.abs(summaryBlock!.width - gridBlock!.width)).toBeLessThan(1); + expect(Math.abs(navigationBlock!.width - gridBlock!.width)).toBeLessThan(1); expect(Math.abs(catalog!.x - summary!.x)).toBeLessThan(1); const workArea = await page.locator(".thot-fleet-ledger__workspace").boundingBox(); if (workArea!.width >= 768) { diff --git a/frontend/src/shell/database-management/FleetLedgerShell.css b/frontend/src/shell/database-management/FleetLedgerShell.css index 1cb233e4..de53b284 100644 --- a/frontend/src/shell/database-management/FleetLedgerShell.css +++ b/frontend/src/shell/database-management/FleetLedgerShell.css @@ -14,7 +14,9 @@ } .thot-fleet-ledger__workspace { - --fleet-summary-inset: 1.25rem; + --fleet-block-gutter: 1.25rem; + --fleet-block-padding: 1rem; + --fleet-summary-inset: calc(var(--fleet-block-gutter) + var(--fleet-block-padding)); display: flex; flex: 1; flex-direction: column; @@ -105,6 +107,11 @@ padding-inline: var(--fleet-summary-inset); } +.thot-fleet-ledger .thot-administration-header, +.thot-fleet-ledger .thot-administration-toolbar { + padding-inline: var(--fleet-summary-inset); +} + .thot-fleet-ledger__header-status > .thot-fleet-ledger__status { display: block; padding: 0; @@ -221,7 +228,8 @@ .thot-fleet-ledger__kpi-section { display: grid; gap: 0.625rem; - padding: 0.75rem var(--fleet-summary-inset) 0; + margin-inline: var(--fleet-block-gutter); + padding: 0.75rem var(--fleet-block-padding) 0; border-bottom: 1px solid oklch(var(--border)); background: oklch(var(--card)); } @@ -272,7 +280,8 @@ min-height: 3rem; gap: 0.5rem; align-items: center; - padding: 0.5rem 1rem; + margin-inline: var(--fleet-block-gutter); + padding: 0.5rem var(--fleet-block-padding); border-bottom: 1px solid oklch(var(--border)); background: oklch(var(--card)); } @@ -456,7 +465,7 @@ min-width: 0; min-height: 18rem; margin-block-end: 30px; - margin-inline-start: 20px; + margin-inline: var(--fleet-block-gutter); overflow: hidden; border-inline-end: 1px solid oklch(var(--border)); background: oklch(var(--card)); @@ -616,6 +625,10 @@ background: oklch(var(--muted) / 0.32); } +.thot-fleet-ledger .thot-fleet-grid-toolbar { + padding-inline: var(--fleet-block-padding); +} + @media (min-width: 48rem) { .thot-fleet-grid-toolbar > .thot-fleet-action-selector { flex: 0 0 auto; @@ -813,9 +826,6 @@ } @media (min-width: 64rem) { - .thot-fleet-ledger__workspace { - --fleet-summary-inset: 1.5rem; - } .thot-fleet-ledger__header { padding-inline: 1.5rem; } @@ -826,7 +836,6 @@ padding-inline: 1.5rem; } - .thot-fleet-ledger__navigation, .thot-fleet-ledger__command-bar { padding-inline: 1.25rem; }