Files
nanodrop/public/style.css
Brendan Chen 8fd1464b9d Add server, routes, views, CLI, CSS, and integration tests
- Server factory with Fastify plugins (JWT, cookie, multipart, formbody, static)
- Auth middleware: requireAuth preHandler (401 for API, redirect for pages)
- Auth API routes: POST /api/v1/auth/login, POST /api/v1/auth/logout
- File API routes: GET/POST /api/v1/files, DELETE /api/v1/files/:id
- Page routes: /, /login, /logout, /upload, /files, /files/:id/delete, /f/:id, /f/:id/raw
- HTML views: layout, login, upload, file-list, file-view, not-found
- CLI register-user script
- public/style.css dark theme
- Test helpers: createTestApp, loginAs, buildMultipart
- Integration tests for auth API, file API, and page routes (51 tests passing)
- Update CLAUDE.md with red/green TDD and commit instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-03 15:55:14 -08:00

127 lines
2.9 KiB
CSS

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #0f1117;
--surface: #1c1f2e;
--border: #2a2d3e;
--accent: #6c63ff;
--accent-hover: #5a52e0;
--text: #e2e8f0;
--muted: #8892a4;
--error: #f56565;
--danger: #e53e3e;
}
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
min-height: 100vh;
display: flex;
flex-direction: column;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
header {
display: flex;
align-items: center;
gap: 1.5rem;
padding: 1rem 2rem;
border-bottom: 1px solid var(--border);
}
.logo { font-size: 1.25rem; font-weight: 700; color: var(--text); }
nav { display: flex; align-items: center; gap: 1rem; margin-left: auto; }
nav a { color: var(--muted); font-size: 0.9rem; }
nav a:hover { color: var(--text); }
main { flex: 1; padding: 2rem; display: flex; justify-content: center; align-items: flex-start; }
.form-container {
width: 100%;
max-width: 420px;
margin-top: 4rem;
}
.form-container h1 { margin-bottom: 1.5rem; font-size: 1.5rem; }
form { display: flex; flex-direction: column; gap: 1rem; }
label {
display: flex;
flex-direction: column;
gap: 0.375rem;
font-size: 0.875rem;
color: var(--muted);
}
input[type="text"],
input[type="password"],
input[type="file"] {
padding: 0.625rem 0.75rem;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
color: var(--text);
font-size: 1rem;
width: 100%;
}
input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
button, .btn {
padding: 0.625rem 1.25rem;
background: var(--accent);
border: none;
border-radius: 6px;
color: #fff;
font-size: 0.9rem;
font-weight: 600;
cursor: pointer;
text-align: center;
display: inline-block;
}
button:hover, .btn:hover { background: var(--accent-hover); }
button.danger { background: var(--danger); }
button.danger:hover { background: #c53030; }
.error { color: var(--error); font-size: 0.9rem; margin-bottom: 0.5rem; }
.share-box {
display: flex;
gap: 0.5rem;
margin: 1rem 0;
}
.share-box input { flex: 1; }
/* File view — centered */
.file-view {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 60vh;
gap: 1.5rem;
text-align: center;
}
.file-view h1 { font-size: 1.25rem; color: var(--muted); word-break: break-all; }
.file-view video,
.file-view audio { max-width: 800px; width: 100%; border-radius: 8px; }
.file-actions { display: flex; gap: 1rem; }
/* File list table */
table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
th, td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--border); }
th { color: var(--muted); font-weight: 600; }
tr:hover td { background: var(--surface); }
h1 { margin-bottom: 1rem; }