Design consistency audit fixes: alerts, cards, dark mode, utilities

Alert sweep (113 alerts, 79 files):
  All persistent static banners now carry alert-permanent so the
  layout's 5-second auto-dismiss cannot swallow guidance, warnings,
  or validation errors. Transient dismissible toasts left untouched.

CSS fixes (site.css):
  .card.shadow-sm      — strips rogue border from ~40 drifted cards
  .card-header.bg-white — rebinds to var(--bs-body-bg) so card
                          headers follow dark/light theme correctly
  Typography utilities  — .text-2xs (.68rem), .text-xs (.73rem)
  Token color classes   — .text-ember, .text-ok, .text-bad,
                          .text-warn, .text-cool, .bg-paper-2
  Layout utilities      — .mw-xs/sm/md/lg replace inline max-width
  Comment              — documents text-ember vs text-primary intent

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-10 18:05:29 -04:00
parent f6d457fe0e
commit 328b195127
80 changed files with 603 additions and 561 deletions
@@ -1,4 +1,4 @@
@model PowderCoating.Application.DTOs.Customer.CustomerDto
@model PowderCoating.Application.DTOs.Customer.CustomerDto
@{
ViewData["Title"] = "Delete Customer";
@@ -14,7 +14,7 @@
</div>
<!-- Warning Banner -->
<div class="alert alert-danger d-flex align-items-start mb-4">
<div class="alert alert-danger alert-permanent d-flex align-items-start mb-4">
<i class="bi bi-exclamation-triangle-fill me-3" style="font-size: 1.5rem;"></i>
<div>
<h5 class="alert-heading mb-2">Are you sure you want to delete this customer?</h5>
@@ -141,7 +141,7 @@
@if (Model.CurrentBalance > 0)
{
<div class="alert alert-warning d-flex align-items-center">
<div class="alert alert-warning alert-permanent d-flex align-items-center">
<i class="bi bi-exclamation-circle me-2"></i>
<div>
<strong>Warning:</strong> This customer has an outstanding balance of @Model.CurrentBalance.ToString("C"). Please ensure all balances are settled before deletion.
@@ -1,4 +1,4 @@
@model PowderCoating.Application.DTOs.Customer.CustomerDto
@model PowderCoating.Application.DTOs.Customer.CustomerDto
@{
ViewData["Title"] = !string.IsNullOrWhiteSpace(Model.CompanyName)
@@ -123,7 +123,7 @@
}
else
{
<span class="text-muted">Not set invoices go to contact email</span>
<span class="text-muted">Not set — invoices go to contact email</span>
}
</p>
</div>
@@ -272,7 +272,7 @@
{
<div class="col-md-12">
<label class="text-muted small mb-1">Tax Exempt Certificate</label>
<div class="alert alert-success d-flex justify-content-between align-items-center mb-0 mt-2">
<div class="alert alert-success alert-permanent d-flex justify-content-between align-items-center mb-0 mt-2">
<div>
<i class="bi bi-file-earmark-check me-2"></i>
<strong>File on record:</strong> @Model.TaxExemptCertificateFileName
@@ -287,7 +287,7 @@
{
<div class="col-md-12">
<label class="text-muted small mb-1">Tax Exempt Certificate</label>
<div class="alert alert-warning mb-0 mt-2">
<div class="alert alert-warning alert-permanent mb-0 mt-2">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>No certificate on file.</strong> Please upload a tax exempt certificate to complete the record.
</div>
@@ -514,7 +514,7 @@
<div class="mb-3">
<label class="form-label fw-semibold">Reason <span class="text-danger">*</span></label>
<select name="Reason" class="form-select" required id="creditReasonSelect">
<option value=""> Select reason </option>
<option value="">— Select reason —</option>
<option value="Pre-payment / Deposit">Pre-payment / Deposit</option>
<option value="Gift / Gift Card">Gift / Gift Card</option>
<option value="Overpayment credit">Overpayment credit</option>
@@ -1,4 +1,4 @@
@model PowderCoating.Application.DTOs.Customer.UpdateCustomerDto
@model PowderCoating.Application.DTOs.Customer.UpdateCustomerDto
@{
ViewData["Title"] = "Edit Customer";
@@ -26,7 +26,7 @@
<a tabindex="0" class="help-icon" role="button"
data-bs-toggle="popover" data-bs-placement="right" data-bs-trigger="focus"
data-bs-title="Company Information"
data-bs-content="Company Name is used on quotes, invoices, and correspondence. Customer Type controls which features are available Commercial customers get payment terms, credit limits, and pricing tier discounts. Status Inactive hides the customer from new quote/job dropdowns but preserves all history.">
data-bs-content="Company Name is used on quotes, invoices, and correspondence. Customer Type controls which features are available — Commercial customers get payment terms, credit limits, and pricing tier discounts. Status Inactive hides the customer from new quote/job dropdowns but preserves all history.">
<i class="bi bi-question-circle"></i>
</a>
</div>
@@ -220,7 +220,7 @@
<a tabindex="0" class="help-icon" role="button"
data-bs-toggle="popover" data-bs-placement="right" data-bs-trigger="focus"
data-bs-title="Business Information"
data-bs-content="Payment Terms sets the default due date on invoices (e.g., Net 30 = 30 days from invoice date). Credit Limit is a soft warning cap the system alerts when exceeded. Tax Exempt removes tax from all invoices; upload the exemption certificate in the Tax Exempt Certificate section below.">
data-bs-content="Payment Terms sets the default due date on invoices (e.g., Net 30 = 30 days from invoice date). Credit Limit is a soft warning cap — the system alerts when exceeded. Tax Exempt removes tax from all invoices; upload the exemption certificate in the Tax Exempt Certificate section below.">
<i class="bi bi-question-circle"></i>
</a>
</div>
@@ -246,7 +246,7 @@
<div class="col-md-3">
<label asp-for="PricingTierId" class="form-label">Pricing Tier</label>
<select asp-for="PricingTierId" asp-items="ViewBag.PricingTiers" class="form-select">
<option value=""> No tier </option>
<option value="">— No tier —</option>
</select>
<small class="text-muted">Applies a discount to all quotes for this customer.</small>
</div>
@@ -291,7 +291,7 @@
<a tabindex="0" class="help-icon" role="button"
data-bs-toggle="popover" data-bs-placement="right" data-bs-trigger="focus"
data-bs-title="Notification Preferences"
data-bs-content="Controls when the customer receives automatic updates. Email notifications send status change alerts (e.g., job ready for pickup) to the customer's email address. SMS requires separate TCPA consent uncheck 'SMS Notifications Active' to temporarily pause without revoking consent.">
data-bs-content="Controls when the customer receives automatic updates. Email notifications send status change alerts (e.g., job ready for pickup) to the customer's email address. SMS requires separate TCPA consent — uncheck 'SMS Notifications Active' to temporarily pause without revoking consent.">
<i class="bi bi-question-circle"></i>
</a>
</div>
@@ -314,7 +314,7 @@
<div class="mt-3">
@if (Model.SmsConsentedAt.HasValue)
{
<!-- Consent already recorded show status and allow pause/resume -->
<!-- Consent already recorded — show status and allow pause/resume -->
<div class="card border-success bg-success-subtle p-3 mb-2">
<div class="d-flex align-items-start gap-3">
<i class="bi bi-shield-fill-check text-success fs-4 mt-1"></i>
@@ -339,7 +339,7 @@
}
else
{
<!-- No consent on file show the compliance notice and consent checkbox -->
<!-- No consent on file — show the compliance notice and consent checkbox -->
<div class="alert alert-warning border-warning alert-permanent" role="alert">
<h6 class="alert-heading fw-bold mb-2">
<i class="bi bi-exclamation-triangle-fill me-2"></i>SMS Consent Requirement (TCPA)
@@ -399,7 +399,7 @@
<div class="col-md-6">
@if (Model.HasTaxExemptCertificate)
{
<div class="alert alert-success d-flex justify-content-between align-items-center">
<div class="alert alert-success alert-permanent d-flex justify-content-between align-items-center">
<div>
<i class="bi bi-file-earmark-check me-2"></i>
<strong>Certificate on file:</strong> @Model.TaxExemptCertificateFileName