Implements the plan from the carpenter walkthrough audit: make the project flow -> final review -> PDF path measurable and safe to gate CI on. - projectHydrationService loads a project's geometry/labor/materials/ rentals/packages/calculation in parallel and reports per-resource timing plus the slowest resource, so hydration SLA breaches are visible instead of silent - projectReadiness centralizes the blocking checks final review must pass before a quote can be sent (name, customer, description, materials/labor present, zero-price lines) - pdfSourceSignature detects when a generated PDF is stale relative to the current project data, so a carpenter doesn't send an outdated quote - MaterialLinkReview + new customer-projects match-preview/link endpoints let a user review and confirm suggested master-material matches instead of silently auto-linking - ProjectFlow refactored around the new hydration/readiness utilities; FinalReview surfaces readiness checks and unlinked material counts - CI: the carpenter smoke test (full-roof-quote-flow.spec.js) is now a blocking gate on main, with the rest of the Playwright suite running best-effort alongside it - docs/qa/CARPENTER_WALKTHROUGH_RELEASE_GATE.md documents the gate and the monthly production audit procedure Co-Authored-By: Claude Sonnet 5 <[email protected]>
1318 lines
25 KiB
CSS
1318 lines
25 KiB
CSS
/* FinalReview.css */
|
|
.final-review {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
background: #f8f9fa;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.review-header {
|
|
text-align: center;
|
|
margin-bottom: 30px;
|
|
padding: 25px;
|
|
background: linear-gradient(135deg, #6f42c1, #5a32a3);
|
|
color: white;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.review-header h2 {
|
|
margin: 0 0 10px 0;
|
|
font-size: 2rem;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.review-header p {
|
|
margin: 0;
|
|
font-size: 1.1rem;
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.quote-readiness-banner {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 20px;
|
|
margin: -12px 0 24px;
|
|
padding: 18px 20px;
|
|
border: 2px solid;
|
|
border-radius: 12px;
|
|
background: #fff;
|
|
}
|
|
|
|
.quote-readiness-banner.blocked {
|
|
border-color: #dc2626;
|
|
background: #fef2f2;
|
|
color: #7f1d1d;
|
|
}
|
|
|
|
.quote-readiness-banner.pending {
|
|
border-color: #d97706;
|
|
background: #fffbeb;
|
|
color: #78350f;
|
|
}
|
|
|
|
.quote-readiness-banner.ready {
|
|
border-color: #16a34a;
|
|
background: #f0fdf4;
|
|
color: #14532d;
|
|
}
|
|
|
|
.quote-readiness-banner strong,
|
|
.quote-readiness-kicker {
|
|
display: block;
|
|
}
|
|
|
|
.quote-readiness-kicker {
|
|
margin-bottom: 4px;
|
|
font-size: 0.72rem;
|
|
font-weight: 800;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.quote-readiness-banner strong {
|
|
font-size: 1.08rem;
|
|
}
|
|
|
|
.quote-readiness-banner p {
|
|
margin: 5px 0 0;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.quote-readiness-banner button {
|
|
min-width: 112px;
|
|
min-height: 44px;
|
|
border: 0;
|
|
border-radius: 8px;
|
|
background: #132238;
|
|
color: #fff;
|
|
cursor: pointer;
|
|
font-weight: 800;
|
|
}
|
|
|
|
@media (max-width: 640px) {
|
|
.quote-readiness-banner {
|
|
align-items: stretch;
|
|
flex-direction: column;
|
|
}
|
|
}
|
|
|
|
.review-sections {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 25px;
|
|
}
|
|
|
|
.review-section {
|
|
background: white;
|
|
border-radius: 12px;
|
|
padding: 25px;
|
|
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
|
|
border: 1px solid #e0e0e0;
|
|
}
|
|
|
|
.review-section h3 {
|
|
margin: 0 0 20px 0;
|
|
font-size: 1.3rem;
|
|
color: #2c5530;
|
|
font-weight: 600;
|
|
border-bottom: 2px solid #f0f0f0;
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
.project-ai-validation {
|
|
border: 1px solid #b9c2cc;
|
|
border-left: 4px solid #365f73;
|
|
padding: 16px;
|
|
margin-bottom: 16px;
|
|
background: #f7f9fa;
|
|
}
|
|
|
|
.project-ai-validation-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 16px;
|
|
}
|
|
|
|
.project-ai-validation-header p,
|
|
.project-ai-result p {
|
|
margin: 4px 0 0;
|
|
color: #4b5563;
|
|
}
|
|
|
|
.project-ai-progress {
|
|
display: grid;
|
|
gap: 8px;
|
|
margin-top: 14px;
|
|
color: #374151;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.project-ai-progress-bar {
|
|
height: 6px;
|
|
overflow: hidden;
|
|
background: #dbe1e5;
|
|
}
|
|
|
|
.project-ai-progress-bar span {
|
|
display: block;
|
|
width: 35%;
|
|
height: 100%;
|
|
background: #365f73;
|
|
animation: project-ai-progress 1.4s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes project-ai-progress {
|
|
from { transform: translateX(-100%); }
|
|
to { transform: translateX(300%); }
|
|
}
|
|
|
|
.project-ai-message,
|
|
.project-ai-result {
|
|
margin-top: 14px;
|
|
padding: 12px;
|
|
border: 1px solid #cbd5e1;
|
|
background: #fff;
|
|
}
|
|
|
|
.project-ai-message.error { border-color: #dc2626; color: #991b1b; }
|
|
.project-ai-message.warning,
|
|
.project-ai-result.warnings { border-color: #d97706; color: #78350f; }
|
|
.project-ai-result.passed { border-color: #16803c; color: #14532d; }
|
|
.project-ai-result ul { margin: 10px 0 0; padding-left: 20px; }
|
|
.project-ai-result li + li { margin-top: 8px; }
|
|
|
|
@media (max-width: 640px) {
|
|
.project-ai-validation-header { align-items: stretch; flex-direction: column; }
|
|
}
|
|
|
|
/* Project Info */
|
|
.project-info {
|
|
border-left: 4px solid #17a2b8;
|
|
}
|
|
|
|
.info-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
gap: 15px;
|
|
}
|
|
|
|
.info-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 5px;
|
|
}
|
|
|
|
.info-item label {
|
|
font-weight: 600;
|
|
color: #555;
|
|
font-size: 0.9rem;
|
|
}
|
|
|
|
.info-item span {
|
|
font-size: 1rem;
|
|
color: #333;
|
|
}
|
|
|
|
/* Geometry Info */
|
|
.geometry-info {
|
|
border-left: 4px solid #28a745;
|
|
}
|
|
|
|
.geometry-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
gap: 15px;
|
|
}
|
|
|
|
.geo-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 5px;
|
|
text-align: center;
|
|
padding: 10px;
|
|
background: #f8f9fa;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
.geo-item.total-area {
|
|
background: linear-gradient(135deg, #e8f5e8, #f0f8f0);
|
|
border: 1px solid #28a745;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.geo-item label {
|
|
font-size: 0.85rem;
|
|
color: #666;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.geo-item span {
|
|
font-size: 1.1rem;
|
|
font-weight: 600;
|
|
color: #2c5530;
|
|
}
|
|
|
|
/* Materials Review */
|
|
.materials-review {
|
|
border-left: 4px solid #4a90e2;
|
|
}
|
|
|
|
/* Excel-style table - RIGTIG TABLE ELEMENT MED FASTE KOLONNER */
|
|
.materials-table, .labor-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
table-layout: fixed;
|
|
font-family: "Calibri", "Segoe UI", system-ui, sans-serif;
|
|
font-size: 14px;
|
|
background: white;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.08);
|
|
border: 1px solid #c0c0c0;
|
|
}
|
|
|
|
.materials-table th,
|
|
.materials-table td,
|
|
.labor-table th,
|
|
.labor-table td {
|
|
border: 1px solid #d0d0d0;
|
|
padding: 6px 10px;
|
|
vertical-align: middle;
|
|
overflow: hidden;
|
|
text-overflow: clip;
|
|
white-space: normal;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.materials-table thead th,
|
|
.labor-table thead th {
|
|
background-color: #f2f2f2;
|
|
font-weight: 600;
|
|
text-align: center;
|
|
font-size: 13px;
|
|
letter-spacing: 0.3px;
|
|
padding: 10px 8px;
|
|
}
|
|
|
|
.materials-table .text-left {
|
|
text-align: left;
|
|
padding-left: 12px;
|
|
}
|
|
|
|
.materials-table .text-center,
|
|
.labor-table .text-center {
|
|
text-align: center;
|
|
}
|
|
|
|
.materials-table .text-right,
|
|
.labor-table .text-right {
|
|
text-align: right;
|
|
padding-right: 12px;
|
|
}
|
|
|
|
.materials-table .number-cell,
|
|
.labor-table .number-cell {
|
|
text-align: right;
|
|
font-variant-numeric: tabular-nums;
|
|
padding-right: 12px;
|
|
}
|
|
|
|
.materials-table tbody tr:nth-child(even),
|
|
.labor-table tbody tr:nth-child(even) {
|
|
background-color: #fafafa;
|
|
}
|
|
|
|
.materials-table tbody tr:hover,
|
|
.labor-table tbody tr:hover {
|
|
background-color: #f0f8ff;
|
|
}
|
|
|
|
.materials-table tfoot td,
|
|
.labor-table tfoot td {
|
|
background: linear-gradient(180deg, #e0e0e0 0%, #d0d0d0 100%);
|
|
font-weight: 700;
|
|
border-top: 2px solid #808080;
|
|
padding: 12px 10px;
|
|
}
|
|
|
|
/* Gammel grid-baseret styling (behold for bagudkompatibilitet hvis nødvendigt) */
|
|
.table-header {
|
|
display: grid;
|
|
grid-template-columns: minmax(240px, 2fr) minmax(90px, 0.8fr) minmax(70px, 0.6fr) minmax(120px, 0.9fr) minmax(140px, 1fr);
|
|
background: linear-gradient(180deg, #f8f8f8 0%, #e8e8e8 100%);
|
|
border-bottom: 2px solid #808080;
|
|
}
|
|
|
|
.table-header span {
|
|
padding: 12px 8px;
|
|
font-weight: 700;
|
|
color: #000;
|
|
text-align: center;
|
|
border-right: 1px solid #c0c0c0;
|
|
font-size: 11pt;
|
|
letter-spacing: 0.3px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.table-header span:first-child {
|
|
text-align: left;
|
|
padding-left: 12px;
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.table-header span:last-child {
|
|
border-right: none;
|
|
text-align: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.labor-table .table-header {
|
|
grid-template-columns: minmax(240px, 2fr) minmax(110px, 0.9fr) minmax(110px, 0.9fr) minmax(140px, 1fr);
|
|
}
|
|
|
|
.table-row {
|
|
display: grid;
|
|
grid-template-columns: minmax(240px, 2fr) minmax(90px, 0.8fr) minmax(70px, 0.6fr) minmax(120px, 0.9fr) minmax(140px, 1fr);
|
|
border-bottom: 1px solid #d4d4d4;
|
|
background: white !important;
|
|
transition: background-color 0.1s;
|
|
align-items: center;
|
|
}
|
|
|
|
.table-row:nth-child(even) {
|
|
background: #fafafa !important;
|
|
}
|
|
|
|
.table-row:hover {
|
|
background: #f0f8ff !important;
|
|
}
|
|
|
|
.table-row > span,
|
|
.table-row > input {
|
|
padding: 10px 8px;
|
|
border-right: 1px solid #e0e0e0;
|
|
text-align: center;
|
|
font-size: 10.5pt;
|
|
line-height: 1.3;
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: center;
|
|
min-width: 0;
|
|
}
|
|
|
|
.table-row > span:first-child,
|
|
.table-row > .material-name {
|
|
text-align: left;
|
|
padding-left: 12px;
|
|
font-weight: 500;
|
|
color: #1a1a1a;
|
|
border-right: 1px solid #c0c0c0;
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.table-row > span:last-child {
|
|
border-right: none;
|
|
text-align: center;
|
|
font-weight: 600;
|
|
justify-content: center;
|
|
}
|
|
|
|
.table-row > input {
|
|
background: white !important;
|
|
border: none !important;
|
|
border-right: 1px solid #e0e0e0 !important;
|
|
text-align: center;
|
|
padding: 10px 8px !important;
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
font-size: 10.5pt;
|
|
color: #000;
|
|
}
|
|
|
|
.table-row > input:focus {
|
|
outline: 2px solid #2e75b6 !important;
|
|
outline-offset: -2px;
|
|
background: #fff8e1 !important;
|
|
box-shadow: none !important;
|
|
}
|
|
|
|
.labor-table .table-row {
|
|
grid-template-columns: minmax(240px, 2fr) minmax(110px, 0.9fr) minmax(110px, 0.9fr) minmax(140px, 1fr);
|
|
}
|
|
|
|
.material-name,
|
|
.task-info {
|
|
white-space: normal;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.pdf-inline-preview {
|
|
margin-top: 14px;
|
|
border: 1px solid #cbd5e1;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
background: #fff;
|
|
}
|
|
|
|
.pdf-preview-frame {
|
|
width: 100%;
|
|
min-height: 560px;
|
|
border: 0;
|
|
background: #fff;
|
|
}
|
|
|
|
/* Fjern browser autofill gul baggrund - ULTRA AGGRESSIV */
|
|
.editable-input,
|
|
.quantity-input,
|
|
.price-input,
|
|
input[type="number"],
|
|
.table-row input {
|
|
background-color: white !important;
|
|
background-image: none !important;
|
|
background: white !important;
|
|
-webkit-appearance: none;
|
|
-moz-appearance: textfield;
|
|
appearance: none;
|
|
}
|
|
|
|
.editable-input:-webkit-autofill,
|
|
.editable-input:-webkit-autofill:hover,
|
|
.editable-input:-webkit-autofill:focus,
|
|
.editable-input:-webkit-autofill:active,
|
|
.quantity-input:-webkit-autofill,
|
|
.price-input:-webkit-autofill,
|
|
input[type="number"]:-webkit-autofill,
|
|
.table-row input:-webkit-autofill {
|
|
-webkit-box-shadow: 0 0 0 1000px white inset !important;
|
|
box-shadow: 0 0 0 1000px white inset !important;
|
|
background-color: white !important;
|
|
background: white !important;
|
|
background-image: none !important;
|
|
-webkit-text-fill-color: #000 !important;
|
|
transition: background-color 5000s ease-in-out 0s;
|
|
caret-color: #000 !important;
|
|
color: #000 !important;
|
|
}
|
|
|
|
.materials-table input,
|
|
.materials-table input:-webkit-autofill,
|
|
.labor-table input,
|
|
.labor-table input:-webkit-autofill {
|
|
-webkit-box-shadow: 0 0 0 1000px white inset !important;
|
|
background: white !important;
|
|
background-color: white !important;
|
|
-webkit-text-fill-color: #000 !important;
|
|
}
|
|
|
|
.material-name {
|
|
font-weight: 500;
|
|
color: #1a1a1a;
|
|
text-align: left;
|
|
padding-left: 12px !important;
|
|
border-right: 1px solid #c0c0c0 !important;
|
|
background: transparent !important;
|
|
}
|
|
|
|
.total {
|
|
font-weight: 700;
|
|
color: #000;
|
|
text-align: right;
|
|
padding-right: 16px !important;
|
|
}
|
|
|
|
.table-total {
|
|
display: grid;
|
|
grid-template-columns: 2fr 0.8fr 0.6fr 0.9fr 1fr;
|
|
padding: 12px 0;
|
|
background: linear-gradient(180deg, #e0e0e0 0%, #d0d0d0 100%);
|
|
border-top: 2px solid #808080;
|
|
border-bottom: 1px solid #808080;
|
|
font-weight: 700;
|
|
font-size: 11pt;
|
|
align-items: center;
|
|
}
|
|
|
|
.table-total span:first-child {
|
|
grid-column: 1 / 5;
|
|
text-align: right;
|
|
padding-right: 12px;
|
|
font-weight: 700;
|
|
color: #000;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.table-total span:last-child {
|
|
text-align: center;
|
|
font-weight: 700;
|
|
color: #000;
|
|
font-size: 11.5pt;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.labor-table .table-total {
|
|
grid-template-columns: 2fr 0.9fr 0.9fr 1fr;
|
|
}
|
|
|
|
.labor-table .table-total span:first-child {
|
|
grid-column: 1 / 4;
|
|
}
|
|
|
|
.total-amount {
|
|
color: #000;
|
|
font-size: 11.5pt;
|
|
font-weight: 700;
|
|
text-align: right;
|
|
padding-right: 16px;
|
|
}
|
|
|
|
/* Editable inputs - Excel style med table support */
|
|
.editable-input,
|
|
.materials-table input,
|
|
.labor-table input {
|
|
width: 100%;
|
|
padding: 6px 10px;
|
|
border: none;
|
|
border-radius: 0;
|
|
font-size: 14px;
|
|
font-family: "Calibri", "Segoe UI", system-ui, sans-serif;
|
|
background: white !important;
|
|
text-align: right;
|
|
box-sizing: border-box;
|
|
color: #000;
|
|
-webkit-appearance: none;
|
|
-moz-appearance: textfield;
|
|
appearance: none;
|
|
}
|
|
|
|
.editable-input:focus,
|
|
.materials-table input:focus,
|
|
.labor-table input:focus {
|
|
outline: 2px solid #2e75b6 !important;
|
|
outline-offset: -2px;
|
|
background: #fff8e1 !important;
|
|
box-shadow: none;
|
|
}
|
|
|
|
.total-amount {
|
|
color: #27ae60;
|
|
font-size: 1.2rem;
|
|
font-weight: 700;
|
|
}
|
|
|
|
/* Labor Review */
|
|
.labor-review {
|
|
border-left: 4px solid #fd7e14;
|
|
}
|
|
|
|
/* Financial Summary */
|
|
.financial-summary {
|
|
border-left: 4px solid #6f42c1;
|
|
}
|
|
|
|
.financial-breakdown {
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
}
|
|
|
|
.financial-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 8px 0;
|
|
font-size: 1rem;
|
|
}
|
|
|
|
.financial-row.subtotal {
|
|
border-top: 1px solid #ddd;
|
|
border-bottom: 1px solid #ddd;
|
|
margin: 10px 0;
|
|
padding: 12px 0;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.financial-row.total {
|
|
border-top: 2px solid #6f42c1;
|
|
margin-top: 15px;
|
|
padding-top: 15px;
|
|
font-size: 1.2rem;
|
|
color: #6f42c1;
|
|
}
|
|
|
|
/* Ordering Section */
|
|
.ordering-section {
|
|
border-left: 4px solid #dc3545;
|
|
}
|
|
|
|
.ordering-info p {
|
|
margin-bottom: 15px;
|
|
line-height: 1.5;
|
|
color: #555;
|
|
}
|
|
|
|
.details-toggle {
|
|
background: none;
|
|
border: none;
|
|
color: #6f42c1;
|
|
cursor: pointer;
|
|
font-size: 0.9rem;
|
|
padding: 5px 0;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.ordering-details {
|
|
margin-top: 15px;
|
|
padding: 15px;
|
|
background: #f8f9fa;
|
|
border-radius: 6px;
|
|
border-left: 3px solid #6f42c1;
|
|
}
|
|
|
|
.ordering-details h4 {
|
|
margin: 0 0 10px 0;
|
|
color: #6f42c1;
|
|
}
|
|
|
|
.ordering-details ul {
|
|
margin: 0;
|
|
padding-left: 20px;
|
|
}
|
|
|
|
.ordering-details li {
|
|
margin-bottom: 5px;
|
|
color: #555;
|
|
}
|
|
|
|
/* Submit Result */
|
|
.submit-result {
|
|
margin-top: 20px;
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
border-left: 4px solid;
|
|
}
|
|
|
|
.submit-result.success {
|
|
background: #d4edda;
|
|
border-color: #28a745;
|
|
color: #155724;
|
|
}
|
|
|
|
.submit-result.error {
|
|
background: #f8d7da;
|
|
border-color: #dc3545;
|
|
color: #721c24;
|
|
}
|
|
|
|
.submit-result h4 {
|
|
margin: 0 0 8px 0;
|
|
}
|
|
|
|
.submit-result p {
|
|
margin: 0;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
/* No Data */
|
|
.no-data {
|
|
text-align: center;
|
|
padding: 40px;
|
|
color: #666;
|
|
font-style: italic;
|
|
}
|
|
|
|
/* Review Actions */
|
|
.review-actions {
|
|
display: flex;
|
|
gap: 20px;
|
|
justify-content: center;
|
|
margin-top: 30px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.final-review .back-btn, .final-review .submit-btn {
|
|
padding: 15px 30px;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 1.1rem;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
min-width: 200px;
|
|
}
|
|
|
|
.final-review .back-btn {
|
|
background: #6c757d;
|
|
color: white;
|
|
}
|
|
|
|
.final-review .back-btn:hover:not(:disabled) {
|
|
background: #5a6268;
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.final-review .submit-btn {
|
|
background: linear-gradient(135deg, #28a745, #218838);
|
|
color: white;
|
|
}
|
|
|
|
.final-review .submit-btn:hover:not(:disabled) {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 15px rgba(40, 167, 69, 0.4);
|
|
}
|
|
|
|
.final-review .submit-btn:disabled, .final-review .back-btn:disabled {
|
|
background: #6c757d;
|
|
cursor: not-allowed;
|
|
opacity: 0.6;
|
|
transform: none;
|
|
}
|
|
|
|
/* Responsive Design */
|
|
@media (max-width: 768px) {
|
|
.final-review {
|
|
padding: 15px;
|
|
}
|
|
|
|
.review-header h2 {
|
|
font-size: 1.5rem;
|
|
}
|
|
|
|
.table-header, .table-row {
|
|
grid-template-columns: 1fr;
|
|
text-align: left;
|
|
}
|
|
|
|
.table-header {
|
|
display: none;
|
|
}
|
|
|
|
.table-row {
|
|
display: block;
|
|
padding: 15px;
|
|
border: 1px solid #e0e0e0;
|
|
margin-bottom: 10px;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
.table-row > span {
|
|
display: block;
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.table-row > span:before {
|
|
content: attr(data-label) ': ';
|
|
font-weight: 600;
|
|
color: #555;
|
|
}
|
|
|
|
.info-grid, .geometry-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.review-actions {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.final-review .back-btn, .final-review .submit-btn {
|
|
min-width: auto;
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
/* Animation */
|
|
@keyframes slideIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.review-section {
|
|
animation: slideIn 0.6s ease-out;
|
|
}
|
|
|
|
.table-row {
|
|
animation: slideIn 0.3s ease-out;
|
|
}
|
|
/* Tilbudstekst Section */
|
|
.quote-text-section {
|
|
background: linear-gradient(135deg, #f8f9fa, #e9ecef);
|
|
}
|
|
|
|
.quote-generation-controls {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 15px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.quote-type-selector {
|
|
display: flex;
|
|
gap: 20px;
|
|
padding: 15px;
|
|
background: white;
|
|
border-radius: 8px;
|
|
border: 2px solid #dee2e6;
|
|
}
|
|
|
|
.quote-type-selector label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
cursor: pointer;
|
|
padding: 8px 15px;
|
|
border-radius: 6px;
|
|
transition: background 0.3s;
|
|
}
|
|
|
|
.quote-type-selector label:hover {
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.quote-type-selector input[type="radio"] {
|
|
width: 18px;
|
|
height: 18px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.quote-type-selector span {
|
|
font-size: 15px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.ai-instructions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.ai-instructions label {
|
|
font-weight: 600;
|
|
color: #495057;
|
|
}
|
|
|
|
.ai-instructions textarea {
|
|
padding: 12px;
|
|
border: 2px solid #dee2e6;
|
|
border-radius: 8px;
|
|
font-size: 14px;
|
|
font-family: inherit;
|
|
resize: vertical;
|
|
transition: border-color 0.3s;
|
|
}
|
|
|
|
.ai-instructions textarea:focus {
|
|
outline: none;
|
|
border-color: #6f42c1;
|
|
}
|
|
|
|
.generate-quote-btn {
|
|
padding: 14px 24px;
|
|
background: linear-gradient(135deg, #6f42c1, #5a32a3);
|
|
color: white;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.generate-quote-btn:hover:not(:disabled) {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(111, 66, 193, 0.3);
|
|
}
|
|
|
|
.generate-quote-btn:disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.quote-editor {
|
|
margin-top: 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 15px;
|
|
}
|
|
|
|
.quote-editor label {
|
|
font-weight: 600;
|
|
color: #495057;
|
|
font-size: 15px;
|
|
}
|
|
|
|
.quote-textarea {
|
|
width: 100%;
|
|
padding: 15px;
|
|
border: 2px solid #dee2e6;
|
|
border-radius: 8px;
|
|
font-size: 14px;
|
|
font-family: 'Courier New', monospace;
|
|
line-height: 1.6;
|
|
resize: vertical;
|
|
transition: border-color 0.3s;
|
|
}
|
|
|
|
.quote-textarea:focus {
|
|
outline: none;
|
|
border-color: #6f42c1;
|
|
}
|
|
|
|
.quote-actions {
|
|
display: flex;
|
|
gap: 15px;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.pdf-status {
|
|
margin-top: 10px;
|
|
font-size: 13px;
|
|
padding: 10px 12px;
|
|
border-radius: 8px;
|
|
border: 1px solid #dee2e6;
|
|
}
|
|
|
|
.pdf-status.fresh {
|
|
background: #e8f5e9;
|
|
border-color: #a5d6a7;
|
|
color: #1b5e20;
|
|
}
|
|
|
|
.pdf-status.stale {
|
|
background: #fff8e1;
|
|
border-color: #ffe082;
|
|
color: #7c4d00;
|
|
}
|
|
|
|
.generate-pdf-btn {
|
|
padding: 12px 24px;
|
|
background: linear-gradient(135deg, #28a745, #218838);
|
|
color: white;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.generate-pdf-btn:hover:not(:disabled) {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(40, 167, 69, 0.3);
|
|
}
|
|
|
|
.generate-pdf-btn:disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.view-pdf-btn {
|
|
padding: 12px 24px;
|
|
background: #17a2b8;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.view-pdf-btn:hover {
|
|
background: #138496;
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(23, 162, 184, 0.3);
|
|
}
|
|
|
|
.download-pdf-btn {
|
|
padding: 12px 24px;
|
|
background: #495057;
|
|
color: white;
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.download-pdf-btn:hover {
|
|
background: #343a40;
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(73, 80, 87, 0.3);
|
|
}
|
|
|
|
.quote-preview-card {
|
|
border: 1px solid #ced4da;
|
|
border-radius: 10px;
|
|
background: #ffffff;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.quote-preview-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 12px 16px;
|
|
border-bottom: 1px solid #e9ecef;
|
|
background: linear-gradient(90deg, #f8f9fa, #ffffff);
|
|
}
|
|
|
|
.quote-preview-header h4 {
|
|
margin: 0;
|
|
font-size: 15px;
|
|
color: #212529;
|
|
}
|
|
|
|
.quote-preview-header span {
|
|
font-size: 12px;
|
|
color: #6c757d;
|
|
}
|
|
|
|
.quote-preview-body {
|
|
padding: 18px 20px;
|
|
background: #fffefb;
|
|
font-family: Georgia, 'Times New Roman', serif;
|
|
line-height: 1.55;
|
|
color: #212529;
|
|
border-left: 4px solid #6f42c1;
|
|
}
|
|
|
|
.quote-preview-body p {
|
|
margin: 0 0 8px 0;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
/* Legacy link style - kept for backwards compatibility */
|
|
.view-pdf-link {
|
|
padding: 12px 24px;
|
|
background: #17a2b8;
|
|
color: white;
|
|
text-decoration: none;
|
|
border-radius: 8px;
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
transition: all 0.3s;
|
|
display: inline-block;
|
|
}
|
|
|
|
.view-pdf-link:hover {
|
|
background: #138496;
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(23, 162, 184, 0.3);
|
|
}
|
|
|
|
.quote-hint {
|
|
padding: 20px;
|
|
background: #fff3cd;
|
|
border: 2px dashed #ffc107;
|
|
border-radius: 8px;
|
|
color: #856404;
|
|
text-align: center;
|
|
font-style: italic;
|
|
margin-top: 15px;
|
|
}
|
|
|
|
/* Editable inputs for prices and hours */
|
|
.editable-table .editable-row {
|
|
align-items: center;
|
|
background: white !important;
|
|
}
|
|
|
|
.editable-table .table-row {
|
|
background: white !important;
|
|
}
|
|
|
|
.editable-input {
|
|
padding: 8px 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 0;
|
|
font-size: 14px;
|
|
font-weight: 400;
|
|
transition: all 0.2s;
|
|
background: white !important;
|
|
width: 80px;
|
|
text-align: center;
|
|
}
|
|
|
|
.editable-input:focus {
|
|
outline: none;
|
|
border-color: #4a90e2;
|
|
background: white !important;
|
|
box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.1);
|
|
}
|
|
|
|
/* Fjern browser autofill gul baggrund - ULTRA AGGRESSIV */
|
|
.editable-input,
|
|
.quantity-input,
|
|
.price-input,
|
|
input[type="number"],
|
|
.table-row input {
|
|
background-color: white !important;
|
|
background-image: none !important;
|
|
background: white !important;
|
|
}
|
|
|
|
.editable-input:-webkit-autofill,
|
|
.editable-input:-webkit-autofill:hover,
|
|
.editable-input:-webkit-autofill:focus,
|
|
.editable-input:-webkit-autofill:active,
|
|
.quantity-input:-webkit-autofill,
|
|
.price-input:-webkit-autofill,
|
|
input[type="number"]:-webkit-autofill,
|
|
.table-row input:-webkit-autofill {
|
|
-webkit-box-shadow: 0 0 0 1000px white inset !important;
|
|
box-shadow: 0 0 0 1000px white inset !important;
|
|
background-color: white !important;
|
|
background: white !important;
|
|
background-image: none !important;
|
|
-webkit-text-fill-color: #000 !important;
|
|
transition: background-color 5000s ease-in-out 0s;
|
|
caret-color: #000 !important;
|
|
color: #000 !important;
|
|
}
|
|
|
|
/* Fjern gul highlighting for alle input felter i tabellen */
|
|
.editable-table input,
|
|
.editable-table input:-webkit-autofill,
|
|
.editable-table input:-webkit-autofill:hover,
|
|
.editable-table input:-webkit-autofill:focus,
|
|
.materials-table input,
|
|
.materials-table input:-webkit-autofill,
|
|
.labor-table input,
|
|
.labor-table input:-webkit-autofill {
|
|
-webkit-box-shadow: 0 0 0 1000px white inset !important;
|
|
box-shadow: 0 0 0 1000px white inset !important;
|
|
background-color: white !important;
|
|
background: white !important;
|
|
background-image: none !important;
|
|
-webkit-text-fill-color: #000 !important;
|
|
color: #000 !important;
|
|
}
|
|
|
|
/* Force white background på alle table rows */
|
|
.editable-table .table-row,
|
|
.editable-table .editable-row,
|
|
.materials-table .table-row,
|
|
.labor-table .table-row {
|
|
background: white !important;
|
|
background-color: white !important;
|
|
background-image: none !important;
|
|
}
|
|
|
|
/* Ekstra aggressiv - target alle inputs */
|
|
input[type="number"].editable-input {
|
|
background-color: white !important;
|
|
background: white !important;
|
|
background-image: none !important;
|
|
}
|
|
|
|
input[type="number"].editable-input:-webkit-autofill {
|
|
-webkit-box-shadow: 0 0 0 1000px white inset !important;
|
|
-webkit-text-fill-color: #000 !important;
|
|
background: white !important;
|
|
background-color: white !important;
|
|
color: #000 !important;
|
|
}
|
|
|
|
.editable-input:focus {
|
|
outline: none;
|
|
border-color: #6f42c1;
|
|
background: white !important;
|
|
box-shadow: 0 0 0 3px rgba(111, 66, 193, 0.1);
|
|
}
|
|
|
|
.editable-input.quantity-input,
|
|
.editable-input.hours-input {
|
|
width: 70px;
|
|
}
|
|
|
|
.editable-input.price-input,
|
|
.editable-input.rate-input {
|
|
width: 90px;
|
|
}
|
|
|
|
.profit-margin-row {
|
|
display: grid;
|
|
grid-template-columns: 1fr auto auto;
|
|
gap: 15px;
|
|
align-items: center;
|
|
background: #fff3cd;
|
|
padding: 12px;
|
|
border-radius: 8px;
|
|
margin: 10px 0;
|
|
}
|
|
|
|
.profit-margin-row label {
|
|
font-weight: 600;
|
|
color: #856404;
|
|
}
|
|
|
|
.profit-input {
|
|
width: 80px !important;
|
|
background: white;
|
|
}
|
|
|
|
.profit-amount {
|
|
font-weight: 600;
|
|
color: #856404;
|
|
min-width: 100px;
|
|
text-align: right;
|
|
}
|
|
.final-review .action-btn {
|
|
width: auto;
|
|
min-width: 44px;
|
|
min-height: 44px;
|
|
height: auto;
|
|
padding: 10px 14px;
|
|
white-space: normal;
|
|
text-align: center;
|
|
}
|
|
|
|
.review-readiness-summary {
|
|
margin: 10px 0 0;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.material-link-review {
|
|
margin: 16px 0;
|
|
padding: 16px;
|
|
border: 1px solid #f59e0b;
|
|
border-radius: 10px;
|
|
background: #fffbeb;
|
|
}
|
|
|
|
.material-link-review button {
|
|
min-height: 44px;
|
|
padding: 10px 14px;
|
|
}
|
|
|
|
.material-link-review-list {
|
|
display: grid;
|
|
gap: 12px;
|
|
margin-top: 14px;
|
|
}
|
|
|
|
.material-link-review-row {
|
|
padding: 12px;
|
|
border: 1px solid #fde68a;
|
|
border-radius: 8px;
|
|
background: #fff;
|
|
}
|
|
|
|
.material-link-review-row p {
|
|
margin: 8px 0;
|
|
}
|