From 245f94d344ec126621394af28baf8ed5aad8d036 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Fri, 7 Aug 2026 10:30:45 -0400 Subject: [PATCH] Stop two dialogs going see-through in dark mode --bg-card is deliberately translucent in dark mode (rgba(0,0,61,0.4)) so cards glass over the page; --bg-card-solid exists for the things that must not. Two hand-rolled modal panels used the former, leaving the notification-type and access-protocol editors transparent over the overlay with the table legible through them. The shared .modal in style.css already got this right. Also writes down the page-vs-modal rule the codebase already follows, since nothing stated it: a record with a detail page gets a routed form page, a lookup row that only exists inside its list gets a modal over that list. Plus the modal rules from the overlay-close fix - data entry never closes on a stray click, confirmations may, and panels are painted solid. --- frontend/CLAUDE.md | 16 ++++++++++++++++ .../frontend/views/AccessProtocolsList.vue | 4 +++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/frontend/CLAUDE.md b/frontend/CLAUDE.md index 700750f..b3e32ce 100644 --- a/frontend/CLAUDE.md +++ b/frontend/CLAUDE.md @@ -96,6 +96,22 @@ Use `PrintersList.vue` as the reference for new list pages. It has NO scoped sty Dark mode is automatic via `@media (prefers-color-scheme: dark)`. Using CSS variables ensures colors adapt automatically - no extra work needed per page. +## Data Entry: Page or Modal + +Both patterns are in use on purpose. Pick by what the record IS, not by how big the form feels today. + +**Routed form page** (`views/Form.vue` + a route) when the record has its own detail page and its own URL: machines, PCs, printers, network devices, measuring tools, USB devices, applications, knowledge-base articles, notifications, printed items. These forms are long, often carry an image upload, a map-position picker or relationship editing, and someone will want to link straight to one. + +**Modal over its list** when the record is reference data that only exists inside the list it belongs to: every `*TypesList`, plus locations, vendors, models, VLANs, subnets, support teams, custom fields, API tokens, printer drivers, dashboard defaults. The form is a handful of fields, and keeping the list visible behind the dialog is the point. + +Rule of thumb: **a thing with a detail page gets a form page; a lookup row gets a modal.** + +Modal rules (from the overlay-close fix, commit d8fe0a4): + +- A modal holding typed input must NOT close on overlay click or Escape. Losing a part-filled form to a stray click is not an acceptable failure. +- A confirmation dialog MAY close on overlay click (`@click.self`), since it holds nothing to lose. +- The panel background is `var(--bg-card-solid)`, never `var(--bg-card)`: the card variable is translucent in dark mode, which leaves a dialog see-through over the overlay. The shared `.modal` in `style.css` already does this; hand-rolled `.modal-panel` rules must too. + ## Component Organization - **Global styles**: `src/assets/style.css` diff --git a/plugins/computers/frontend/views/AccessProtocolsList.vue b/plugins/computers/frontend/views/AccessProtocolsList.vue index 1682de5..016b967 100644 --- a/plugins/computers/frontend/views/AccessProtocolsList.vue +++ b/plugins/computers/frontend/views/AccessProtocolsList.vue @@ -192,7 +192,9 @@ onMounted(load) z-index: 1000; } .modal-panel { - background: var(--bg-card); + /* Solid: var(--bg-card) is translucent in dark mode, which made this + dialog see-through. */ + background: var(--bg-card-solid); color: var(--text); border: 1px solid var(--border); border-radius: 10px;