Give cards the surface look of the PM app

Cards had a 3px petrol bar on the top edge, and Bootstrap's shadow-sm
class overrode their own shadow with !important. They now use the PM app
surface: a 1px border all around, a 16px radius and a soft diffuse shadow
with a faint inner highlight, with a stronger shadow and a weaker highlight
in dark mode. The shadow-sm classes are removed from the cards so the
shared rule applies. Menus, drawers and dialogs keep their shadows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Grovy311 2026-09-26 12:20:09 +02:00
parent 2e3e85a8e5
commit 51cbab1750
5 changed files with 30 additions and 12 deletions

View file

@ -171,6 +171,10 @@ Support Ctrl+Plus and Ctrl+Shift+Plus for insertion.
Bootstrap may be used for the general application UI, such as navigation, page layout, buttons, forms, cards, alerts and modals.
Cards follow the PM app look: 1px border all around, 16px radius and the
soft shadow defined on `.card` in `globals.css` (own dark-mode value). Do
not add Bootstrap `shadow-*` classes or a colored top border to cards.
Do not use Bootstrap as the core table/grid framework for the circuit list editor.
The circuit list editor must remain a custom spreadsheet-like component with controlled cell selection, inline edit mode, row grouping, drag-and-drop indicators and keyboard behavior.

View file

@ -431,12 +431,26 @@ a.kpi:hover {
color: var(--color-accent-pale);
}
/* Flächen-Look wie in der PM-App (Vorbild grow-monitor): gleichmäßiger
1-px-Rahmen statt farbigem Balken an der Oberkante, größerer Radius und ein
weicher Streuschatten mit feiner heller Innenkante oben. Der Akzent kommt
über Kopfzeile und Inhalt, nicht über die Kante. Karten tragen deshalb keine
Bootstrap-Klasse shadow-*, die den Schatten mit !important überschreiben
würde. */
.card {
border-radius: var(--radius);
border-top: 3px solid var(--color-primary);
--bs-card-border-radius: 16px;
--bs-card-border-color: var(--color-border);
box-shadow:
0 1px 2px var(--shadow-soft),
0 10px 24px -14px var(--shadow-strong);
0 4px 24px var(--shadow-soft),
0 1px 0 rgba(255, 255, 255, 0.7) inset;
}
/* Auf dunklem Grund ein kräftigerer Streuschatten und nur eine schwache
Innenkante, sonst wirkt sie wie ein harter weißer Strich. */
:root[data-bs-theme="dark"] .card {
box-shadow:
0 4px 24px rgba(0, 0, 0, 0.4),
0 1px 0 rgba(255, 255, 255, 0.05) inset;
}
.card-header {

View file

@ -904,7 +904,7 @@ export default function ProjectDetailPage() {
) : null}
<section className="col-12" id="verteilungen">
<div className="card shadow-sm">
<div className="card">
<div className="card-header d-flex justify-content-between align-items-center">
<div>
<span>Verteilungen</span>
@ -997,7 +997,7 @@ export default function ProjectDetailPage() {
</section>
<section className="col-12 col-lg-5" id="etagen">
<div className="card shadow-sm h-100">
<div className="card h-100">
<div className="card-header d-flex justify-content-between align-items-center">
<div>
<span>Etagen</span>
@ -1028,7 +1028,7 @@ export default function ProjectDetailPage() {
</section>
<section className="col-12 col-lg-7" id="raeume">
<div className="card shadow-sm">
<div className="card">
<div className="card-header d-flex justify-content-between align-items-center">
<div>
<span>Räume</span>
@ -1079,7 +1079,7 @@ export default function ProjectDetailPage() {
</section>
</div>
<section className="card shadow-sm mt-4" id="projektgeraete">
<section className="card mt-4" id="projektgeraete">
<div className="card-header d-flex flex-wrap justify-content-between align-items-center gap-2">
<div>
<span>Projektgeräte</span>

View file

@ -238,7 +238,7 @@ export default function ProjectsPage() {
{error ? <div className="alert alert-warning">{error}</div> : null}
<div className="d-flex flex-column gap-4">
<section className="card shadow-sm">
<section className="card">
<div className="card-header">Neues Projekt</div>
<div className="card-body" style={{ maxWidth: 480 }}>
<form className="vstack gap-3" onSubmit={handleCreateProject}>
@ -271,7 +271,7 @@ export default function ProjectsPage() {
</div>
</section>
<section className="card shadow-sm">
<section className="card">
<div className="card-header">Projekt importieren</div>
<div className="card-body" style={{ maxWidth: 480 }}>
<p className="text-secondary small">
@ -326,7 +326,7 @@ export default function ProjectsPage() {
</div>
</section>
<section className="card shadow-sm">
<section className="card">
<div className="card-header">Globale Geräte / Verbraucher</div>
<div className="card-body border-bottom">
<form className="row g-2" onSubmit={handleCreateGlobalDevice}>

View file

@ -227,7 +227,7 @@ export function ProjectVersionHistory({
history?.currentRevision === currentRevision;
return (
<section className="card shadow-sm">
<section className="card">
<div className="card-header d-flex flex-wrap justify-content-between align-items-center gap-2">
<span>Versionen und Sicherungspunkte</span>
<div className="d-flex align-items-center gap-2">