fix(tables,profile): define spacing tokens (gutters + cell padding); profile rows open the .zddc form

The tables tool referenced --spacing-sm/md/lg (14×) but they were never
defined and used no fallbacks, so every padding/margin/gap collapsed to 0 —
table cells had no vertical padding and the table sat flush to the viewport
edges. Define --spacing-sm/md/lg (+ alias the --color-*/--radius-sm names the
tool uses) in shared/base.css, and give .table-main a clear left/right gutter
(padding: md lg). Fixes every tables view (profile/tokens/diagnostics/mdl).

Profile: clicking a project (or admin-subtree) row now opens that scope's
.zddc INFO FORM in the browse editor (via the ?file=.zddc deep link →
selects + previews the .zddc → schema-driven Title/Roles/Admins form),
instead of navigating into the project's files. Diagnostic rows still link
to their endpoints.

Validated in a containerized browser: 24px side gutters + padded rows;
clicking Proj → /Proj/?file=.zddc → the .zddc form editor. Full suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZDDC 2026-06-07 08:13:54 -05:00
parent 1b9fec66b3
commit 14f8780dc5
4 changed files with 49 additions and 5 deletions

View file

@ -35,6 +35,20 @@
/* Shape */ /* Shape */
--radius: 4px; --radius: 4px;
/* Spacing scale referenced by the tables tool (tables/css/table.css).
Were undefined (var() with no fallback collapsed to 0), which left
table cells unpadded and the table flush to the viewport edges. */
--spacing-sm: 0.4rem;
--spacing-md: 0.8rem;
--spacing-lg: 1.5rem;
/* Token aliases the tables tool references under --color-*/--radius-*
names; map them to the canonical tokens (themed values flow through). */
--color-text-muted: var(--text-muted);
--color-border: var(--border);
--color-bg-elevated: var(--bg-secondary);
--radius-sm: var(--radius);
/* Typography. --font-display covers headings (Source Serif 4 a refined /* Typography. --font-display covers headings (Source Serif 4 a refined
transitional serif that reads as "engineering / document / serious" transitional serif that reads as "engineering / document / serious"
without being academic). --font is body UI text (IBM Plex Sans without being academic). --font is body UI text (IBM Plex Sans

View file

@ -1,7 +1,9 @@
/* tables/ — directory-of-YAML table view. Reuses tokens from shared/base.css. */ /* tables/ — directory-of-YAML table view. Reuses tokens from shared/base.css. */
.table-main { .table-main {
padding: var(--spacing-md); /* Vertical breathing room + clear left/right gutters so the table isn't
flush to the viewport edges. */
padding: var(--spacing-md) var(--spacing-lg);
max-width: 100%; max-width: 100%;
} }

View file

@ -3,6 +3,7 @@ package handler
import ( import (
"html/template" "html/template"
"net/http" "net/http"
"strings"
"codeberg.org/VARASYS/ZDDC/zddc/internal/config" "codeberg.org/VARASYS/ZDDC/zddc/internal/config"
"codeberg.org/VARASYS/ZDDC/zddc/internal/zddc" "codeberg.org/VARASYS/ZDDC/zddc/internal/zddc"
@ -79,17 +80,28 @@ func serveProfilePage(cfg config.Config, w http.ResponseWriter, r *http.Request)
// project" to POST /.profile/projects (only when the caller can create one). // project" to POST /.profile/projects (only when the caller can create one).
func buildProfileTableContext(cfg config.Config, r *http.Request) map[string]interface{} { func buildProfileTableContext(cfg config.Config, r *http.Request) map[string]interface{} {
view := enumerateAccess(r.Context(), DeciderFromContext(r), cfg, PrincipalFromContext(r), "") view := enumerateAccess(r.Context(), DeciderFromContext(r), cfg, PrincipalFromContext(r), "")
// Clicking a project/subtree row opens its .zddc INFO FORM (title, roles,
// admins, …) in the browse editor — not the project's files. The browse
// ?file=.zddc deep link selects + previews that dir's .zddc, which renders
// as the schema-driven form (real or a virtual placeholder). dir_tool at
// these paths is browse, so the trailing-slash URL loads the shell.
zddcFormURL := func(dirURL string) string {
if !strings.HasSuffix(dirURL, "/") {
dirURL += "/"
}
return dirURL + "?file=.zddc"
}
rows := []map[string]interface{}{} rows := []map[string]interface{}{}
for _, proj := range view.Projects { for _, proj := range view.Projects {
rows = append(rows, map[string]interface{}{ rows = append(rows, map[string]interface{}{
"url": proj.URL, "url": zddcFormURL(proj.URL),
"editable": false, "editable": false,
"data": map[string]interface{}{"name": proj.Name, "title": proj.Title, "kind": "project"}, "data": map[string]interface{}{"name": proj.Name, "title": proj.Title, "kind": "project"},
}) })
} }
for _, sub := range view.AdminSubtrees { for _, sub := range view.AdminSubtrees {
rows = append(rows, map[string]interface{}{ rows = append(rows, map[string]interface{}{
"url": sub.Path, "url": zddcFormURL(sub.Path),
"editable": false, "editable": false,
"data": map[string]interface{}{"name": sub.Path, "title": sub.Title, "kind": "admin"}, "data": map[string]interface{}{"name": sub.Path, "title": sub.Title, "kind": "admin"},
}) })

View file

@ -74,6 +74,20 @@
/* Shape */ /* Shape */
--radius: 4px; --radius: 4px;
/* Spacing scale — referenced by the tables tool (tables/css/table.css).
Were undefined (var() with no fallback → collapsed to 0), which left
table cells unpadded and the table flush to the viewport edges. */
--spacing-sm: 0.4rem;
--spacing-md: 0.8rem;
--spacing-lg: 1.5rem;
/* Token aliases the tables tool references under --color-*/--radius-*
names; map them to the canonical tokens (themed values flow through). */
--color-text-muted: var(--text-muted);
--color-border: var(--border);
--color-bg-elevated: var(--bg-secondary);
--radius-sm: var(--radius);
/* Typography. --font-display covers headings (Source Serif 4 — a refined /* Typography. --font-display covers headings (Source Serif 4 — a refined
transitional serif that reads as "engineering / document / serious" transitional serif that reads as "engineering / document / serious"
without being academic). --font is body UI text (IBM Plex Sans — without being academic). --font is body UI text (IBM Plex Sans —
@ -1182,7 +1196,9 @@ body.is-elevated::after {
/* tables/ — directory-of-YAML table view. Reuses tokens from shared/base.css. */ /* tables/ — directory-of-YAML table view. Reuses tokens from shared/base.css. */
.table-main { .table-main {
padding: var(--spacing-md); /* Vertical breathing room + clear left/right gutters so the table isn't
flush to the viewport edges. */
padding: var(--spacing-md) var(--spacing-lg);
max-width: 100%; max-width: 100%;
} }
@ -1632,7 +1648,7 @@ body.is-elevated::after {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title" id="table-title">ZDDC Table</span> <span class="app-header__title" id="table-title">ZDDC Table</span>
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.27-dev · 2026-06-06 23:22:12 · 0c6396d-dirty</span></span> <span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.27-dev · 2026-06-07 13:11:11 · 1b9fec6-dirty</span></span>
</div> </div>
</div> </div>
<div class="header-right"> <div class="header-right">