a3f369f437
Introduce the first PLAN.md milestone: replace the hello-world binary with an Axum server that binds to localhost by default, exposes a health endpoint, and serves the static browser UI from the repository's static directory. The router is available through the library crate so integration tests can exercise server behavior without opening a network listener. Add a justfile for routine validation and document the initial project shape, configuration knobs, and reusable test checklist. The rustfmt config now uses only stable options so the new formatting recipe runs without nightly warnings. The upload API and resumable chunk behavior are intentionally left for later milestones; the UI currently handles file selection only. Test Plan: - just check Refs: PLAN.md milestone 1
178 lines
2.7 KiB
CSS
178 lines
2.7 KiB
CSS
:root {
|
|
color-scheme: light dark;
|
|
--bg: #f6f7f9;
|
|
--panel: #ffffff;
|
|
--text: #1d2430;
|
|
--muted: #667085;
|
|
--line: #d0d5dd;
|
|
--accent: #147a73;
|
|
--accent-strong: #0f5f59;
|
|
--track: #e4e7ec;
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
min-height: 100vh;
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
font-family:
|
|
Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
|
|
sans-serif;
|
|
}
|
|
|
|
button,
|
|
input {
|
|
font: inherit;
|
|
}
|
|
|
|
.app-shell {
|
|
width: min(720px, 100%);
|
|
margin: 0 auto;
|
|
padding: 32px 16px;
|
|
}
|
|
|
|
.upload-panel {
|
|
display: grid;
|
|
gap: 20px;
|
|
padding: 24px;
|
|
border: 1px solid var(--line);
|
|
border-radius: 8px;
|
|
background: var(--panel);
|
|
box-shadow: 0 10px 30px rgb(16 24 40 / 8%);
|
|
}
|
|
|
|
.panel-heading {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: 16px;
|
|
}
|
|
|
|
h1,
|
|
p {
|
|
margin: 0;
|
|
}
|
|
|
|
h1 {
|
|
font-size: 2rem;
|
|
line-height: 1.1;
|
|
}
|
|
|
|
.subtle {
|
|
margin-top: 6px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
.status-pill {
|
|
flex: 0 0 auto;
|
|
padding: 6px 10px;
|
|
border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent);
|
|
border-radius: 999px;
|
|
color: var(--accent-strong);
|
|
background: color-mix(in srgb, var(--accent) 10%, transparent);
|
|
font-size: 0.875rem;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.file-picker {
|
|
display: grid;
|
|
gap: 10px;
|
|
padding: 18px;
|
|
border: 1px dashed var(--line);
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.file-picker span {
|
|
font-weight: 700;
|
|
}
|
|
|
|
.file-summary {
|
|
display: grid;
|
|
gap: 4px;
|
|
padding: 14px;
|
|
border: 1px solid var(--line);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.file-summary span {
|
|
color: var(--muted);
|
|
}
|
|
|
|
.progress-wrap {
|
|
height: 14px;
|
|
overflow: hidden;
|
|
border-radius: 999px;
|
|
background: var(--track);
|
|
}
|
|
|
|
.progress-bar {
|
|
width: 0%;
|
|
height: 100%;
|
|
background: var(--accent);
|
|
transition: width 180ms ease;
|
|
}
|
|
|
|
.actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
}
|
|
|
|
button {
|
|
min-width: 96px;
|
|
min-height: 40px;
|
|
border: 1px solid transparent;
|
|
border-radius: 6px;
|
|
color: #ffffff;
|
|
background: var(--accent);
|
|
font-weight: 700;
|
|
cursor: pointer;
|
|
}
|
|
|
|
button:disabled {
|
|
color: var(--muted);
|
|
background: var(--track);
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.event-log {
|
|
min-height: 80px;
|
|
margin: 0;
|
|
padding: 14px 14px 14px 32px;
|
|
border: 1px solid var(--line);
|
|
border-radius: 8px;
|
|
color: var(--muted);
|
|
}
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
:root {
|
|
--bg: #14161a;
|
|
--panel: #1f242b;
|
|
--text: #f2f4f7;
|
|
--muted: #b8c0cc;
|
|
--line: #3d4654;
|
|
--accent: #35b8aa;
|
|
--accent-strong: #9ce4dc;
|
|
--track: #343b46;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 520px) {
|
|
.panel-heading {
|
|
display: grid;
|
|
}
|
|
|
|
.status-pill {
|
|
width: max-content;
|
|
}
|
|
|
|
.upload-panel {
|
|
padding: 18px;
|
|
}
|
|
}
|