Land the dataops-family redesign on main - #31
Merged
Merged
Conversation
Vendor the dakit bundle (tokens + base + components, self-hosted fonts) into static/dakit/ via scripts/sync_dakit.sh, which records the dakit commit in static/dakit/PROVENANCE; relay has no Node build, so the generated CSS is checked in like any other vendored dependency. Load dakit before app.css in base.html, switch the theme boot script and toggle to the shared dakit-theme storage key (migrating the old datamailer.theme value once), and cover the wiring in the operator UI test.
Replace the raw --dm-* color/type/space definitions with a compat shim aliasing dakit's semantic tokens (dakit docs/adoption.md alias strategy), so both themes resolve through dakit's contrast-verified palette — the dark remap replaces relay's private dark values, which is the point of the shared system. dakit gained the danger.hover role for relay's solid danger buttons, so the last raw color goes too. app.css keeps no token source of its own: base.html already links the vendored bundle (static/dakit/dakit.css) first, so drop the duplicate tokens copy, the local @font-face rules, and static/mailing/fonts — the bundle serves the same self-hosted files from static/dakit/fonts. Also drop the unused --border/--ink/--surface legacy aliases.
Mechanical rename of every call site through the shim mapping and delete the shim — app.css now defines no tokens of its own. Radius follow dakit canon: inputs, nav items and inset surfaces take the 4px step, buttons and panels the 6px step. docs/design-system.md now describes the dakit foundation, the vendored bundle, and the --dk-* roles.
The bundle's @font-face rules use ../fonts/ relative URLs, so dakit.css must sit one level above the fonts directory — mirror dakit's dist/ + fonts/ layout in static/dakit/ instead of flattening it. Fonts now load instead of falling back to system faces.
Dakit's base layer now draws its own chevron on every non-multiple select, 12px off the edge instead of the native arrow hugging it (circled in the Active client screenshot). The synced bundle carries it; the client-switcher's padding keeps its label clear of the glyph. Note: this commit also carries the operator-UX additions another session appended to app.css (skip link, sidebar current-client, local nav) — staged together by accident; content is theirs, left intact here rather than rewritten under a concurrent writer.
…eme) Carries the shared dropdown chevron and the theme-pinned color-scheme from dakit's base layer; PROVENANCE records the source commit.
Making .secondary-section a card kept the section-header's and the heading's own page-flow margin-tops, which stacked on the card's padding-top into an empty band that read as a phantom bordered box above Recent History / Recent Events.
The sidebar moves onto the page background with the product mark, an icon-plus-text nav (16x16 stroke icons, the dakit icon language), and the active-client select directly under the mark. Global links become a slim toolbar over the canvas only, right-aligned like dataops. Phones get a 64px top bar whose menu opens the nav as a drawer with a scrim, Escape, and focus handling; collapsing still leaves a visible restore control (icon rail).
Demote repeated and per-row actions to the quiet secondary (Use client, filters, contact toolbar updates, API docs links, test-email apply), keep the filled accent for the one primary action per view, alias it as .button.primary, and restate destructive actions as dakit's outlined danger instead of a filled red button. Button weight follows dakit's medium.
Stats render as one segmented strip (hairline-divided cells in a single bordered container) instead of loose cards, everywhere stats-grid is used. Tables take dakit's uppercase quiet headers, badges take the dk-badge geometry (small radius, 11px), timelines become divided rows in one container, empty states are plain copy instead of boxes, and focus rings unify on dakit's 2px focus-ring. The dashboard attention queue becomes a banded panel like dataops' 'Needs your attention'.
The badge-tone change carried two forms (test send, cancel) whose views live only in the uncommitted campaign-UI work, so every campaign detail render crashed on reverse(). Drop the forms here until that work lands, and re-point the detail and base-template assertions at the copy and shell this branch actually ships.
The 1px-gap trick painted the container's border color across empty grid tracks once eight worker cells wrapped. Give each cell its own right/bottom hairline pulled 1px past its track instead; overflow hidden clips the outer edges.
At 390px the toolbar clipped the theme toggle and wrapped the API Docs label; global controls go icon-only at phone widths. The clients table becomes labelled rows (the family spec's mobile table conversion) and every narrow table-wrap gains a right-edge fade hinting sideways scroll.
The sidebar plane moves to --dk-bg-muted, nav rows take the family's 36px/10px geometry, the drawer scrim uses --dk-bg-backdrop instead of a raw overlay color, and controls settle on --dk-radius-md with the dataops focus ring. A toolbar account chip (avatar + sign-out) completes the family toolbar, and an sr-only utility backs the visually-hidden table headers.
Every stacked form now exits through one footer row above a top border with the primary action first and Cancel after it, per the family spec. The receiving-address form moves its submit out of the field grid into that footer, and its count strip uses the shared stat cells instead of margined sections inside the bordered container.
Campaigns, audiences, and clients carry data-labels and join the stack-table pattern, so phone widths read one labelled row per record instead of a clipped grid. The campaign table drops its fixed layout so the six-column comparison fits the 1440 canvas without cutting off the delivery column.
…et secondary recipe)
Lands origin/redesign/dataops-family (5912faf) on top of main (cdf3a9a). Conflict: templates/base.html — main's admin-nav change (cdf3a9a) met the redesign's full shell restructure. Resolution: the redesign's shell wins (toolbar + account menu + icon sidebar with dakit bundle); main's functional change is re-applied inside the new shell — the sidebar Administer 'Admin' entry now links to {% url 'mailing:admin_api_keys' %} with aria-current on admin_api_keys instead of the old /admin/ Django admin link. Django admin remains reachable via the link on the Admin API Keys page (added by cdf3a9a). Tests: uv run pytest — 754 passed; ruff clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lands the dataops-family redesign onto current main by merging
origin/redesign/dataops-family(tip5912faf) intoorigin/main(tipcdf3a9a).What it does
bc5768e), and the admin-nav link to admin API key management (cdf3a9a).Conflict resolution (templates/base.html)
The only conflict. Resolution: the redesign's restructured shell wins (sidebar nav with icon links,
{% with current_url_name=request.resolver_match.url_name %}, "Administer" nav group); main's functional change fromcdf3a9awas re-applied inside the new shell — the Admin link now points to{% url 'mailing:admin_api_keys' %}witharia-current="page"on theadmin_api_keysroute, using the shell'scurrent_url_namevariable.Verification
uv run pytest: 754 passed.uv run ruff check .: all checks passed.