From c99c91c826499f24d2264b632f7ffa011c15f420 Mon Sep 17 00:00:00 2001 From: DCCONSTRUCTIONS Date: Fri, 1 May 2026 22:28:34 +0300 Subject: [PATCH] docs: add nodedc ui guideline registry --- dc-ui-guideline/README.md | 20 +++ .../components/action-dropdown.json | 41 ++++++ .../components/admin-side-nav.json | 45 ++++++ dc-ui-guideline/components/admin-table.json | 43 ++++++ dc-ui-guideline/components/app-header.json | 40 ++++++ .../components/calendar-popover.json | 47 +++++++ .../components/circle-action-button.json | 53 ++++++++ .../components/dropdown-surface.json | 48 +++++++ dc-ui-guideline/components/entity-modal.json | 47 +++++++ dc-ui-guideline/components/glass-panel.json | 36 +++++ .../components/launcher-showcase-stage.json | 33 +++++ .../components/media-source-field.json | 40 ++++++ dc-ui-guideline/components/profile-menu.json | 41 ++++++ dc-ui-guideline/components/segmented-nav.json | 34 +++++ .../components/service-rail-card.json | 39 ++++++ .../components/status-control.json | 33 +++++ .../components/work-item-card.json | 42 ++++++ dc-ui-guideline/mcp.manifest.json | 33 +++++ .../recipes/admin-catalog.recipe.json | 47 +++++++ .../recipes/launcher-shell.recipe.json | 39 ++++++ .../recipes/task-manager-board.recipe.json | 40 ++++++ dc-ui-guideline/registry.json | 128 ++++++++++++++++++ dc-ui-guideline/rules/ui-rules.json | 51 +++++++ dc-ui-guideline/sources/source-map.json | 86 ++++++++++++ dc-ui-guideline/tokens/nodedc.tokens.css | 24 ++++ dc-ui-guideline/tokens/nodedc.tokens.json | 79 +++++++++++ 26 files changed, 1209 insertions(+) create mode 100644 dc-ui-guideline/README.md create mode 100644 dc-ui-guideline/components/action-dropdown.json create mode 100644 dc-ui-guideline/components/admin-side-nav.json create mode 100644 dc-ui-guideline/components/admin-table.json create mode 100644 dc-ui-guideline/components/app-header.json create mode 100644 dc-ui-guideline/components/calendar-popover.json create mode 100644 dc-ui-guideline/components/circle-action-button.json create mode 100644 dc-ui-guideline/components/dropdown-surface.json create mode 100644 dc-ui-guideline/components/entity-modal.json create mode 100644 dc-ui-guideline/components/glass-panel.json create mode 100644 dc-ui-guideline/components/launcher-showcase-stage.json create mode 100644 dc-ui-guideline/components/media-source-field.json create mode 100644 dc-ui-guideline/components/profile-menu.json create mode 100644 dc-ui-guideline/components/segmented-nav.json create mode 100644 dc-ui-guideline/components/service-rail-card.json create mode 100644 dc-ui-guideline/components/status-control.json create mode 100644 dc-ui-guideline/components/work-item-card.json create mode 100644 dc-ui-guideline/mcp.manifest.json create mode 100644 dc-ui-guideline/recipes/admin-catalog.recipe.json create mode 100644 dc-ui-guideline/recipes/launcher-shell.recipe.json create mode 100644 dc-ui-guideline/recipes/task-manager-board.recipe.json create mode 100644 dc-ui-guideline/registry.json create mode 100644 dc-ui-guideline/rules/ui-rules.json create mode 100644 dc-ui-guideline/sources/source-map.json create mode 100644 dc-ui-guideline/tokens/nodedc.tokens.css create mode 100644 dc-ui-guideline/tokens/nodedc.tokens.json diff --git a/dc-ui-guideline/README.md b/dc-ui-guideline/README.md new file mode 100644 index 0000000..4225428 --- /dev/null +++ b/dc-ui-guideline/README.md @@ -0,0 +1,20 @@ +# NODE.DC UI Guideline + +This folder is the first local source of truth for reusable NODE.DC UI components. + +It is intentionally MCP-friendly: +- `registry.json` lists every known component contract. +- `tokens/nodedc.tokens.json` contains machine-readable design tokens. +- `tokens/nodedc.tokens.css` mirrors runtime CSS variables. +- `components/*.json` describe component anatomy, states, rules, and source references. +- `recipes/*.json` describe larger UI compositions. +- `sources/source-map.json` links this launcher and NODEDC Task Manager implementation files. + +The codebase remains the source of truth for implementation. This folder is the index and contract layer that an MCP server or coding agent can read before generating UI. + +## Operating Rule + +Before creating a new NODE.DC UI element, check `registry.json`. + +If a matching component exists, use or extend it. Do not create a local one-off dropdown, modal, button, status pill, table, calendar, or navigation panel. + diff --git a/dc-ui-guideline/components/action-dropdown.json b/dc-ui-guideline/components/action-dropdown.json new file mode 100644 index 0000000..e056573 --- /dev/null +++ b/dc-ui-guideline/components/action-dropdown.json @@ -0,0 +1,41 @@ +{ + "id": "action-dropdown", + "name": "ActionDropdown", + "kind": "component", + "status": "stable-reference", + "summary": "Shared action menu for ellipsis buttons and command lists. Used instead of local card menus.", + "sourceRefs": [ + { + "project": "nodedc_taskmanager", + "file": "plane-src/packages/ui/src/dropdowns/action-dropdown.tsx", + "exports": ["ActionDropdown"] + }, + { + "project": "nodedc_taskmanager", + "file": "HDROPDOWN-CANON.md", + "section": "Action dropdown" + } + ], + "propsContract": { + "items": "Array of action menu items with key, icon, title, description, disabled, action, nestedMenuItems.", + "button": "Optional custom trigger.", + "buttonAsChild": "Allows using the provided trigger element as anchor.", + "placement": "Popper placement.", + "portalElement": "Defaults to document.body.", + "menuClassName": "Optional width/padding adjustment." + }, + "behaviorContract": [ + "Uses real trigger element.", + "Uses fixed Popper strategy.", + "Uses offset [0, 8].", + "Uses flip and preventOverflow.", + "Uses portal to document.body by default.", + "Stops trigger event propagation so cards do not open when the menu opens." + ], + "rules": [ + "Do not build card ellipsis menus with local isOpen and absolute positioning.", + "Menu item visual rendering lives inside ActionDropdown.", + "Nested items are allowed, but still use the same dropdown shell." + ] +} + diff --git a/dc-ui-guideline/components/admin-side-nav.json b/dc-ui-guideline/components/admin-side-nav.json new file mode 100644 index 0000000..7ddbc4c --- /dev/null +++ b/dc-ui-guideline/components/admin-side-nav.json @@ -0,0 +1,45 @@ +{ + "id": "admin-side-nav", + "name": "AdminSideNav", + "kind": "component", + "status": "draft-stable", + "summary": "Left admin panel navigation with full-width rounded rows, circular icons, client selector, close button, and role footer.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/widgets/admin-overlay/AdminOverlay.tsx", + "classes": ["admin-panel-nav", "admin-panel-client-select", "admin-panel-nav-item", "admin-panel-role"] + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["admin-panel-nav", "admin-panel-nav-item", "admin-panel-nav-item__icon", "admin-panel-close"] + } + ], + "anatomy": [ + "panel shell", + "head: eyebrow, title, close action", + "client selector row", + "nav list", + "role footer" + ], + "geometry": { + "width": "clamp(20.75rem, 19.5vw, 22rem)", + "panelPadding": "1.1rem", + "rowHeight": "controlRing + 2 * controlInset", + "iconSize": "controlRing", + "edgeInset": "5px" + }, + "states": { + "inactive": "muted text, darker icon circle, partial opacity", + "active": "white icon circle and brighter row surface", + "hover": "slightly brighter row surface" + }, + "rules": [ + "Rows stretch to panel edges by counteracting panel padding.", + "Active nav icon is white, not green.", + "Close button is anchored at panel radius with 5px inset.", + "Client selector uses the same row/circle geometry as nav rows." + ] +} + diff --git a/dc-ui-guideline/components/admin-table.json b/dc-ui-guideline/components/admin-table.json new file mode 100644 index 0000000..92416d1 --- /dev/null +++ b/dc-ui-guideline/components/admin-table.json @@ -0,0 +1,43 @@ +{ + "id": "admin-table", + "name": "AdminTable", + "kind": "component", + "status": "draft-stable", + "summary": "Admin data table shell used for services, clients, users, groups, invites, sync, and audit.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/widgets/admin-overlay/AdminOverlay.tsx", + "functions": ["ServicesSection", "ClientsSection", "UsersSection", "GroupsSection", "InvitesSection", "SyncSection", "AuditSection"] + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["table-shell", "admin-data-table", "services-admin-table", "admin-table-input"] + } + ], + "anatomy": [ + "table-shell glass surface", + "table-toolbar", + "thead labels", + "tbody rows", + "inline editable cells", + "StatusControl cells", + "DateField cells", + "CircleActionButton action cells" + ], + "visualContract": { + "background": "same family as inactive admin nav row, not a foreign panel", + "fontSize": "0.82rem table; compact labels 0.66rem", + "cellVerticalAlign": "middle", + "rowAction": "circular edit button at right" + }, + "rules": [ + "Create action is a solid circular plus, not a wide text CTA.", + "Inline editable cells use transparent input surfaces that brighten on hover/focus.", + "Status cells use StatusControl.", + "Date cells use CalendarPopover/DateField.", + "Drag handles move full rows, not detached ghosts." + ] +} + diff --git a/dc-ui-guideline/components/app-header.json b/dc-ui-guideline/components/app-header.json new file mode 100644 index 0000000..95a1201 --- /dev/null +++ b/dc-ui-guideline/components/app-header.json @@ -0,0 +1,40 @@ +{ + "id": "app-header", + "name": "NodeDcAppHeader", + "kind": "component", + "status": "draft-stable", + "summary": "Top application header with logo, centered navigation group, workspace mark, and profile cluster.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/widgets/top-bar/TopBar.tsx" + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["nodedc-expanded-toolbar", "nodedc-expanded-nav-group", "nodedc-expanded-nav-button", "nodedc-expanded-user-group"] + }, + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/core/components/core/app-header.tsx" + } + ], + "anatomy": [ + "left brand logo", + "center workspace mark", + "center segmented nav", + "right profile pill with optional notification icon and avatar" + ], + "geometry": { + "shellPadding": "1.25rem top/right/left in launcher", + "pillHeight": "3rem in launcher expanded toolbar", + "brandLogo": "visual size follows Task Manager reference, not text-only brand" + }, + "rules": [ + "Header is monocolor black/dark, not gradient decoration.", + "Active top nav segment is white filled pill.", + "Profile avatar diameter must match reference topbar avatar.", + "Launcher and Task Manager headers must remain visually identical where routes overlap." + ] +} + diff --git a/dc-ui-guideline/components/calendar-popover.json b/dc-ui-guideline/components/calendar-popover.json new file mode 100644 index 0000000..2c5995f --- /dev/null +++ b/dc-ui-guideline/components/calendar-popover.json @@ -0,0 +1,47 @@ +{ + "id": "calendar-popover", + "name": "CalendarPopover", + "kind": "component", + "status": "stable-reference", + "summary": "Date picker popover based on Task Manager DateDropdown and nodedc-calendar-shell styling.", + "sourceRefs": [ + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/core/components/dropdowns/date.tsx", + "exports": ["DateDropdown"] + }, + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/styles/globals.css", + "classes": ["nodedc-calendar-shell"] + }, + { + "project": "nodedc_launcher", + "file": "src/widgets/admin-overlay/AdminOverlay.tsx", + "functions": ["DateField"] + } + ], + "anatomy": [ + "date trigger button", + "portal dropdown surface", + "calendar shell", + "month/year controls", + "day buttons", + "single or range mode" + ], + "visualContract": { + "surface": "DropdownSurface", + "calendarRadius": "1.1rem", + "dayButtonRadius": "999px", + "selectedRangeFill": "accentRgb with high contrast dark text", + "outsideDays": "muted" + }, + "behaviorContract": [ + "Default placement bottom-start.", + "Render through portal.", + "Support minDate, maxDate, clearable value, start-of-week preference.", + "Close on select when closeOnSelect is true." + ], + "nextImplementationStep": "Replace launcher native input date fallback with this shared calendar component." +} + diff --git a/dc-ui-guideline/components/circle-action-button.json b/dc-ui-guideline/components/circle-action-button.json new file mode 100644 index 0000000..3515074 --- /dev/null +++ b/dc-ui-guideline/components/circle-action-button.json @@ -0,0 +1,53 @@ +{ + "id": "circle-action-button", + "name": "CircleActionButton", + "kind": "primitive", + "status": "draft-stable", + "summary": "Icon-only circular action control for close, add, edit, refresh, search, copy, drag-adjacent actions, and toolbar icon actions.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/shared/ui/Button.tsx", + "exports": ["IconButton"] + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["admin-circle-action", "admin-panel-close", "services-admin-table__edit"] + }, + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/styles/globals.css", + "classes": ["nodedc-external-icon-button", "nodedc-toolbar-icon-button"] + } + ], + "anatomy": [ + "button element", + "single centered icon", + "aria-label/title", + "optional solid active/primary variant" + ], + "geometry": { + "size": "tokens.size.controlRing", + "shape": "circle", + "insetToHostEdge": "tokens.size.controlInset when anchored in a rounded container" + }, + "variants": { + "ghost": { + "background": "transparent", + "border": "soft white alpha only if needed", + "hover": "white alpha surface" + }, + "solid": { + "background": "rgba(247, 248, 244, 0.96)", + "color": "onAccentRgb" + } + }, + "rules": [ + "Do not replace with text pill when action is clear by icon.", + "Close button starts transparent with only soft circular boundary.", + "Hover may add subtle surface fill.", + "All icon-only admin actions share the same diameter." + ] +} + diff --git a/dc-ui-guideline/components/dropdown-surface.json b/dc-ui-guideline/components/dropdown-surface.json new file mode 100644 index 0000000..4f02c8c --- /dev/null +++ b/dc-ui-guideline/components/dropdown-surface.json @@ -0,0 +1,48 @@ +{ + "id": "dropdown-surface", + "name": "DropdownSurface", + "kind": "primitive", + "status": "stable-reference", + "summary": "Canonical dark floating surface for selection dropdowns, action dropdowns, filters, and profile menu popovers.", + "sourceRefs": [ + { + "project": "nodedc_taskmanager", + "file": "HDROPDOWN-CANON.md" + }, + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/styles/globals.css", + "classes": ["nodedc-dropdown-surface", "nodedc-dropdown-search", "nodedc-dropdown-option"] + }, + { + "project": "nodedc_launcher", + "file": "src/shared/ui/PortalDropdown.tsx" + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["portal-dropdown", "nodedc-dropdown-surface"] + } + ], + "visualContract": { + "background": "linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.01)) over rgba(8,8,11,0.9)", + "radius": "1.25rem", + "padding": "0.75rem", + "blur": "44px", + "shadow": "tokens.shadow.dropdown", + "border": "0" + }, + "behaviorContract": [ + "Render on fixed/portal layer when inside cards, sidebars, tables, sticky headers, or scroll containers.", + "Close on outside pointer and Escape.", + "Use Popper or equivalent fixed-position placement.", + "Default selection placement is bottom-start.", + "Default action placement for card quick actions is bottom-start or bottom-end depending on anchor edge." + ], + "optionContract": { + "radius": "0.9rem", + "hover": "rgba(255,255,255,0.06)", + "outline": "none" + } +} + diff --git a/dc-ui-guideline/components/entity-modal.json b/dc-ui-guideline/components/entity-modal.json new file mode 100644 index 0000000..110ffa2 --- /dev/null +++ b/dc-ui-guideline/components/entity-modal.json @@ -0,0 +1,47 @@ +{ + "id": "entity-modal", + "name": "EntityModal", + "kind": "component", + "status": "draft-stable", + "summary": "Dark glass edit/create modal used for services, clients, users, and groups.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/widgets/admin-overlay/AdminOverlay.tsx", + "functions": ["ServiceContentModal", "ClientEditorModal", "UserEditorModal", "GroupEditorModal", "EntityModalHead", "EntityModalFoot"] + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["service-content-modal-layer", "service-content-modal", "service-content-field"] + }, + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/styles/globals.css", + "classes": ["nodedc-glass-modal", "nodedc-modal-input", "nodedc-modal-editor", "nodedc-modal-primary-button"] + } + ], + "anatomy": [ + "fixed overlay layer", + "modal shell", + "head with eyebrow/title/close circle", + "scrollable responsive grid", + "fields", + "footer with cancel, optional delete, save" + ], + "visualContract": { + "shellWidth": "min(58rem, viewport - 2.8rem)", + "radius": "modal", + "background": "dark matte glass", + "blur": "modal", + "fieldRadius": "1rem to 1.25rem", + "footerButtonHeight": "2.75rem" + }, + "rules": [ + "Delete is left of Save inside the right footer action group.", + "Cancel stays on the left.", + "Close action is circular and transparent until hover.", + "Fields/selects/textareas share the same glass family." + ] +} + diff --git a/dc-ui-guideline/components/glass-panel.json b/dc-ui-guideline/components/glass-panel.json new file mode 100644 index 0000000..4795cff --- /dev/null +++ b/dc-ui-guideline/components/glass-panel.json @@ -0,0 +1,36 @@ +{ + "id": "glass-panel", + "name": "GlassPanel", + "kind": "surface", + "status": "draft-stable", + "summary": "Dark matte glass container used for panels, cards, modal shells, dropdown shells, and admin content blocks.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/shared/ui/Glass.tsx" + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["glass-surface", "admin-panel-nav", "admin-panel-content", "service-content-modal"] + }, + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/styles/globals.css", + "classes": ["nodedc-dropdown-surface", "nodedc-modal-field", "nodedc-settings-card"] + } + ], + "tokens": { + "radius": "card | modal | control depending on scale", + "blur": "panel | modal | dropdown", + "background": "dark matte glass gradient over rgba black", + "border": "none or transparent soft glass only" + }, + "rules": [ + "Never use hard outline as the main visual boundary.", + "Use background opacity and blur to separate layers.", + "For major shells use radius.card or radius.modal.", + "For controls inside shells use radius.control." + ] +} + diff --git a/dc-ui-guideline/components/launcher-showcase-stage.json b/dc-ui-guideline/components/launcher-showcase-stage.json new file mode 100644 index 0000000..70417b6 --- /dev/null +++ b/dc-ui-guideline/components/launcher-showcase-stage.json @@ -0,0 +1,33 @@ +{ + "id": "launcher-showcase-stage", + "name": "LauncherShowcaseStage", + "kind": "recipe-component", + "status": "draft-stable", + "summary": "Large showcase stage with looping ambient media, selected service media square, and glass description square.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/widgets/service-stage/ServiceStage.tsx" + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["service-stage", "stage-service-overlay", "stage-media-card", "stage-description-card", "stage-video-controls"] + } + ], + "anatomy": [ + "stage container", + "ambient background media", + "topline back/title", + "left side controls", + "two centered equal squares: media and description", + "bottom center previous/next controls" + ], + "rules": [ + "The media card and description card have equal width and height.", + "Cards are separated by a small gap and each has four rounded corners.", + "Ambient media fills the stage and clips to radius.card.", + "When admin panel content is open, stage content controls are hidden and media becomes decorative." + ] +} + diff --git a/dc-ui-guideline/components/media-source-field.json b/dc-ui-guideline/components/media-source-field.json new file mode 100644 index 0000000..1139dde --- /dev/null +++ b/dc-ui-guideline/components/media-source-field.json @@ -0,0 +1,40 @@ +{ + "id": "media-source-field", + "name": "MediaSourceField", + "kind": "component", + "status": "draft-stable", + "summary": "Media input field that switches between local storage upload and external URL for card and background content.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/widgets/admin-overlay/AdminOverlay.tsx", + "functions": ["MediaSourceField", "MediaPreview"] + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["service-media-control", "service-media-file-button", "service-media-source-button"] + } + ], + "anatomy": [ + "label with icon", + "rounded input/control shell", + "file chooser button", + "selected filename", + "URL input", + "two circular source buttons: file, url", + "preview surface" + ], + "behaviorContract": [ + "Local file upload persists to public storage and returns stable URL.", + "Source switch decides whether field uses stored file URL or external URL.", + "Accepts images, gifs, videos, and common video extensions.", + "Preview renders video when mediaKind or extension indicates video." + ], + "rules": [ + "The file chooser is a single rounded button, never browser default file input UI.", + "The source buttons are circular and attached to the field right side.", + "Background content and card content both accept the same media categories." + ] +} + diff --git a/dc-ui-guideline/components/profile-menu.json b/dc-ui-guideline/components/profile-menu.json new file mode 100644 index 0000000..f640439 --- /dev/null +++ b/dc-ui-guideline/components/profile-menu.json @@ -0,0 +1,41 @@ +{ + "id": "profile-menu", + "name": "ProfileMenu", + "kind": "component", + "status": "stable-reference", + "summary": "User profile popover opened from the top toolbar avatar. Uses ActionDropdown shell with custom menu content.", + "sourceRefs": [ + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/core/components/workspace/sidebar/user-menu-root.tsx", + "exports": ["UserMenuRoot"] + }, + { + "project": "nodedc_taskmanager", + "file": "plane-src/packages/ui/src/dropdowns/action-dropdown.tsx", + "exports": ["ActionDropdown"] + } + ], + "anatomy": [ + "toolbar avatar trigger", + "cover image header", + "centered circular avatar", + "user name and email", + "action rows: settings, sign out", + "optional admin-only action" + ], + "visualContract": { + "menuWidth": "18rem", + "menuPadding": "0.75rem", + "coverHeight": "7.25rem", + "coverRadius": "0.5rem in task manager reference; can be upgraded to token radius.control", + "rowRadius": "0.9rem", + "rowHover": "rgba(255,255,255,0.06)" + }, + "rules": [ + "Profile popover is an ActionDropdown menuContent variant, not a separate dropdown engine.", + "Avatar trigger stays circular and borderless.", + "Menu uses DropdownSurface/ActionDropdown stacking rules." + ] +} + diff --git a/dc-ui-guideline/components/segmented-nav.json b/dc-ui-guideline/components/segmented-nav.json new file mode 100644 index 0000000..d09dbcb --- /dev/null +++ b/dc-ui-guideline/components/segmented-nav.json @@ -0,0 +1,34 @@ +{ + "id": "segmented-nav", + "name": "SegmentedNav", + "kind": "component", + "status": "draft-stable", + "summary": "Rounded grouped navigation control used in topbars and mode switchers.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["nodedc-expanded-nav-group", "nodedc-expanded-nav-button"] + }, + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/styles/globals.css", + "classes": ["nodedc-toolbar-group", "nodedc-toolbar-pill", "nodedc-toolbar-primary"] + } + ], + "visualContract": { + "groupRadius": "999px", + "groupPadding": "0.25rem", + "buttonRadius": "999px", + "buttonHeight": "2.5rem to 3rem depending on header scale", + "activeFill": "white or accent depending on context", + "inactiveFill": "transparent or dark group surface" + }, + "rules": [ + "No outlines.", + "All items share height.", + "Active segment does not resize the group.", + "Use text labels only for route/mode tabs; icon-only actions use CircleActionButton." + ] +} + diff --git a/dc-ui-guideline/components/service-rail-card.json b/dc-ui-guideline/components/service-rail-card.json new file mode 100644 index 0000000..2cfaf8c --- /dev/null +++ b/dc-ui-guideline/components/service-rail-card.json @@ -0,0 +1,39 @@ +{ + "id": "service-rail-card", + "name": "ServiceRailCard", + "kind": "component", + "status": "draft-stable", + "summary": "Bottom launcher rail item made from a square media tile and separate glass description tile with an attached circular arrow action.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/widgets/service-rail/ServiceRail.tsx" + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["service-rail", "service-rail-card", "service-rail-card__media", "service-rail-card__body"] + } + ], + "anatomy": [ + "rail glass strip with ambient media under blur", + "service card group", + "square media tile", + "separate square body tile", + "status pill", + "circular arrow action" + ], + "layoutContract": [ + "One service centers in the rail.", + "Two services divide available rail into three equal gaps.", + "Three services divide into five equal gaps.", + "When gaps would become smaller than one tile size, horizontal scroll starts." + ], + "rules": [ + "Media and body tiles are separated by a small seam gap.", + "Both tiles have four rounded corners.", + "Tiles touch rail vertical bounds from top to bottom after rail padding rules.", + "The arrow action can select/open the service card." + ] +} + diff --git a/dc-ui-guideline/components/status-control.json b/dc-ui-guideline/components/status-control.json new file mode 100644 index 0000000..f1bf40d --- /dev/null +++ b/dc-ui-guideline/components/status-control.json @@ -0,0 +1,33 @@ +{ + "id": "status-control", + "name": "StatusControl", + "kind": "component", + "status": "draft-stable", + "summary": "Status pill and status dropdown for service/client/user/invite/sync/audit states.", + "sourceRefs": [ + { + "project": "nodedc_launcher", + "file": "src/widgets/admin-overlay/AdminOverlay.tsx", + "functions": ["ServiceStatusDropdown", "AdminStatusDropdown", "AdminStatusPill"] + }, + { + "project": "nodedc_launcher", + "file": "src/styles/globals.css", + "classes": ["service-status-trigger", "admin-status-trigger", "admin-status-menu"] + } + ], + "geometry": { + "width": "8.65rem for admin status, 7.45rem for compact service status", + "height": "2.08rem", + "radius": "999px", + "labelAlignment": "center" + }, + "tones": ["green", "yellow", "violet", "red", "muted"], + "rules": [ + "No outline and no select browser arrow inside status pills.", + "Clickable status opens DropdownSurface menu.", + "Static status uses the same pill geometry but pointer-events none.", + "Color opacity must stay restrained; status cannot become a bright visual hotspot." + ] +} + diff --git a/dc-ui-guideline/components/work-item-card.json b/dc-ui-guideline/components/work-item-card.json new file mode 100644 index 0000000..7cf74b5 --- /dev/null +++ b/dc-ui-guideline/components/work-item-card.json @@ -0,0 +1,42 @@ +{ + "id": "work-item-card", + "name": "WorkItemCard", + "kind": "component", + "status": "stable-reference", + "summary": "Task Manager kanban work item card with avatar header, centered title, progress, footer metadata, and ellipsis action dropdown.", + "sourceRefs": [ + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/core/components/issues/issue-layouts/shared/nodedc-work-item-card.tsx", + "exports": ["NodedcWorkItemCard", "NodedcWorkItemProgress", "getNodedcWorkItemCardAppearance"] + }, + { + "project": "nodedc_taskmanager", + "file": "plane-src/apps/web/styles/globals.css", + "classes": ["nodedc-work-item-card"] + } + ], + "anatomy": [ + "rounded card surface", + "header", + "optional subtitle", + "center title area", + "segmented progress", + "footer" + ], + "geometry": { + "radius": "28px in reference", + "padding": "1rem", + "minContentHeight": "220px" + }, + "states": { + "passive": "cardPassive surface with muted foreground", + "active": "cardActive accent surface with on-card-active foreground" + }, + "rules": [ + "Kanban card ellipsis uses ActionDropdown.", + "Card click must not intercept dropdown trigger clicks.", + "Progress segments use three equal tracks and accent fill when passive." + ] +} + diff --git a/dc-ui-guideline/mcp.manifest.json b/dc-ui-guideline/mcp.manifest.json new file mode 100644 index 0000000..314b9d2 --- /dev/null +++ b/dc-ui-guideline/mcp.manifest.json @@ -0,0 +1,33 @@ +{ + "schemaVersion": "0.1.0", + "serverName": "nodedc-ui-guideline", + "recommendedResources": [ + { + "uri": "nodedc-ui://registry", + "file": "registry.json", + "description": "Top-level component registry." + }, + { + "uri": "nodedc-ui://tokens", + "file": "tokens/nodedc.tokens.json", + "description": "Machine-readable design tokens." + }, + { + "uri": "nodedc-ui://rules", + "file": "rules/ui-rules.json", + "description": "Global UI rules and forbidden patterns." + }, + { + "uri": "nodedc-ui://sources", + "file": "sources/source-map.json", + "description": "Source implementation map across launcher and task manager." + } + ], + "toolingNotes": [ + "Expose each components/*.json file as a read-only resource.", + "Expose recipes/*.json as composition examples.", + "When generating UI, load registry, tokens, rules, then the specific component specs.", + "Prefer source references over re-inventing markup." + ] +} + diff --git a/dc-ui-guideline/recipes/admin-catalog.recipe.json b/dc-ui-guideline/recipes/admin-catalog.recipe.json new file mode 100644 index 0000000..468f3e1 --- /dev/null +++ b/dc-ui-guideline/recipes/admin-catalog.recipe.json @@ -0,0 +1,47 @@ +{ + "id": "admin-catalog", + "name": "AdminCatalogRecipe", + "summary": "Composition for launcher admin panel and catalog-style admin sections.", + "components": [ + "admin-side-nav", + "admin-table", + "status-control", + "calendar-popover", + "circle-action-button", + "entity-modal", + "media-source-field", + "dropdown-surface", + "action-dropdown" + ], + "layout": { + "base": "left AdminSideNav + optional AdminTable content + decorative compressed stage media", + "navOnly": "stage squeezes but keeps showcase controls", + "contentOpen": "content table opens next to nav; stage becomes narrow decorative media" + }, + "compositionRules": [ + "Admin nav buttons use the same row geometry as project quick-select buttons.", + "Table create actions are circular plus buttons.", + "Inline status fields use StatusControl, not native select UI.", + "Dates use CalendarPopover, with Task Manager calendar as reference.", + "Edit opens EntityModal; content/media uses MediaSourceField.", + "All dropdowns use portal/fixed layer." + ], + "sourceRefs": [ + { + "project": "nodedc_launcher", + "files": [ + "src/widgets/admin-overlay/AdminOverlay.tsx", + "src/styles/globals.css" + ] + }, + { + "project": "nodedc_taskmanager", + "files": [ + "plane-src/apps/web/core/components/dropdowns/date.tsx", + "plane-src/packages/ui/src/dropdowns/action-dropdown.tsx", + "plane-src/apps/web/styles/globals.css" + ] + } + ] +} + diff --git a/dc-ui-guideline/recipes/launcher-shell.recipe.json b/dc-ui-guideline/recipes/launcher-shell.recipe.json new file mode 100644 index 0000000..cfe53d4 --- /dev/null +++ b/dc-ui-guideline/recipes/launcher-shell.recipe.json @@ -0,0 +1,39 @@ +{ + "id": "launcher-shell", + "name": "LauncherShellRecipe", + "summary": "Composition for NODE.DC launcher main screen.", + "components": [ + "app-header", + "segmented-nav", + "launcher-showcase-stage", + "service-rail-card", + "circle-action-button", + "status-control", + "glass-panel" + ], + "layout": { + "root": "dark monocolor app background", + "top": "NodeDcAppHeader", + "center": "LauncherShowcaseStage", + "bottom": "ServiceRailCard collection in rail strip" + }, + "compositionRules": [ + "Header stays visually identical to Task Manager header where possible.", + "Stage and rail respect pagePad and panelGap tokens.", + "Selected service opens the stage detail; repeat click can close detail where the screen supports collapsed state.", + "Rail uses ambient media under glass, clipped to the strip." + ], + "sourceRefs": [ + { + "project": "nodedc_launcher", + "files": [ + "src/app/LauncherApp.tsx", + "src/widgets/top-bar/TopBar.tsx", + "src/widgets/service-stage/ServiceStage.tsx", + "src/widgets/service-rail/ServiceRail.tsx", + "src/styles/globals.css" + ] + } + ] +} + diff --git a/dc-ui-guideline/recipes/task-manager-board.recipe.json b/dc-ui-guideline/recipes/task-manager-board.recipe.json new file mode 100644 index 0000000..4585ffd --- /dev/null +++ b/dc-ui-guideline/recipes/task-manager-board.recipe.json @@ -0,0 +1,40 @@ +{ + "id": "task-manager-board", + "name": "TaskManagerBoardRecipe", + "summary": "Composition for Task Manager project board, including kanban cards, action dropdowns, profile menu, and calendar.", + "components": [ + "app-header", + "segmented-nav", + "work-item-card", + "action-dropdown", + "dropdown-surface", + "calendar-popover", + "profile-menu", + "circle-action-button" + ], + "layout": { + "top": "Task Manager header with active route segmented nav and profile cluster", + "board": "kanban columns with WorkItemCard items", + "floatingMenus": "ActionDropdown and selection dropdowns on portal layer", + "date": "CalendarPopover for task start/target dates" + }, + "compositionRules": [ + "Card ellipsis uses ActionDropdown.", + "Date chips open CalendarPopover.", + "Profile avatar opens ProfileMenu through ActionDropdown menuContent.", + "All popovers use DropdownSurface and never render inline inside cards." + ], + "sourceRefs": [ + { + "project": "nodedc_taskmanager", + "files": [ + "plane-src/apps/web/core/components/issues/issue-layouts/shared/nodedc-work-item-card.tsx", + "plane-src/apps/web/core/components/workspace/sidebar/user-menu-root.tsx", + "plane-src/apps/web/core/components/dropdowns/date.tsx", + "plane-src/packages/ui/src/dropdowns/action-dropdown.tsx", + "plane-src/apps/web/styles/globals.css" + ] + } + ] +} + diff --git a/dc-ui-guideline/registry.json b/dc-ui-guideline/registry.json new file mode 100644 index 0000000..40c4f53 --- /dev/null +++ b/dc-ui-guideline/registry.json @@ -0,0 +1,128 @@ +{ + "schemaVersion": "0.1.0", + "name": "NODE.DC UI Guideline", + "purpose": "Component registry for NODE.DC launcher, task manager, future apps, and MCP-backed UI generation.", + "sourceProjects": [ + { + "id": "nodedc_launcher", + "root": "/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher", + "role": "current launcher implementation and first MCP guideline host" + }, + { + "id": "nodedc_taskmanager", + "root": "/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER", + "role": "reference implementation for app header, work item cards, action dropdowns, profile menu, and calendar" + } + ], + "tokens": { + "json": "tokens/nodedc.tokens.json", + "css": "tokens/nodedc.tokens.css" + }, + "components": [ + { + "id": "app-header", + "spec": "components/app-header.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher", + "taskManagerReference": true + }, + { + "id": "segmented-nav", + "spec": "components/segmented-nav.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "circle-action-button", + "spec": "components/circle-action-button.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "glass-panel", + "spec": "components/glass-panel.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "dropdown-surface", + "spec": "components/dropdown-surface.json", + "status": "stable-reference", + "primarySource": "nodedc_taskmanager" + }, + { + "id": "action-dropdown", + "spec": "components/action-dropdown.json", + "status": "stable-reference", + "primarySource": "nodedc_taskmanager" + }, + { + "id": "status-control", + "spec": "components/status-control.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "calendar-popover", + "spec": "components/calendar-popover.json", + "status": "stable-reference", + "primarySource": "nodedc_taskmanager" + }, + { + "id": "profile-menu", + "spec": "components/profile-menu.json", + "status": "stable-reference", + "primarySource": "nodedc_taskmanager" + }, + { + "id": "admin-side-nav", + "spec": "components/admin-side-nav.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "admin-table", + "spec": "components/admin-table.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "entity-modal", + "spec": "components/entity-modal.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "media-source-field", + "spec": "components/media-source-field.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "launcher-showcase-stage", + "spec": "components/launcher-showcase-stage.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "service-rail-card", + "spec": "components/service-rail-card.json", + "status": "draft-stable", + "primarySource": "nodedc_launcher" + }, + { + "id": "work-item-card", + "spec": "components/work-item-card.json", + "status": "stable-reference", + "primarySource": "nodedc_taskmanager" + } + ], + "recipes": [ + "recipes/launcher-shell.recipe.json", + "recipes/admin-catalog.recipe.json", + "recipes/task-manager-board.recipe.json" + ], + "globalRules": "rules/ui-rules.json", + "sourceMap": "sources/source-map.json" +} + diff --git a/dc-ui-guideline/rules/ui-rules.json b/dc-ui-guideline/rules/ui-rules.json new file mode 100644 index 0000000..ee92355 --- /dev/null +++ b/dc-ui-guideline/rules/ui-rules.json @@ -0,0 +1,51 @@ +{ + "schemaVersion": "0.1.0", + "rules": [ + { + "id": "no-random-local-ui", + "severity": "error", + "text": "Do not create a local one-off UI element when a registry component exists." + }, + { + "id": "no-outlines", + "severity": "error", + "text": "Visible browser outlines and hard colored outlines are forbidden. Use surface hover/focus states." + }, + { + "id": "circle-actions", + "severity": "error", + "text": "Icon-only actions are circular controls. They use the shared control-ring size and 5px inset rules." + }, + { + "id": "dropdowns-portal", + "severity": "error", + "text": "Dropdowns inside cards, tables, sidebars, sticky headers, and scroll containers render through a portal/fixed layer." + }, + { + "id": "dropdowns-shared-engine", + "severity": "error", + "text": "Selection dropdowns and action dropdowns use the shared dropdown engine. Do not implement local outside-click and absolute inline menus." + }, + { + "id": "matte-glass", + "severity": "error", + "text": "Popup, dropdown, modal, sidebar, and settings surfaces use dark matte glass with blur, not plain transparency or light foreign backgrounds." + }, + { + "id": "status-pills", + "severity": "error", + "text": "Statuses use the shared status-tone palette, centered label, no outline, and fixed status control geometry." + }, + { + "id": "admin-tables", + "severity": "warning", + "text": "Admin data screens use AdminTable anatomy: table-shell, toolbar, editable cells, circular actions, and shared status/date controls." + }, + { + "id": "taskmanager-calendar", + "severity": "warning", + "text": "Calendar popovers must follow the Task Manager nodedc-calendar-shell and portal dropdown pattern." + } + ] +} + diff --git a/dc-ui-guideline/sources/source-map.json b/dc-ui-guideline/sources/source-map.json new file mode 100644 index 0000000..d2ebd8b --- /dev/null +++ b/dc-ui-guideline/sources/source-map.json @@ -0,0 +1,86 @@ +{ + "schemaVersion": "0.1.0", + "projects": { + "nodedc_launcher": { + "root": "/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher", + "sources": { + "tokensAndCss": [ + "src/styles/globals.css" + ], + "topBar": [ + "src/widgets/top-bar/TopBar.tsx" + ], + "launcherStage": [ + "src/widgets/service-stage/ServiceStage.tsx" + ], + "serviceRail": [ + "src/widgets/service-rail/ServiceRail.tsx" + ], + "adminOverlay": [ + "src/widgets/admin-overlay/AdminOverlay.tsx" + ], + "primitiveUi": [ + "src/shared/ui/Button.tsx", + "src/shared/ui/Glass.tsx", + "src/shared/ui/PortalDropdown.tsx" + ], + "storage": [ + "src/shared/api/storageApi.ts" + ] + } + }, + "nodedc_taskmanager": { + "root": "/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER", + "sources": { + "existingDocs": [ + "HDESIGN-CODE.md", + "HDROPDOWN-CANON.md", + "HUI-CANON-AUDIT.md", + "design.config.json" + ], + "tokensAndCss": [ + "plane-src/apps/web/styles/globals.css" + ], + "actionDropdown": [ + "plane-src/packages/ui/src/dropdowns/action-dropdown.tsx" + ], + "dateDropdown": [ + "plane-src/apps/web/core/components/dropdowns/date.tsx" + ], + "profileMenu": [ + "plane-src/apps/web/core/components/workspace/sidebar/user-menu-root.tsx" + ], + "workItemCard": [ + "plane-src/apps/web/core/components/issues/issue-layouts/shared/nodedc-work-item-card.tsx" + ], + "appHeader": [ + "plane-src/apps/web/core/components/core/app-header.tsx", + "plane-src/apps/web/ce/components/common/extended-app-header.tsx" + ] + } + } + }, + "crossProjectMapping": [ + { + "component": "dropdown-surface", + "launcher": ["portal-dropdown", "nodedc-dropdown-surface"], + "taskManager": ["nodedc-dropdown-surface", "nodedc-dropdown-option"] + }, + { + "component": "calendar-popover", + "launcher": ["DateField", "nodedc-calendar-shell placeholder"], + "taskManager": ["DateDropdown", "nodedc-calendar-shell"] + }, + { + "component": "profile-menu", + "launcher": ["topbar profile cluster needs implementation"], + "taskManager": ["UserMenuRoot"] + }, + { + "component": "admin-table", + "launcher": ["ServicesSection", "ClientsSection", "UsersSection", "GroupsSection"], + "taskManager": ["settings tables and external contour settings classes"] + } + ] +} + diff --git a/dc-ui-guideline/tokens/nodedc.tokens.css b/dc-ui-guideline/tokens/nodedc.tokens.css new file mode 100644 index 0000000..c04a380 --- /dev/null +++ b/dc-ui-guideline/tokens/nodedc.tokens.css @@ -0,0 +1,24 @@ +:root { + --nodedc-accent-rgb: 195 255 102; + --nodedc-card-passive-rgb: 42 43 46; + --nodedc-card-active-rgb: 195 255 102; + --nodedc-on-accent-rgb: 11 17 23; + --nodedc-radius-modal: 1.75rem; + --nodedc-radius-card: 1.35rem; + --nodedc-radius-control: 1.25rem; + --nodedc-radius-option: 0.9rem; + --nodedc-radius-calendar: 1.1rem; + --nodedc-radius-circle: 999px; + --nodedc-toolbar-pill-height: 2.5rem; + --nodedc-control-ring: 2.92rem; + --nodedc-control-inset: 5px; + --nodedc-status-width: 8.65rem; + --nodedc-status-height: 2.08rem; + --nodedc-page-pad: 1.25rem; + --nodedc-panel-gap: 1.25rem; + --nodedc-panel-pad: 1rem; + --nodedc-dropdown-blur: 44px; + --nodedc-panel-blur: 28px; + --nodedc-modal-blur: 34px; +} + diff --git a/dc-ui-guideline/tokens/nodedc.tokens.json b/dc-ui-guideline/tokens/nodedc.tokens.json new file mode 100644 index 0000000..03c6859 --- /dev/null +++ b/dc-ui-guideline/tokens/nodedc.tokens.json @@ -0,0 +1,79 @@ +{ + "schemaVersion": "0.1.0", + "name": "NODE.DC Design Tokens", + "color": { + "accentRgb": [195, 255, 102], + "onAccentRgb": [11, 17, 23], + "cardPassiveRgb": [42, 43, 46], + "cardActiveRgb": [195, 255, 102], + "surfaceBlack": "rgba(8, 8, 11, 0.9)", + "surfacePanel": "rgba(10, 10, 13, 0.88)", + "surfaceControl": "rgba(255, 255, 255, 0.06)", + "surfaceControlHover": "rgba(255, 255, 255, 0.10)", + "textPrimary": "rgba(255, 255, 255, 0.94)", + "textSecondary": "rgba(255, 255, 255, 0.74)", + "textMuted": "rgba(255, 255, 255, 0.54)" + }, + "radius": { + "modal": "1.75rem", + "card": "1.35rem", + "control": "1.25rem", + "dropdownOption": "0.9rem", + "calendar": "1.1rem", + "circle": "999px" + }, + "size": { + "toolbarHeight": "3rem", + "toolbarPillHeight": "2.5rem", + "controlRing": "2.92rem", + "controlInset": "5px", + "statusWidth": "8.65rem", + "statusHeight": "2.08rem", + "modalButtonHeight": "2.75rem", + "launcherRailHeight": "9.2rem" + }, + "space": { + "pagePad": "1.25rem", + "panelGap": "1.25rem", + "panelPad": "1rem", + "controlGap": "0.65rem", + "dropdownPad": "0.75rem", + "tableCellX": "0.75rem", + "tableCellY": "0.48rem" + }, + "blur": { + "dropdown": "44px", + "panel": "28px", + "modal": "34px", + "control": "18px" + }, + "shadow": { + "dropdown": "0 22px 60px rgba(0, 0, 0, 0.36), 0 6px 18px rgba(0, 0, 0, 0.2)", + "panel": "0 34px 110px rgba(0, 0, 0, 0.52)", + "modal": "0 34px 120px rgba(0, 0, 0, 0.62)", + "workItem": "0 14px 34px rgba(0, 0, 0, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.035)" + }, + "statusTone": { + "green": { + "background": "rgba(181, 255, 90, 0.075)", + "color": "rgba(226, 255, 190, 0.94)" + }, + "yellow": { + "background": "rgba(246, 201, 95, 0.075)", + "color": "rgba(255, 232, 178, 0.94)" + }, + "violet": { + "background": "rgba(210, 197, 255, 0.07)", + "color": "rgba(232, 225, 255, 0.92)" + }, + "red": { + "background": "rgba(255, 120, 120, 0.07)", + "color": "rgba(255, 216, 216, 0.92)" + }, + "muted": { + "background": "rgba(255, 255, 255, 0.075)", + "color": "rgba(255, 255, 255, 0.78)" + } + } +} +