diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index c0d6db3..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "tools/ui-design-code"]
- path = tools/ui-design-code
- url = ../ui-design-code
diff --git a/README.md b/README.md
index 731380c..32db7fa 100644
--- a/README.md
+++ b/README.md
@@ -3,18 +3,3 @@
Architecture documentation was moved to the Project Bible:
- `bible/README.md`
-
-## UI design-code integration
-
-`core` now serves UI theme assets from `ui-design-code` at runtime:
-
-- CSS: `/ui-design/static/css/theme.css`
-- JS: `/ui-design/static/js/app.js`
-
-Path resolution order for `ui-design-code`:
-
-1. `UI_DESIGN_CODE_DIR` env var
-2. `./tools/ui-design-code`
-3. `../ui-design-code`
-
-This lets UI updates in `ui-design-code` appear in `core` without copying files.
diff --git a/internal/api/ui.go b/internal/api/ui.go
index 12e8e2b..5051c99 100644
--- a/internal/api/ui.go
+++ b/internal/api/ui.go
@@ -201,7 +201,6 @@ type uiHandlers struct {
func RegisterUIRoutes(mux *http.ServeMux, deps UIDependencies) {
h := uiHandlers{deps: deps}
- registerUIDesignRoutes(mux)
mux.HandleFunc("/", h.handleStart)
mux.HandleFunc("/ui", h.handleIndex)
mux.HandleFunc("/ui/", h.handleIndex)
diff --git a/internal/api/ui_design_assets.go b/internal/api/ui_design_assets.go
deleted file mode 100644
index 3f1f068..0000000
--- a/internal/api/ui_design_assets.go
+++ /dev/null
@@ -1,134 +0,0 @@
-package api
-
-import (
- "errors"
- "fmt"
- "log"
- "net/http"
- "os"
- "path/filepath"
- "runtime"
- "strings"
-)
-
-type uiDesignAssets struct {
- RootPath string
- CSSPath string
- JSPath string
-}
-
-func registerUIDesignRoutes(mux *http.ServeMux) {
- assets, err := resolveUIDesignAssets()
- if err != nil {
- log.Printf("ui design assets: %v", err)
- return
- }
- log.Printf("ui design assets: using %s", assets.RootPath)
-
- mux.HandleFunc("/ui-design/static/css/theme.css", func(w http.ResponseWriter, r *http.Request) {
- serveUIDesignFile(w, r, "/ui-design/static/css/theme.css", assets.CSSPath, "text/css; charset=utf-8")
- })
- if assets.JSPath != "" {
- mux.HandleFunc("/ui-design/static/js/app.js", func(w http.ResponseWriter, r *http.Request) {
- serveUIDesignFile(w, r, "/ui-design/static/js/app.js", assets.JSPath, "application/javascript; charset=utf-8")
- })
- }
-}
-
-func serveUIDesignFile(w http.ResponseWriter, r *http.Request, routePath, filePath, contentType string) {
- if r.URL.Path != routePath {
- http.NotFound(w, r)
- return
- }
- if r.Method != http.MethodGet && r.Method != http.MethodHead {
- w.WriteHeader(http.StatusMethodNotAllowed)
- return
- }
- if _, err := os.Stat(filePath); err != nil {
- http.NotFound(w, r)
- return
- }
- w.Header().Set("Cache-Control", "no-store")
- w.Header().Set("Content-Type", contentType)
- http.ServeFile(w, r, filePath)
-}
-
-func resolveUIDesignAssets() (uiDesignAssets, error) {
- roots := candidateUIDesignRoots()
- if len(roots) == 0 {
- return uiDesignAssets{}, errors.New("no ui-design-code path candidates")
- }
-
- cssSuffixes := []string{
- filepath.Join("demo", "web", "static", "css", "app.css"),
- filepath.Join("kit", "patterns", "theme-vapor", "static", "vapor.css"),
- filepath.Join("kit", "patterns", "theme-aqua-legacy", "demo-aqua-freeze.css"),
- }
- jsSuffixes := []string{
- filepath.Join("demo", "web", "static", "js", "app.js"),
- }
-
- for _, root := range roots {
- cssPath := firstExistingFile(root, cssSuffixes)
- if cssPath == "" {
- continue
- }
- jsPath := firstExistingFile(root, jsSuffixes)
- return uiDesignAssets{
- RootPath: root,
- CSSPath: cssPath,
- JSPath: jsPath,
- }, nil
- }
-
- return uiDesignAssets{}, fmt.Errorf("ui-design-code not found in candidates: %s", strings.Join(roots, ", "))
-}
-
-func candidateUIDesignRoots() []string {
- seen := make(map[string]struct{})
- var roots []string
-
- push := func(path string) {
- if strings.TrimSpace(path) == "" {
- return
- }
- abs, err := filepath.Abs(path)
- if err != nil {
- return
- }
- abs = filepath.Clean(abs)
- if _, ok := seen[abs]; ok {
- return
- }
- info, err := os.Stat(abs)
- if err != nil || !info.IsDir() {
- return
- }
- seen[abs] = struct{}{}
- roots = append(roots, abs)
- }
-
- push(os.Getenv("UI_DESIGN_CODE_DIR"))
- push(filepath.Join("tools", "ui-design-code"))
- push(filepath.Join("..", "ui-design-code"))
-
- if _, file, _, ok := runtime.Caller(0); ok {
- apiDir := filepath.Dir(file)
- coreRoot := filepath.Clean(filepath.Join(apiDir, "..", ".."))
- push(filepath.Join(coreRoot, "tools", "ui-design-code"))
- push(filepath.Join(coreRoot, "..", "ui-design-code"))
- }
-
- return roots
-}
-
-func firstExistingFile(root string, suffixes []string) string {
- for _, suffix := range suffixes {
- path := filepath.Join(root, suffix)
- info, err := os.Stat(path)
- if err == nil && !info.IsDir() {
- return path
- }
- }
- return ""
-}
diff --git a/internal/api/ui_shared.tmpl b/internal/api/ui_shared.tmpl
index 6271011..704e596 100644
--- a/internal/api/ui_shared.tmpl
+++ b/internal/api/ui_shared.tmpl
@@ -855,8 +855,6 @@
}
}
-
-