From 18c722e5bc7f5d22a5fffcd6966e536c472d3a8c Mon Sep 17 00:00:00 2001 From: Thomas Nilles Date: Sat, 16 May 2026 16:36:49 -0400 Subject: [PATCH] Initialize work order management system with database schema, API handlers, web client, and Docker configuration. --- web/components/wo-form.mjs | 15 ++++---- web/components/wo-list.mjs | 24 ++++++------- web/styles/global.css | 74 ++++++++++++++++++++++++++++++++------ 3 files changed, 83 insertions(+), 30 deletions(-) diff --git a/web/components/wo-form.mjs b/web/components/wo-form.mjs index e3584cc..ac9fa67 100644 --- a/web/components/wo-form.mjs +++ b/web/components/wo-form.mjs @@ -26,21 +26,22 @@ class WoForm extends HTMLElement { :host { display: block; } form { display: grid; gap: 1rem; } .row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; } - label { display: flex; flex-direction: column; gap: .3rem; font-size: .9rem; font-weight: 600; color: #1a2e3b; } + label { display: flex; flex-direction: column; gap: .3rem; font-size: .9rem; font-weight: 600; color: var(--text); } input, select, textarea { - border: 1px solid #e2ebf0; border-radius: 8px; - padding: .5rem .75rem; font-size: .95rem; background: #fff; color: #1a2e3b; + border: 1px solid var(--border); border-radius: 8px; + padding: .5rem .75rem; font-size: .95rem; background: var(--surface); color: var(--text); + color-scheme: inherit; } - input:focus, select:focus, textarea:focus { outline: none; border-color: #0a7ea4; } + input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); } textarea { resize: vertical; min-height: 80px; } .actions { display: flex; gap: .75rem; justify-content: flex-end; } button { padding: .5rem 1.25rem; border: none; border-radius: 8px; font-weight: 600; cursor: pointer; } - .btn-primary { background: #0a7ea4; color: #fff; } - .btn-cancel { background: transparent; border: 1px solid #e2ebf0; color: #1a2e3b; } - .error { color: #c0392b; font-size: .85rem; } + .btn-primary { background: var(--accent); color: #fff; } + .btn-cancel { background: transparent; border: 1px solid var(--border); color: var(--text); } + .error { color: var(--danger); font-size: .85rem; }
diff --git a/web/components/wo-list.mjs b/web/components/wo-list.mjs index c5810bf..40624ce 100644 --- a/web/components/wo-list.mjs +++ b/web/components/wo-list.mjs @@ -20,28 +20,28 @@ class WoList extends HTMLElement { this.shadowRoot.innerHTML = ` ${this.#data.length === 0 ? '
No work orders found.
' diff --git a/web/styles/global.css b/web/styles/global.css index 6190eb6..b3c6428 100644 --- a/web/styles/global.css +++ b/web/styles/global.css @@ -1,8 +1,10 @@ +/* ── Light mode (default) ─────────────────────────────────────────────────── */ :root { --navy: #0d2137; --accent: #0a7ea4; --accent-lt: #14b8d4; --surface: #ffffff; + --surface-2: #f8fafc; --bg: #f0f6fa; --border: #e2ebf0; --text: #1a2e3b; @@ -13,17 +15,57 @@ --radius: 8px; --shadow: 0 2px 8px rgba(0,0,0,.08); + /* Status badge colours — light */ + --badge-draft-bg: #e2e8f0; --badge-draft-text: #475569; + --badge-assigned-bg: #dbeafe; --badge-assigned-text: #1d4ed8; + --badge-scheduled-bg: #fef3c7; --badge-scheduled-text: #92400e; + --badge-in_progress-bg: #d1fae5; --badge-in_progress-text: #065f46; + --badge-pending_review-bg: #ede9fe; --badge-pending_review-text: #5b21b6; + --badge-closed-bg: #f3f4f6; --badge-closed-text: #6b7280; + font-family: Calibri, 'Segoe UI', system-ui, sans-serif; font-size: 16px; color: var(--text); background: var(--bg); + color-scheme: light; } +/* ── Dark mode ────────────────────────────────────────────────────────────── */ +@media (prefers-color-scheme: dark) { + :root { + --navy: #0a1929; + --accent: #29b6d8; + --accent-lt: #4dd0e8; + --surface: #0f2336; + --surface-2: #0c1d2e; + --bg: #081828; + --border: #1e3a52; + --text: #e2eaf2; + --muted: #8baabf; + --danger: #f87171; + --success: #34d399; + --warning: #fbbf24; + --shadow: 0 2px 12px rgba(0,0,0,.4); + + /* Status badge colours — dark (muted tints so they don't blaze) */ + --badge-draft-bg: #1e2d3d; --badge-draft-text: #94a3b8; + --badge-assigned-bg: #1e3a5f; --badge-assigned-text: #93c5fd; + --badge-scheduled-bg: #3d2e00; --badge-scheduled-text: #fde68a; + --badge-in_progress-bg: #064e30; --badge-in_progress-text: #6ee7b7; + --badge-pending_review-bg: #2e1f5e; --badge-pending_review-text: #c4b5fd; + --badge-closed-bg: #1c2a38; --badge-closed-text: #6b7280; + + color-scheme: dark; + } +} + +/* ── Reset ────────────────────────────────────────────────────────────────── */ body { min-height: 100vh; } a { color: var(--accent); text-decoration: none; } a:hover { text-decoration: underline; } +/* ── Buttons ──────────────────────────────────────────────────────────────── */ button { cursor: pointer; border: none; @@ -41,6 +83,7 @@ button.secondary { color: var(--text); } +/* ── Form controls ────────────────────────────────────────────────────────── */ input, select, textarea { border: 1px solid var(--border); border-radius: var(--radius); @@ -55,6 +98,10 @@ input:focus, select:focus, textarea:focus { border-color: var(--accent); } +/* Native date/time pickers pick up OS colour scheme via color-scheme property */ +input[type="datetime-local"] { color-scheme: inherit; } + +/* ── Cards ────────────────────────────────────────────────────────────────── */ .card { background: var(--surface); border: 1px solid var(--border); @@ -63,6 +110,7 @@ input:focus, select:focus, textarea:focus { box-shadow: var(--shadow); } +/* ── Status badges ────────────────────────────────────────────────────────── */ .badge { display: inline-block; padding: .2rem .6rem; @@ -72,15 +120,17 @@ input:focus, select:focus, textarea:focus { text-transform: uppercase; letter-spacing: .04em; } -.badge-draft { background: #e2e8f0; color: #475569; } -.badge-assigned { background: #dbeafe; color: #1d4ed8; } -.badge-scheduled { background: #fef3c7; color: #92400e; } -.badge-in_progress { background: #d1fae5; color: #065f46; } -.badge-pending_review { background: #ede9fe; color: #5b21b6; } -.badge-closed { background: #f3f4f6; color: #6b7280; } +.badge-draft { background: var(--badge-draft-bg); color: var(--badge-draft-text); } +.badge-assigned { background: var(--badge-assigned-bg); color: var(--badge-assigned-text); } +.badge-scheduled { background: var(--badge-scheduled-bg); color: var(--badge-scheduled-text); } +.badge-in_progress { background: var(--badge-in_progress-bg); color: var(--badge-in_progress-text); } +.badge-pending_review { background: var(--badge-pending_review-bg); color: var(--badge-pending_review-text); } +.badge-closed { background: var(--badge-closed-bg); color: var(--badge-closed-text); } +/* ── Layout ───────────────────────────────────────────────────────────────── */ #app { max-width: 1200px; margin: 0 auto; padding: 0 1rem; } +/* ── Nav ──────────────────────────────────────────────────────────────────── */ nav { background: var(--navy); color: #fff; @@ -88,13 +138,15 @@ nav { display: flex; align-items: center; gap: 1.5rem; + border-bottom: 1px solid rgba(255,255,255,.06); } -nav .brand { font-weight: 700; font-size: 1.1rem; color: #fff; } -nav a { color: rgba(255,255,255,.8); font-size: .9rem; } -nav a:hover { color: #fff; text-decoration: none; } -nav .spacer { flex: 1; } -nav .user-info { font-size: .85rem; color: rgba(255,255,255,.7); } +nav .brand { font-weight: 700; font-size: 1.1rem; color: #fff; } +nav a { color: rgba(255,255,255,.8); font-size: .9rem; } +nav a:hover { color: #fff; text-decoration: none; } +nav .spacer { flex: 1; } +nav .user-info { font-size: .85rem; color: rgba(255,255,255,.6); } +/* ── Page header ──────────────────────────────────────────────────────────── */ .page-header { display: flex; align-items: center;