/** * Copyright since 2025 Mifos Initiative * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ .info-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px 16px; margin-bottom: 16px; > div { display: flex; flex-direction: column; } .k { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; color: rgb(0 0 0 / 50%); margin-bottom: 2px; } .pill { margin-left: 6px; vertical-align: middle; } } .mode-toggle { display: flex; gap: 8px; margin: 16px 0 12px; button.active { background: rgb(25 118 210 / 12%); } } .decided-summary { padding: 14px 16px; border-radius: 8px; border-left: 4px solid rgb(0 0 0 / 30%); background: rgb(0 0 0 / 4%); &.ok { border-left-color: #1a9c63; background: #e8f8f0; } &.bad { border-left-color: #d32f2f; background: #fdeaea; } } .decided-headline { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; } .compare-row { display: grid; grid-template-columns: minmax(120px, 38%) 1fr; gap: 6px 16px; padding: 4px 0; border-top: 1px solid rgb(255 255 255 / 60%); &:first-of-type { border-top: none; } } .compare-label { color: rgb(0 0 0 / 55%); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; } .compare-value { font-size: 0.85rem; word-break: break-word; } mat-form-field { width: 100%; } .section-title { margin: 20px 0 8px; font-size: 0.95rem; } .section-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; .section-title { margin: 20px 0 8px; } } .muted { color: rgb(0 0 0 / 50%); font-size: 0.82rem; margin-bottom: 8px; } .image-row { display: flex; gap: 12px; flex-wrap: wrap; } .cheque-image { max-width: 260px; max-height: 140px; object-fit: contain; border: 1px solid #ddd; border-radius: 4px; cursor: pointer; background: #fafafa; } // the overlay boxes are positioned absolute relative to THIS wrapper, not the (possibly flex-centered) // .cheque-stage — otherwise, once the stage centers the image via flexbox in fullscreen mode, the overlay's // left/top coordinates (measured from the stage's own top-left corner) land nowhere near the actual image .cheque-image-wrap { position: relative; display: inline-block; line-height: 0; transform-origin: center center; } .cheque-stage { position: relative; display: inline-block; line-height: 0; // fullscreen compare mode: the stage itself becomes a fixed, full-viewport backdrop so the cheque and // every draggable signature overlay are shown as large as possible for a real side-by-side comparison &.fullscreen-stage { position: fixed; inset: 0; z-index: 2000; display: flex; align-items: center; justify-content: center; width: 100vw; height: 100vh; max-width: none; overflow: auto; background: rgb(0 0 0 / 92%); .cheque-image { width: auto; max-width: 82vw; max-height: 88vh; cursor: zoom-in; } } // matches the native fullscreen state directly (independent of Angular's class-binding timing), so the // stage fills correctly the instant the browser promotes it to the top layer &:fullscreen { width: 100vw; height: 100vh; max-width: none; display: flex; align-items: center; justify-content: center; background: rgb(0 0 0 / 92%); } } .fullscreen-close { position: absolute; top: 16px; right: 16px; z-index: 2010; width: 36px; height: 36px; border-radius: 50%; border: none; background: rgb(255 255 255 / 15%); color: #fff; font-size: 16px; cursor: pointer; &:hover { background: rgb(255 255 255 / 25%); } } .fullscreen-zoom { position: absolute; top: 16px; left: 50%; transform: translateX(-50%); z-index: 2010; display: flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 20px; background: rgb(255 255 255 / 15%); color: #fff; font-size: 12px; span { min-width: 40px; text-align: center; font-variant-numeric: tabular-nums; } button { width: 26px; height: 26px; border-radius: 50%; border: none; background: rgb(255 255 255 / 15%); color: #fff; font-size: 14px; line-height: 1; cursor: pointer; &:hover { background: rgb(255 255 255 / 25%); } } } .fullscreen-shelf { position: absolute; top: 16px; left: 16px; z-index: 2010; display: flex; flex-direction: column; gap: 8px; max-height: 88vh; overflow-y: auto; padding-right: 4px; } .shelf-item { width: 150px; padding: 4px; border: 2px solid transparent; border-radius: 4px; background: #fff; cursor: pointer; text-align: center; &.active { border-color: #1976d2; } img { display: block; width: 100%; height: 54px; object-fit: contain; } span { display: block; margin-top: 2px; color: #333; font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } } .sig-overlay { position: absolute; // must beat the fullscreen shelf/close-button (z-index: 2010) — they share the same stacking context // (the fullscreen-stage), so a low z-index here meant the overlay silently rendered BEHIND the shelf // wherever the two visually overlapped, e.g. when dragging it toward the top-left where the shelf sits z-index: 2020; box-sizing: border-box; border: 1px dashed rgb(25 118 210 / 70%); background: rgb(255 255 255 / 40%); cursor: move; user-select: none; } .sig-overlay-handle { display: flex; align-items: center; justify-content: space-between; gap: 4px; padding: 1px 4px; background: rgb(25 118 210 / 85%); color: #fff; font-size: 10px; line-height: 1.6; cursor: move; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .sig-overlay-close { background: none; border: none; color: #fff; cursor: pointer; font-size: 11px; line-height: 1; padding: 0 2px; } .sig-overlay-img { display: block; width: 100%; height: auto; pointer-events: none; } .sig-overlay-resize { position: absolute; right: 0; bottom: 0; width: 12px; height: 12px; cursor: nwse-resize; background: repeating-linear-gradient(135deg, rgb(25 118 210 / 80%) 0 2px, transparent 2px 4px); } .sig-overlay-opacity { width: 44px; height: 10px; margin: 0 4px; cursor: pointer; } .no-image { padding: 12px; border: 1px dashed #ccc; border-radius: 4px; color: rgb(0 0 0 / 40%); font-size: 0.82rem; &.small { padding: 6px 10px; width: 120px; } } .check-badges { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 6px; } .validation-detail { margin-bottom: 8px; } .mode-label { font-weight: 500; } .signer-row { display: flex; align-items: center; gap: 14px; padding: 8px 0; border-bottom: 1px solid rgb(0 0 0 / 6%); &:last-of-type { border-bottom: none; } } .signer-signature { flex-shrink: 0; } .signature-image { width: 140px; height: 60px; object-fit: contain; border: 1px solid #ddd; border-radius: 4px; cursor: pointer; background: #fafafa; } .signer-info { flex: 1; min-width: 0; } .signer-name { font-weight: 500; display: flex; align-items: center; gap: 8px; } .gate-warning { color: #d32f2f; font-size: 0.82rem; margin-bottom: 8px; } .pill { font-size: 11px; padding: 2px 8px; border-radius: 6px; font-weight: 600; white-space: nowrap; &.ok { background: #dff5e8; color: #28c07a; } &.bad { background: #fde3e3; color: #d32f2f; } &.neutral { background: #e0e0e0; color: #757575; } }