Design system port: replace Bootstrap 2 with the LinkedDataHub design system - #371
Open
namedgraph wants to merge 61 commits into
Open
Design system port: replace Bootstrap 2 with the LinkedDataHub design system#371namedgraph wants to merge 61 commits into
namedgraph wants to merge 61 commits into
Conversation
Blocks now carry the classes ui_kits/app/app.css targets, replacing the Bootstrap grid ones: row-fluid block -> block ldh-block main span7 -> main ldh-block-body well -> ldh-block-head 'block' and 'main' stay alongside the new names: 62 and 11 CSR handler patterns anchor on those tokens, so dropping them would unhook drag-drop, inline editing and the block toolbars. The header gains the two flex children app.css expects - a titles group (type list as badge, h2.ttl, description as span.sub instead of a <p>) and an .actions group holding the timestamp and actions. bs2:Left and bs2:Right emitted reserved grid columns for backlinks, related resources and parallax navigation. The design system has no columns; that content belongs to a block-scoped drawer, so they now render inside div.ldh-drawer. They stay unconditional because CSR fills them later. Two CSR call sites had to follow the markup: - view.xsl took the nav placeholders with a child step, which the drawer wrapper broke - faceted search would have lost its facets and parallax its controls, silently, since an empty for-each is not an error. - chart.xsl and query.xsl lift the header out before replacing block content via ./div/div[@Class = 'well'], declared as="element()", so the rename would have been a runtime type error rather than a silent miss. Still to port: bs2:Left/bs2:Right internals to the drawer's own structure, the drawer's open/close behaviour, bs2:Actions buttons to .tb, the YouTube header's inner markup, and dropping app.css itself in - without which this renders unstyled. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
colors_and_type.css (tokens), app.css (components), retro.css (m3 skin) copied from the design system export; fonts.css @font-faces the vendored woff2s - Geist, Geist Mono, Instrument Serif (latin subsets) and the Material Symbols Rounded variable icon font - so no external font requests. The root element takes data-retro="m3" data-theme="light", which the skin keys on. Linked after the Bootstrap stylesheets so the design system wins where both target the same elements; the Bootstrap links come out at the end of the port. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bs2:NavBar becomes the ldh-header grid (wordmark | address | actions), replacing the Bootstrap fixed-top collapse structure; NavBarLeft/Main/ Right and their span columns go. The brand takes the wordmark shape, the address bar the ldh-address skin (same form, 'navbar-form' token and input#uri kept for the CSR submit handler), and the right side becomes ldh-icon-btn buttons with Material Symbols glyphs - apps grid, settings gear, notification bell (admin) - plus an initials ldh-avatar for the agent. btn-group/dropdown-toggle tokens stay: the CSR handler toggles .open on them. ldh:LeftSidebar takes the ldh-sidebar skin: sb-search field, sb-section/ sb-heading groups, sb-tree rows with Material carets. The flyout mechanics are untouched - hidden by default, edge-hover shows, mouseout hides - and document-tree/class-list/btn-expand-tree/btn-geo/btn-latest anchors stay for the CSR handlers. ldh-bridge.css is the deliberate shim between CSR state tokens and the design system: dropdown .open menus, ul.nav strips, the tab bar, tree rows and the expand/collapse carets, styled with the system's tokens. Rules leave this file as components finish porting. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The generic bs2:Row got the drawer in the shell port, but two more block templates - the ldh:XHTML content block and the edit-form row - still applied bs2:Left/bs2:Right in-flow, so their backlinks headings rendered inside the block body. The drawer markup is extracted into the ldh:BlockLinksDrawer named template (dh title + close, db holding bs2:Left/bs2:Right) and all three block shapes call it; bs2:Left/Right defaults become drawer groups (left-nav/right-nav dgroup) and the backlinks well becomes a dgroup with its nav-header kept for the CSR load-on-click handler. The header actions gain the tb-links trigger for @Rdf:about resources; CSR handlers in block.xsl open the drawer (display flex) and close it from its dh button. bs2:Actions loses the Bootstrap button faces: btn-copy-uri and btn-edit become .tb toolbar icons (content_copy, edit) with their handler tokens kept. Verified in the browser: 14 drawers on the dev root document, all hidden; clicking tb-links opens the block's drawer with hydrated facet/backlinks content, its close button hides it again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bs2:ActionBar becomes the zoned ldh-actionbar grid (add | breadcrumb+ timestamp | actions), dropping its container/row/span wrappers. The Create/Add cluster sits in ldh-add-wrap, breadcrumbs take the classic ldh-bc skin on the same CSR-built ul, and doc-controls becomes the quiet mono ldh-ab-ts stamp (History link unchanged). The right-side document actions lose their sprite-logo faces: delete, save-as, access and edit are .tb icon buttons with Material glyphs and their identity tokens (btn-delete, btn-save-as, btn-acl btn-access-form, btn-edit) plus disabled state written explicitly. Export and the layout mode switcher stay dropdowns but with .tb trigger faces; mode glyphs come from the new $ldh:mode-icons map shared by the switcher button and the bs2:ModeListItem entries. bs2:TypeList becomes the badge strip (ldh-typelist), facet headers move from nav-header btn to the drawer's dh2 look, and the bridge styles the read-mode dl/dt/dd as design-system property rows and ul.pager - whose exact-class markup the CSR paging handlers match on - as prev/next buttons. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Modals: the CSR appends div.modal.fade.in and removes it on close, so the bridge styles those tokens as the ldh-modal card - centered fixed panel, radius/shadow, mhead-style header with close, scrolling body, footer bar shared with .form-actions. No modal.xsl template changes. Forms: control-group/control-label/controls stay (they are CSR anchors for constraint violations and constructor rows) and become a two-column property grid with explicit cell placement - RDF/POST hidden inputs and <hr> separators are also direct children of .control-group and were silently taking the first grid cell, pushing every label off its row. Inputs, textareas and selects get the field skin with the focus ring; type hints (.help-inline) read quiet and turn danger only inside .error groups; submit buttons take the accent skin. Verified in the browser: the document edit modal renders the two-column statement layout with working focus states and footer actions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
static/css/bootstrap.css and bootstrap-responsive.css are no longer linked. ldh-bridge.css replaces the primitives LDH still emits - .btn faces, carets, badges, alerts, progress bars, tables, typeahead menus - at :where() zero specificity so design-system component classes always win. The two remaining bootstrap.css links are app-specific rule files (Web-Client's and LDH's own) that keep the historical name only. Bootstrap-only vocabulary dies per the census of what the CSR actually anchors on: - purged outright (no anchors): span2-span10, offset*, well/well-small, sidebar-nav, nav-list, input-*, form-search, input-append, btn-small, btn-large, inline, table-striped/bordered, progress-striped, pull-* trimmed where flex replaced floats - renamed on both sides, emission and contains-token anchors together: span12 -> row-main, row-fluid -> block-row, form-horizontal -> ldh-prop-form, alert alert-error -> ldhc-alert va-danger, container-fluid folded into content-body - kept, still meaningful as CSR anchors: block, main, control-group/ control-label/controls, progress/bar/active, dropdown/btn-group/open, modal family, navbar/navbar-form, breadcrumb, pager/previous/next, tab-pane/tab-content, nav-header, search-form/search-query - btn-danger remove buttons become ldhc-btn in-negative, keeping their remove-action/link-remove handler tokens The footer takes the design system's cols/ftitle shape, and the content body gets its stacking rhythm and max-width from the bridge now that Bootstrap's row margins are gone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A dt followed by several dds dropped the extra dds into the term column under grid auto-placement; dt/dd now take explicit columns. .btn-primary picks up a link-colored text rule somewhere upstream, which vanishes on the accent fill - one real-specificity color rule pins it to --fg-on-accent. Content column takes a 1280px measure and the block cards get their stacking margins back (Bootstrap's row margins are gone). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, WYMEditor static/css/bootstrap.css and bootstrap.min.css (the 2.3.2 framework files) are deleted - nothing links them since the framework drop. The script chain loses static/js/bootstrap.js and jquery.min.js: dropdowns, modals and tabs have been IXSL-driven for years, and the only jQuery left in LDH code was the RDF/POST subject-type/value glue. js/jquery.js becomes js/functions.js with the IXSL contract intact - fetchDispatchXML, onSubjectTypeChange, onSubjectValueChange and ixslTemplateListener keep their names and behaviour (the two subject handlers rewritten from jQuery to plain DOM). The Bootstrap-layout pieces of its ready block die with the markup they served (btn-navbar collapse, $().dropdown fallback); outside-click dropdown close and the typeahead autocomplete-off live on as vanilla listeners. The WYMEditor bundle (2.2MB, jQuery-based) goes too - replaced by the RDFa editor in 5.7.0, nothing references it. Verified in the browser: no jQuery-undefined errors, Export dropdown opens via IXSL and closes on outside click, the edit modal renders. The one remaining console 404 is the dev dataset's own broken test object (?uri=https://example.org/aaa), not a regression. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
com/atomgraph/linkeddatahub/css/bootstrap.css never was the framework - it holds LDH's own application rules that accumulated under the historical name. It becomes ldh.css, minus the ten rules whose selector tokens no longer occur in any LDH or Web-Client markup (old breadcrumb logos, action-bar span layout, btn-ban/btn-context, dead sidebar list skins). Web-Client's bootstrap.css stays linked: it styles Web-Client-emitted markup and lives in that repo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two things made the page read as a wall of anonymous white cards rather than the design: - The SaxonJS bs2:Row wrapper carried the ldh-block card skin AND passed it to its next-match inner block, so every CSR-wrapped block rendered card-in-card - visible as sliver borders around alerts and empty- looking bars. The wrapper keeps only the 'block' anchor token now; the inner block is the card. - ldh:XHTML content blocks are prose, and the design renders prose as quiet blocks (no surface, part of the page flow). Their class default becomes 'block ldh-block is-quiet', which app.css already styles. The [Language: en] chip in the reported screenshot does not reproduce in a fresh Chromium or Firefox - it is the stale-SEF browser cache (/static/ is served immutable); a hard reload clears it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The legacy .action-bar rule pins it at --action-bar-top with a 51px fallback - the old Bootstrap navbar height - while the new ldh-header is 56px tall and was not sticky at all, so on scroll the header left the viewport and content showed through a 51px gap above the stuck action bar. The header is now sticky at top 0 and --action-bar-top is defined as the header height, so the two form one pinned chrome stack; #tab-bar's legacy 51px offset follows the same variable. The action bar trades the legacy gray fill for the surface color with a bottom hairline. Verified scrolled 1200px down: header spans 0-56, action bar starts at exactly 56, content scrolls beneath both. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The breadcrumb items were still li > sprite-classed anchor + divider. bs2:BreadCrumbListItem now emits the design's crumb anatomy - a.crumb (is-current on the leaf) holding a Material glyph chosen by document type (folder for Root/Container, description for Item, link otherwise) plus the label, with span.sep between crumbs - inside the same ul both render paths share; the CSR-created ul takes the ldh-breadcrumb classes. The crumb builds its own <a> with the imports/default.xsl href recipe rather than overriding the generic xhtml:Anchor mode, which would have re-defaulted every anchor's href away from ldh:href(). The action-bar port had also silently reversed the document buttons: the old markup floated each one right, so DOM order delete->edit read on screen as edit->delete, and the flex container preserved DOM order instead. The DOM now matches the screen order the floats produced: edit, access, save-as, delete, then export and the mode switcher. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…alert blocks The container block's double bottom border had three contributors, found by DOM forensics rather than guesswork: - CSR hydration re-renders a row as a full ldh-block card inside the SSR wrapper card, stacking two borders 13px apart. One card layer only now: a nested .ldh-block flattens (no border/shadow/radius/surface). - The token rename swept the XSLT but not ldh.css, orphaning its row-fluid/span12/form-horizontal/input-append selectors - drag-handle hiding, block clipping, drag-over and diff borders, the progress-bar sizing that kept the loading skeleton invisible after errors, and the search-field flex. All follow the rename (block/block-row/row-main/ ldh-prop-form); the dead action-bar span rule is deleted. - A block whose content collapsed to a single error alert kept its card chrome, framing the alert with white lips. Such blocks go quiet via :has() - the alert brings its own surface - and alerts lose their stray margins inside blocks. The m3 skin's resting M3-elevation shadow, which reads as a hard line under every card, rests flat per the design's card preview (border instead; hover unchanged), and the bridge table rule no longer draws a separator under the last row. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The bar's controls were still Bootstrap skeletons (btn-group + ul.dropdown-menu) under bridge CSS. They now emit the design system's own structures, as divs per house style: - Create: ldh-add-wrap > ldh-btn (add glyph + label + caret) + ldh-add-menu with .it entries; bs2:ConstructorListItem renders the design item shape (ico/body/lbl, folder for Container, description for Item) while keeping the add-constructor/data-for-class/ data-create-graph contract. Both end-user and admin variants. - Add: ldh-of-wrap > ghost ldh-btn + ldh-of-menu, generate-containers / import-ontology tokens kept. - Document actions collapse into the design's single Actions menu (bolt + label + caret): Edit / Access / Save as, a divider, the three RDF export links (target=_blank keeps them outside CSR interception), a divider, and a danger-styled Delete - handler tokens and disabled states preserved. bs2:MediaTypeList dies with its dead export-rdf interception exemption; its links live in the menu now. - Mode switcher: ldh-mode > label-row trigger (glyph + active-mode label + caret) + modes-pop with .mi entries as anchors, mode-class and active tokens kept alongside is-active. - Breadcrumbs switch to the pills variant: bc-pill chips with chevron separators in a div container on both render paths. - The timestamp gains the schedule glyph; the address bar shows the document URI on SSR and always mirrors it on navigation (previously blanked for local documents - the design's Header shows the URL). All design menus open through the existing CSR btn-group 'open' toggle; the bridge maps that state onto ldh-add-menu/ldh-of-menu/modes-pop visibility and exempts the address field from the form-field skin. Verified in the browser before the stack was stopped externally: Create pill, Actions menu with dividers and danger Delete, pill breadcrumb, labeled Content switcher all render and open; the address-bar change compiles but its browser check is pending the stack's return. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The XHTML/Object create-block buttons were the last old-school controls: Bootstrap primary pills with sprite faces. They are ghost ldh-btns now, with Material glyphs (notes / data_object) and their create-action / add-constructor / data-for-class contract intact. The sprite system itself goes: all 73 background-image rules pointing at the icons/ directory are deleted from ldh.css and the directory itself is removed - every ported control renders Material Symbols instead. The ldh:logo templates stay purely as class-token carriers for the CSR handlers that anchor on them; with the sprite CSS gone they paint nothing. The one non-CSS consumer, the signup-complete <img>, becomes a check_circle glyph. Verified in the browser: the create-block buttons render as quiet design pills, and the address bar now shows the document URI (the CSR change from the previous commit, unverifiable then while the stack was down). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The bridge's Bootstrap-replacement .caret was a 0x0 border triangle, which collided with the ported markup's <span class="msi caret"> expand_more</span>: the triangle painted inside the button while the glyph text overflowed the zero-size box as a stray chevron below it. .caret is now a Material glyph in both generations - ported spans render their own expand_more, and legacy empty <span class="caret"/> spans (login dropdown, sort toggle, the drawer's backlinks heading) get the same glyph via ::before, with caret-reversed flipping to expand_less. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…les only Of the empty <span class="caret"/> leftovers, five were static dropdown carets - they now ship the expand_more glyph directly, like the rest of the ported markup. The two caret-reversed collapse indicators stay empty by design: the CSR handlers flip the caret-reversed class on them, and only ::before content can follow a class change on a ligature-font glyph. The bridge comment records that distinction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The sticky action bar (z-index 999 from the legacy rules) painted over modal dialogs, hiding their header - the bridge had given modals z-index 110. Modals sit at 1050 now, above the whole chrome stack, with a non-interactive dim behind them via body:has(); typeahead suggestion menus move above the modal plane so in-form typeaheads keep working. Design menus (Create/Actions/modes) also stayed open after picking an item. The outside-click closer now also closes on menu-item picks, deferred a tick so it settles after the IXSL btn-group toggle that handles the same click - otherwise the two could race and re-open the menu. Verified in the browser: Create > Container opens the modal above the chrome with the page dimmed behind it, and the Create menu is closed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The m3 skin paints every .ldh-header descendant with the inverse near- white text color for the dark bar - correct for the bar itself, but the light dropdown panels inside it (Applications, Settings, agent) rendered white-on-white and read as empty. Panel content takes the regular ink back at higher specificity, section headers keep the hint color, and the avatar's initials stay dark in its hover/open state where the fill goes light. Settings had no pull-right token, so its menu left-aligned and clipped off the viewport; header menus now hug the right edge regardless. Menu picks also close these header menus via the same deferred closer as the action-bar menus. Verified in the browser: all three menus open readable and right- aligned - System apps list, Application/Administration/Namespace ontology, and the agent entry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Census: zero CSR anchors on pull-*, and floats are inert inside flex containers and on absolutely positioned elements - so every pull token whose parent already became flex chrome (header action strips, block head actions, alerts, dropdown toggles) or that rode an absolute menu was doing nothing. Those 14 are gone; the Actions wrapper layout keys on its position in .actions instead of the token. What stays, deliberately: pull-right on ul.dropdown-menu as the alignment signal for the not-yet-ported menus, and the still-active floats in interior form markup (btn-remove-property/btn-add rows, typeahead metadata, the hover-overlay edit buttons) - those go when their components get ported, and the bridge documents exactly that. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The legacy modal markup puts button.close FIRST and titles the dialog with a <legend>; the bridge's flex header laid children out in DOM order - close at the left, the title squeezed into a wrapping column, the description eating the rest. The header is a two-column grid now: the title column (legend/h2/h3 styled as the design's mhead title, any <p> as a muted subtitle under it) and the close button pinned top-right, regardless of source order. Verified on the Request access modal: title left, description under it, close at the right - matching the design's mhead anatomy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both bs2:Chart forms (the RDF and SPARQL-results variants, which the CSR re-render also compiles in) swap their fieldset block-row for the design system's chart-controls three-column grid with .field cells - mono uppercase overline labels, full-width selects, the series multi-select as a listbox. Select classes/ids (chart-type / chart-category / chart-series, name=ou|ol) are untouched, so the onchange handlers and the RDF/POST encoding are unaffected. Fieldsets and legends lose their Bootstrap-era box look globally: borderless sections with overline legends, which also fixes the old-school group boxes in the access modal. Multi-selects inside the controls grid keep their natural height. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Full-DOM audit (Playwright crawl of every menu, modal, form and mode against the design-system contracts) surfaced the components that lost their faces when the sprite CSS died, plus one real regression risk: - The constructor modal had an empty <legend> - it is titled with the class label now (ac:object-label in xsl:try; the bare call throws and killed the whole modal render, which the first fix attempt proved the hard way. The catch falls back to the URI local name.) - Remove-statement and remove-resource buttons were empty invisible boxes in every editing form: .tb buttons with the close glyph now, in all three emitters (constructor.xsl - with the xsl:attribute reordered before the glyph span, imports/default.xsl, resource.xsl), handler tokens kept - The search modal's submit button was invisible: search glyph - Add-statement button swaps the HTML entity cross for the add glyph - Graph HUD buttons gain fit_screen / fullscreen glyphs per OtherModes - Dead tokens purged: wymupdate, dl-horizontal, the sprite-era class injection on block-title anchors Verified in the browser: Create > Container opens titled with glyphed remove buttons (4/4); the per-block edit button opens the inline editing form with glyphed controls and footer actions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A faceless-button DOM sweep (every button with no text, glyph or image, across edit mode, the create modal and the inline block edit form) caught the emitters whose only face was a sprite class injected via the ldh:logo mode: the subject-edit toggle in form legends (edit glyph), the add-value button on property controls (add glyph) and the rdf:type control group's remove button in imports/rdf.xsl, which now matches the canonical tb btn-remove-property + close-glyph shape. Dead sprite background-position rules and the border-triangle caret-reversed rule (the double-arrow bug's last holdout) leave ldh.css. Re-swept after deploying: no faceless buttons remain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…glish go with it The facets answer to 'where did the filters go': out of the links drawer, into a ldh-view-toolbar at the top of every view block, per the ViewBlocks contract. Left zone: filter_alt lead + one dropdown pill per facetable property - the pill is the old nav-header (button-shaped, same hidden subject/predicate/object inputs), so the lazy value-load onclick and the checkbox filter onchange run unchanged; the hydrated ul.nav now doubles as the facet-pop popover card. Right zone: the inline-create button, Total results, the order-by select + direction button, and the mode dropdown (with a visible active-mode glyph from ldh:mode-icons). The drawer group the facets vacated hides when empty; parallax stays in the drawer. Verified in the browser: pill opens, values load with counts, checking a value filters the results. The last pull-left/pull-right tokens are purged along the way - header menus right-align via a header-scoped rule, the form legend is restructured (label first, subject controls in a right-hugging .actions cluster, remove button last), remove/add groups trail their form rows via flex order, the language badge follows its value, and the typeahead metadata span is .meta. The bridge float shims are deleted. Branch-introduced English strings move to translations.rdf (add-stmt, remove-resource, remove-link, get-started, learn-more, footer titles and links, export format names); the facet lead reuses filter-title. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The three serialization links (RDF/XML, Turtle, JSON-LD) move out of the Actions menu into a new bs2:ExportList mode that bs2:ActionBarRight renders after the mode switcher: an icon-only ghost button (download glyph, titled from the existing export translation entry) opening the same target=_blank links. Same signed-in guard and HTTP-error suppression as before, same ldh-of-wrap anatomy, so the open-toggle and close-on-pick wiring covers it unchanged. The Actions menu keeps edit / access / save-as / delete, minus the now-stray second divider. Verified in the browser: the button renders right of Content, its menu lists the three formats with the correct accept hrefs, and the Actions menu no longer carries them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The edge-hover flyout stopped appearing: the port stamped the sidebar with the design's ldh-sidebar class, whose resting state is translateX(-100%) waiting for an is-open toggle - but the CSR handlers carry show/hide as inline display (mouse at x=0 sets block, mouseout sets none). The handler fired, display flipped, and the panel stayed 288px off-screen. The bridge now neutralizes the slide transform so display alone controls visibility, and starts the panel below the sticky header instead of the design's full-height top:0. Verified in the browser: mouse at the left edge slides out the panel (search, document tree, class pills, other views) at x:0 under the header; mousing out hides it again. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ith it Every form footer (modal and inline) now follows the design's footer anatomy: secondaries (Cancel/Reset/Close) are ghost ldh-btns, the primary (Save/Compare/Allow/Annotate) is a filled ldh-btn with a glyph, and it sits last so the ghost buttons lead into it. Handler tokens (btn-save, btn-cancel, btn-reset, btn-close, btn-save-chart, spo-action, cancel-action) ride along unchanged, as do the two $button-class param defaults that feed the ldh:logo class injection. The Bootstrap-era form-actions class itself is gone: the design system has no such band (its ldh-form-actions-* names mean the per-form actions dropdown), so the footers take the design's ldh-block-foot token - all emitters, the one CSR matcher that anchored on it, and the bridge rules renamed together. modal-footer stays as the sticky-scroll token, its hardcoded white swapped for the surface token. Also fixed en route: a stray quote in ldh:Form's save button class, and the access form's hardcoded Allow label now comes from a new translations entry. Verified in the browser: the create modal footer renders ghost Reset + filled glyphed Save on the ldh-block-foot band. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…column The rdf:RDF form shell gains a show-close-button param (default false, so the SSR EditMode page keeps its plain footer) emitting a ghost Close button ahead of Reset; the generic modal.xsl close handler already matches any button.btn-close inside a modal, so no new wiring. All six modal flows through the shell opt in: document create, document edit, add-instance, app settings, and both constraint-violation re-render paths. The three modal footers that already had a Close (import ontology, generate containers, request access) join the new convention: ghost Close and Reset leading into the ldh-btn primary. Also swept up: form-actions-class param values that still said 'form-actions' (the class-literal rename missed them), and modal.xsl's button-class defaults move off btn btn-primary. Modals now span the content column - width matches .content-body's inner width (max 1280px minus side padding) instead of the 880px cap. Verified in the browser: create modal footer reads Close / Reset / Save, inline form reads Cancel / Reset / Save, and the modal box is pixel-identical in x and width to the content blocks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rimaries Content mode's XHTML/Object buttons and the row modes' Create picker used to sit at the end of the document flow - on long documents the main authoring affordance was a scroll away, and the content-mode pair was ghost-styled while every other creation button was filled. Both rows now render into a fixed ldh-create-dock at the bottom right, all buttons unified as filled ldh-btn primaries with the add glyph, matching the action bar's Create anatomy. The dock's right edge is anchored to the drawer-width token (360px + gutter), so it can never collide with the right-edge drawer slide-in - and that boundary is where the action bar's timestamp control ends, so they read as aligned (within 9px at 1440; exact element-tracking is not expressible from position:fixed). The class-picker menu opens upward from the dock, the dock hides while a modal is open (the dim overlay is pointer-inert), and elevation comes from the shadow token. Legacy create-action height caps and the create-resource margin rule leave ldh.css. Verified in the browser: content mode shows + XHTML / + Object floating bottom-right; switching to Read mode re-renders the dock with the + Create picker in the same position. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The form-row remove/add buttons (tb btn-remove-property, tb btn-add, tb btn-remove-resource) rendered as browser-default bordered boxes: app.css styles .tb only inside .ldh-toolbar, .ldh-of-wrap and .ldh-block-head .actions, and the form rows sit outside all three scopes. The bridge now carries a zero-specificity :where(button.tb) base - 28px quiet icon button, neutral hover, danger hover on the remove tokens - so every scoped design recipe still wins unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… viewport The dock switches from fixed to sticky: it still rides the viewport bottom while content scrolls, but it lives in flow at the end of the content, so reaching the end parks it above the footer instead of floating over (or below) it. The right-edge clearance of the drawer strip carries over as an auto/max margin pair, since sticky offsets resolve against the content column rather than the viewport. The page column is a flex stack now (#visible-body min-height 100vh, #tab-body absorbs the slack), which pins the footer to the viewport bottom on short pages. The legacy sizing that made empty pages look broken is gone from ldh.css: the forced body height that painted the page gradient below the footer, the stale fixed-navbar padding pair, and content-body's min-height heuristic that the flex chain replaces. Verified in the browser: on a long page the dock floats bottom-right and parks 64px above the footer at full scroll; on a short page the footer ends the document exactly (no painted void) with the dock in flow above it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Four-angle review (reuse, simplification, efficiency, altitude) of the design-system port, applied: The big catch is a real repair: bs2:ModeListItem emits bare a.mi items, but every view-level handler still matched ul.view-mode-list/li[.active] - dead XPaths, so view mode switching and the reads feeding sort, facet filtering and parallax were silently broken. The view mode menu now uses the document-level anatomy (ldh-mode wrap, modes-pop), all matchers and active-mode reads key on a.mi.is-active (mode class extracted via map:keys($class-modes)), activation toggles follow, and the redundant legacy 'active' token is gone. Verified in the browser: mode switch re-renders, facet checkbox filters. Dedup and dead code: the unreachable bs2:Constructor template (~80 lines) and its orphaned with-label param are deleted; the Root/Container /Item glyph choice lives once in an ldh:class-icons map; the Link-header target parse is one ldh:link-targets function instead of six inline copies; the RDF export menu is one for-each over accept/label pairs under the pre-existing bs2:MediaTypeList mode name instead of a parallel bs2:ExportList; the admin AddData override passes its menu item through xsl:next-match instead of re-emitting the whole dropdown; the avatar initials item is a shared template; ldh:BlockLinksDrawer is a match template per the project idiom; double icon plumbing (sprite-era ldh:logo class injection under msi glyphs) is gone from the footer buttons; the dead va-danger token becomes alert-error; login buttons drop the stacked legacy btn vocabulary. State classes: the dropdown toggle stamps open + is-open together, so app.css's native open-state rules apply and the outside-click closer clears both (with an early exit when nothing is open). CSS: the legacy Bootstrap tab skin that out-specified the bridge's design-token tabs is gone from ldh.css along with dead rules (collapsing-top-navbar, sprite btn-logo, doc-controls btn-edit) and the 51px-era fallbacks; the bridge gains shared tokens (--ldh-content-w, --ldh-drawer-w in one :root), uses --r-pill / --shadow-lg / --shadow-xl / --border-default instead of nonexistent-token fallbacks and literal shadows, deduplicates .btn-group positioning, and the action bar's left zone gets its own ab-left class instead of overloading ldh-add-wrap. Efficiency: diff-key serialization short-circuits on non-diff renders (ldh:diff-class / ldh:value-diff-class guard on empty key sets); the duplicate triples-map builds in the diff view are hoisted. Deferred with notes: icon-font subsetting (5.4MB woff2), :has()-based quiet-block detection vs stamping is-quiet at the failure emitters, shared modal header/footer shell, map-based diff-key membership, constructor-sync request grouping, package catalog caching, typelist as ldhc-tag, caret convention unification. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
.content-body centers with auto side margins, which opt a flex item out of cross-axis stretch - once .document-body became a flex column for create-bar parking, the column shrink-wrapped to its widest child and every block in Properties mode narrowed with it. An explicit width puts the auto margins back to centering the max-width cap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KwvP2BwVb5rmXc7hWxqF4a
The bar's right padding was the floating cluster's drawer-strip clearance, pushing the Create button 360px in from the edge. A full-width row needs no clearance - the drawer overlays it when open - so the padding is now gutter + column inset, putting the button flush with the blocks' right edge. That orphaned the --ldh-drawer-w token, whose only consumer this padding was. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KwvP2BwVb5rmXc7hWxqF4a
…imitives LDH still emits Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnsTqafyvZJUN7CmDse2mn
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnsTqafyvZJUN7CmDse2mn
…the footer Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnsTqafyvZJUN7CmDse2mn
… expects Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnsTqafyvZJUN7CmDse2mn
…thout editable content Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnsTqafyvZJUN7CmDse2mn
…-aligns with the content column Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…g a second box inside the pill Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…tle with description, date, type badge A document paired with its foaf:primaryTopic renders as one row carrying the topic's label, description and type. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
… Table chart is skinned in CSS instead Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…lass Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…line row forms' transplant and constructor chain The modal body hosts a div.block.ldh-block that ldh:replace-block-element (the DOM-update tail shared with ldh:render-row-form) transplants the rendered form onto, so the generic handlers - add-value property picker, constructor sync, type typeahead - anchor on 'block' instead of 'block-row' and work in both placements. The edit flow fetches constructed-doc/constructors/shapes in parallel and folds shapes + constructed-doc via ldh:build-merged-constructor, so SHACL-defined properties resolve the same as SPIN-defined ones; the violation re-render rides the same load-pairs. The fieldset legend doubles as the modal form's heading. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…er; the 3D graph sizes to its canvas height Graphs nested inside view blocks keep their fixed height - the canvas is a direct .content-body child only at document level. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…tops drifting The bar heights size the bars rather than mirror their content, letting stacked sticky offsets (.editor-bar) compose them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…pills and headings with the rows below Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…e the design's property groups Offset box-shadow copies of the dt/dd cells fill the column gap and the card padding; a hovered dd lights its (deduped) dt via :has(), up to four values per property. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…ce the flattened modes-pop markup no longer carries it on the parent Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…results region instead of the block wrappers, and a card with an open menu wins the paint order Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…escription in an auto-fill grid aligned to the toolbar Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…ute inset is reserved for the fullbleed wrapper Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…cepting default-mode dispatches and view Properties mode renders again Same class of bug as be7c4eb (normalize-rdfxml): an unnamed-mode match="/" entry point in a late import outranks every root/document template below it, so the otherwise branch of ldh:ViewModeChoice fed its results document to the RDFa extractor, which found no RDFa in RDF/XML and emitted an empty rdf:RDF element. Both call sites pass $doc explicitly, and the RDFa-Editor's own CLAUDE.md already documents the named-entry-only contract. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
… the extractor entry becomes rdfax:extract-rdfa, the canonicalization passes cm:canonical, cm:normalize and cm:demote, and the standalone entry rdfae:main Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…ar while an XHTML block is being edited Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
…, joining graph mode in the fullbleed treatment Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Tgf5DjbYiX3SPnCFSgCzd
Closed
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.
Ports the core end-user UI from Bootstrap 2.3.2 to the LinkedDataHub design system (vendored export), replacing markup — not skinning — while keeping every CSR interaction contract intact. Verified throughout against the running instance with Playwright (owner WebID client cert), screenshot-by-screenshot.
What's ported (design markup,
div-based, no HTML5 semantic elements)ldh-header(wordmark, address bar showing the document URI, Material-glyph icon buttons, initials avatar),ldh-sidebarwithsb-*tree/classes/other sections; flyout mechanics unchangedldh-actionbar—ldh-btnCreate withldh-add-menu(design.itconstructor entries), ghost Add, pills breadcrumb (bc-pillchips + chevron separators),schedule-glyph timestamp, single design Actions menu (Edit / Access / Save as · export links · danger Delete), labeledldh-modeswitcher withmodes-popldh-blockcards withldh-block-head(badge/title/toolbar.tbactions incl. the drawer trigger); backlinks/related/parallax live in a per-blockldh-drawer; XHTML prose renders quiet (is-quiet); exactly one card layer (nested cards flatten)control-groupcontract, field skins with focus rings, modal card above the sticky chrome with a dim backdropcolors_and_type.css,app.css,core.css, m3 skin; Geist / Geist Mono / Instrument Serif / Material Symbols vendored as local woff2 — no external requestsWhat's gone
bootstrap.js+ jQuery unlinked (LDH glue rewritten vanilla infunctions.js, IXSL contract intact); WYMEditor bundle removedldh:logosprite system: all 73 icon rules and theicons/directory — Material Symbols everywherewell,span*,input-*,pull-*where inert,table-striped, …), anchored tokens renamed on both sides (span12→row-main,row-fluid→block-row,form-horizontal→ldh-prop-form); LDH's owncss/bootstrap.cssrenamed toldh.cssand prunedDeliberately kept
block,control-group,dropdown-toggle/open,progress/bar,pager/previous/next, …) — styled byldh-bridge.css, the documented transitional shim between CSR state classes and the design systembs2:mode names and thexsl/bootstrap/2.3.2/path — mechanical rename deferredKnown gaps (follow-ups)
ldh-view-toolbarFacetDropdowns; container sort/view controls not yetview-mode-segmhead/mlistmarkup.ldh-header *color blast needs the inheritance fix + self-colored panels in the design project🤖 Generated with Claude Code