Move foundation CSS into public/css (todo §1); drop placeholder style.css, repoint views + mockups

This commit is contained in:
2026-06-15 11:25:43 +02:00
parent a070362649
commit 30db8216e6
12 changed files with 15 additions and 90 deletions

View File

@@ -362,11 +362,11 @@ src/context.ts RequestContext handed to handlers + buildContext()
src/config.ts Env loader — Ory endpoints, cookie/CSRF secrets, JWKS, port; validated at boot
src/plugin.ts definePlugin() + the host's plugin discovery/router (planned)
views/ Core EJS templates (index, 403/404/500, partials/)
public/ Static assets under /public/ (css/, favicon, robots.txt)
public/ Static assets under /public/ (css/styles.css + auth.css, favicon, robots.txt)
config/menu.ts Central menu override + branding (planned)
plugins/ Drop-in plugin folders, auto-discovered (planned)
html-css-foundation/ Raw HTML/CSS design reference — the source for the
building-block partials; not served.
html-css-foundation/ HTML design mockups — the source for the building-block
partials; reference the stylesheets in public/css/.
```
Comments and docs cite roadmap phases as `§N` — the sections in `todo.md`.

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>App Shell — Template</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="../public/css/styles.css">
</head>
<body>

View File

@@ -4,8 +4,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sign in — Console</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="auth.css">
<link rel="stylesheet" href="../public/css/styles.css">
<link rel="stylesheet" href="../public/css/auth.css">
</head>
<body>

View File

@@ -1,75 +0,0 @@
:root {
color-scheme: light dark;
--bg: #ffffff;
--fg: #1a1a1a;
--muted: #5a5a5a;
--accent: #2563eb;
--border: #e5e5e5;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #15171a;
--fg: #e8e8e8;
--muted: #9aa0a6;
--accent: #6ea8fe;
--border: #2a2d31;
}
}
* {
box-sizing: border-box;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 16px/1.6 system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}
.site-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--border);
}
.site-header .brand {
font-weight: 700;
text-decoration: none;
color: var(--fg);
}
.site-header nav a {
color: var(--muted);
text-decoration: none;
}
.site-header nav a:hover {
color: var(--accent);
}
main,
footer {
max-width: 42rem;
margin: 0 auto;
padding: 1.5rem;
}
footer {
color: var(--muted);
border-top: 1px solid var(--border);
}
a {
color: var(--accent);
}
code {
background: color-mix(in srgb, var(--fg) 8%, transparent);
padding: 0.1rem 0.35rem;
border-radius: 4px;
}

View File

@@ -29,11 +29,11 @@ test("serves the home page as HTML", async () => {
});
test("serves a static file: GET sends body + content-type, HEAD sends headers only", async () => {
const get = await fetch(base + "/public/css/style.css");
const get = await fetch(base + "/public/css/styles.css");
assert.equal(get.status, 200);
assert.match(get.headers.get("content-type") ?? "", /text\/css/);
const head = await fetch(base + "/public/css/style.css", { method: "HEAD" });
const head = await fetch(base + "/public/css/styles.css", { method: "HEAD" });
assert.equal(head.status, 200);
assert.ok(Number(head.headers.get("content-length")) > 0);
assert.equal((await head.text()).length, 0);
@@ -83,7 +83,7 @@ test("renders the 500 HTML page when a handler throws", async () => {
test("renders the 403 error page as HTML", async () => {
const html = await ejs.renderFile(join(viewsDir, "403.ejs"), { title: "Forbidden" });
assert.match(html, /403/);
assert.match(html, /style\.css/);
assert.match(html, /styles\.css/);
});
test("rejects unsafe static request paths (encoded traversal, NUL) with 403", async () => {
@@ -94,7 +94,7 @@ test("rejects unsafe static request paths (encoded traversal, NUL) with 403", as
test("resolveStaticPath blocks traversal and control chars, allows nested files", () => {
assert.equal(resolveStaticPath("/srv/public", "../app.ts"), null);
assert.equal(resolveStaticPath("/srv/public", "a\x00b"), null);
assert.equal(resolveStaticPath("/srv/public", "css/style.css"), "/srv/public/css/style.css");
assert.equal(resolveStaticPath("/srv/public", "css/styles.css"), "/srv/public/css/styles.css");
});
test("contentTypeFor maps known and unknown extensions", () => {

View File

@@ -25,7 +25,7 @@ everything via Docker.
- [x] Remove all usage of NODE_ENV - add a new core principle to the project that the app should at all times be unaware of what environment it is running in. Configuration should be explicit, like "disable email" or "cache templates". → Dropped NODE_ENV everywhere; added **environment-agnostic** principle (AGENTS.md §4 + README). Behaviour is now explicit toggles: `CACHE_TEMPLATES`, `REQUIRE_SECURE_SECRETS` (parsed/validated in `config.ts`, wired via `server.ts`); compose files set them per deployment. `app.ts` no longer reads `process.env`.
## 1. Building blocks — extract from `html-css-foundation/` (no Ory needed; render mock data)
- [ ] Move `styles.css` + `auth.css` into `public/css/`; remove existing `style.css`.
- [x] Move `styles.css` + `auth.css` into `public/css/`; remove existing `style.css`.`git mv` from `html-css-foundation/` into `public/css/`; dropped the placeholder `style.css`; views + tests now reference `styles.css`; foundation mockups repointed to `../public/css/`.
- [ ] Lucide icon sprite from `lucide-static` (dep added) → `views/partials/icons.ejs`; serve/inline only the icons used.
- [ ] App-shell partial (sidebar + topbar + content slot).
- [ ] Nav-tree partial — recursive, header/leaf × clickable/static, counts, `aria-current`.

View File

@@ -4,7 +4,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title><%= title %></title>
<link rel="stylesheet" href="/public/css/style.css" />
<link rel="stylesheet" href="/public/css/styles.css" />
</head>
<body>
<main>

View File

@@ -4,7 +4,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title><%= title %></title>
<link rel="stylesheet" href="/public/css/style.css" />
<link rel="stylesheet" href="/public/css/styles.css" />
</head>
<body>
<main>

View File

@@ -4,7 +4,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title><%= title %></title>
<link rel="stylesheet" href="/public/css/style.css" />
<link rel="stylesheet" href="/public/css/styles.css" />
</head>
<body>
<main>

View File

@@ -4,7 +4,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title><%= title %></title>
<link rel="stylesheet" href="/public/css/style.css" />
<link rel="stylesheet" href="/public/css/styles.css" />
<link rel="icon" href="/public/favicon.svg" />
</head>
<body>