Files
cbsnexora/src/main.scss
T
niteshandClaude Sonnet 5 1eaa8cc8cf feat(fd): make the Payment dialog the FD Dashboard's Renew action too, redesign it
The Payment dialog (Transfer to Savings / Reinvest Full / Reinvest Principal Only / Partial
Reinvest, works whether an FD is Active or Matured) already had a complete, correct backend
implementation for every closure type -- including one this session found and fixed a real gap
in on the backend side (Reinvest Principal Only silently stranded its leftover interest). Rather
than duplicating that logic in a second, narrower dialog, the FD Dashboard's Renew action now
opens this same dialog in a `dashboardRenewal` mode: every closure type is still available, but
the Closed On Date is computed from the product's grace window instead of picked freely
(backdated to the original maturity date within grace, today once it's passed, picker hidden so
it can't be moved off that value), and submit() calls the new gap-interest pre-step endpoint
first when past grace, before the same generic `payment` command every other caller already used.

Also: full visual redesign (bigger dialog, gradient header, per-option accent colors, refined
spacing) applied to both entry points since they're the same component now; removes the native
"Close" action from a Matured FD's Account Actions menu, since what happens at maturity now
goes through the nightly job or this dialog, not a separate close command that bypassed both.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 16:12:45 +05:30

2015 lines
42 KiB
SCSS

/**
* 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/.
*/
@use 'theme/mifosx-theme';
@use 'theme/material-web' as *;
@use 'theme/pictonblue-yellowgreen' as *;
@use 'theme/indigo-pink' as *;
@use 'theme/pink-bluegrey' as *;
@use 'theme/deeppurple-amber' as *;
@use 'theme/purple-green.scss' as *;
@use 'assets/styles/helper';
@use 'lightgallery/scss/lightgallery' as *;
@use 'lightgallery/scss/lg-thumbnail' as *;
@use 'lightgallery/scss/lg-zoom' as *;
@use 'lightgallery/scss/lg-fullscreen' as *;
@use 'app/core/error-handler/error-handler.component';
// Global Imports
/* You can add global styles to this file, and also import other style files */
.custom-snackbar-top-right {
top: 48px !important;
right: 24px !important;
left: auto !important;
transform: none !important;
position: fixed !important;
z-index: 9999;
}
.snack-error .mdc-snackbar__surface {
background-color: #dc2626 !important;
color: #fff !important;
}
.snack-error .mat-mdc-snack-bar-label {
color: #fff !important;
}
.snack-error .mat-mdc-button {
color: #fecaca !important;
}
// ===== Image Preview Dialog (election candidate photo/symbol viewer) =====
.ipd-dialog .mat-mdc-dialog-container {
padding: 0;
border-radius: 20px;
overflow: hidden;
background: transparent;
box-shadow: none;
}
// ===== Payment / Renewal Dialog Panel =====
.pmt-dialog-panel .mat-mdc-dialog-container .mdc-dialog__surface {
padding: 0 !important;
border-radius: 16px !important;
overflow: hidden !important;
box-shadow: 0 20px 40px rgb(15 23 42 / 25%) !important;
}
.pmt-dialog-panel .mat-mdc-dialog-content {
padding: 0 !important;
max-height: none !important;
}
.ipd-dialog .mdc-dialog__surface {
border-radius: 20px !important;
background: transparent !important;
box-shadow: none !important;
}
.ipd-backdrop {
background: rgb(0 0 0 / 82%);
backdrop-filter: blur(6px);
}
// ===== Sub-menu Mega Panels (rendered in CDK overlay) =====
.deposits-mega-panel,
.hrm-mega-panel {
max-width: 700px !important;
}
.share-mega-panel,
.others-mega-panel {
max-width: 850px !important;
}
.share-grid,
.others-grid {
grid-template-columns: repeat(4, 1fr) !important;
}
.others-grid,
.npa-grid {
grid-template-columns: repeat(3, 1fr) !important;
}
.npa-mega-panel,
.advances-mega-panel {
max-width: 800px !important;
}
.advances-grid {
grid-template-columns: repeat(3, 1fr) !important;
}
.letter-mega-panel {
max-width: 1100px !important;
}
.letter-grid {
grid-template-columns: repeat(5, minmax(190px, 1fr)) !important;
min-width: 1040px;
}
.reconciliation-mega-panel {
max-width: 1100px !important;
}
.reconciliation-grid {
grid-template-columns: repeat(5, minmax(190px, 1fr)) !important;
min-width: 1040px;
}
/* Admin Mega Menu — 3-column rectangular panel (Setup · Catalog ·
Audit & Compliance). Reuses the deposit-mega-menu grid + group chrome
and retints the group-title accent to Admin purple. */
.admin-mega-panel {
max-width: 760px !important;
}
.admin-grid {
grid-template-columns: repeat(3, minmax(220px, 1fr)) !important;
min-width: 680px;
.deposit-group-title {
color: #7c3aed !important;
border-bottom-color: #7c3aed !important;
}
}
// ===== Material Select Panel Styles (Material Design 3) =====
.mat-mdc-select-panel {
background: var(--md-sys-color-surface-container, #fff);
border-radius: 8px;
box-shadow:
0 2px 4px #00000014,
0 4px 12px #0000000f,
0 8px 24px #00000014;
.mat-mdc-option {
font-size: 0.875rem;
min-height: 48px;
padding: 0 16px;
color: var(--md-sys-color-on-surface, #1a1c1e);
transition: background-color 0.2s ease;
&:hover {
background-color: #1074b914;
}
&.mat-mdc-option-active {
background-color: #1074b91f;
}
&.mdc-list-item--selected {
background-color: #1074b91f;
color: var(--md-sys-color-primary, #1074b9);
font-weight: 500;
}
.mdc-list-item__primary-text {
color: inherit;
}
}
}
// Dark theme select panel
.dark-theme .mat-mdc-select-panel {
background: var(--md-sys-color-surface-container, #2c2f36);
.mat-mdc-option {
color: var(--md-sys-color-on-surface, #e2e2e5);
&:hover {
background-color: #5ba2ec14;
}
&.mat-mdc-option-active {
background-color: #5ba2ec1f;
}
&.mdc-list-item--selected {
background-color: #5ba2ec1f;
color: var(--md-sys-color-primary, #5ba2ec);
font-weight: 500;
}
}
}
.scrollbar-styling {
scrollbar-width: thin;
scrollbar-color: #889 #f1f1f1;
}
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
}
::-webkit-scrollbar-thumb {
background: #889;
&:hover {
background: #555;
}
}
/* === Global Layout Utilities === */
.layout-row-wrap {
display: flex;
flex-flow: row wrap;
}
.layout-column {
display: flex;
flex-direction: column;
}
.layout-row {
display: flex;
flex-direction: row;
}
.align-flex-end {
justify-content: flex-end;
}
.flex-align-center {
display: flex;
align-items: center;
justify-content: center;
}
.flex-center {
display: flex;
justify-content: center;
align-items: center;
}
.responsive-column {
@media (width <=768px) {
flex-direction: column;
}
}
.gap-2px {
gap: 2%;
}
.gap-5px {
gap: 5px;
}
.gap-20px {
gap: 20px;
}
.gap-25px {
gap: 25px;
}
.gap-32px {
gap: 32px;
}
.gap-40px {
gap: 40px;
}
.align-start {
justify-content: flex-start;
}
.align-end {
justify-content: flex-end;
}
.align-center-start {
justify-content: flex-start;
align-items: center;
}
.align-center {
justify-content: center;
}
.align-center-center {
justify-content: center;
align-items: center;
}
.align-between {
justify-content: space-between;
}
.align-items-center {
align-items: center;
}
.align-start-baseline {
align-items: baseline;
justify-content: flex-start;
}
.layout-align-end {
display: flex;
justify-content: flex-end;
align-items: center;
}
.align-start-center {
display: flex;
justify-content: flex-start;
align-items: center;
}
.align-start-start {
display: flex;
justify-content: flex-start;
align-items: flex-start;
}
.layout-align-center {
align-items: center;
justify-content: center;
}
.layout-gt-sm-row {
@media (width >=600px) {
flex-direction: row;
}
}
.align-gt-sm-start-center {
@media (width >=600px) {
justify-content: flex-start;
align-items: center;
}
}
.flex-auto {
flex: 0.1 0 auto;
}
.flex-3-auto {
flex: 3 0 auto;
}
.flex-4 {
flex: 0 0 4%;
}
.flex-5 {
flex: 0 0 5%;
}
.flex-8 {
flex: 0 0 8%;
}
.flex-9 {
flex: 0 0 9%;
}
.flex-10 {
flex: 0 0 10%;
}
.flex-13 {
flex: 0 0 13%;
}
.flex-14 {
flex: 0 0 12%;
}
.flex-15 {
flex: 0 0 15%;
}
.flex-16 {
flex: 0 0 16%;
}
.flex-18 {
flex: 0 0 18%;
}
.flex-20 {
flex: 0 0 20%;
}
.flex-23 {
flex: 0 0 23%;
}
.flex-24 {
flex: 0 0 24%;
}
.flex-25 {
flex: 0 0 25%;
}
.flex-28 {
flex: 0 0 28%;
}
.flex-29 {
flex: 0 0 29%;
}
.flex-30 {
flex: 0 0 30%;
}
.flex-31 {
flex: 0 0 31%;
}
.flex-32 {
flex: 0 0 32%;
}
.flex-33 {
flex: 0 0 33%;
}
.flex-34 {
flex: 0 0 34%;
}
.flex-38 {
flex: 0 0 38%;
}
.flex-40 {
//flex: 0 0 40%;
flex: 1;
width: 40%;
}
.flex-43 {
flex: 0 0 43%;
}
.flex-45 {
flex: 0 0 45%;
}
.flex-46 {
flex: 0 0 46%;
}
.flex-47 {
flex: 0 0 47%;
}
.flex-48 {
flex: 0 0 48%;
}
@media (width <=768px) {
.hide-lt-md {
display: none !important;
}
}
.flex-49 {
flex: 0 0 49%;
}
.flex-50 {
flex: 0 0 50%;
margin-bottom: 1rem;
}
.flex-53 {
flex: 0 0 53%;
}
.flex-60 {
// flex: 0 0 60%;
flex: 1;
width: 60%;
}
.flex-63 {
flex: 0 0 63%;
}
.flex-65 {
flex: 0 0 65%;
}
.flex-67 {
flex: 0 0 67%;
}
.flex-68 {
flex: 0 0 68%;
}
.flex-70 {
flex: 0 0 70%;
}
.flex-73 {
flex: 0 0 73%;
}
.flex-75 {
flex: 0 0 75%;
}
.flex-83 {
flex: 0 0 83%;
}
.flex-90 {
flex: 0 0 90%;
}
.flex-94 {
flex: 0 0 94%;
}
.flex-95 {
flex: 0 0 95%;
}
.flex-96 {
flex: 0 0 96%;
}
@media screen and (width <=599px) {
.flex-xs-15 {
flex: 0 0 15%;
max-width: 15%;
}
}
@media screen and (width >=600px) and (width <=959px) {
.flex-sm-10 {
flex: 0 0 10%;
max-width: 10%;
}
}
@media screen and (width >=960px) and (width <=1279px) {
.flex-md-5 {
flex: 0 0 5%;
max-width: 5%;
}
}
.hide-lt-sm {
@media (width <=599px) {
display: none !important;
}
}
.flex-98 {
flex: 0 0 98%;
}
.flex-100 {
flex: 0 0 100%;
width: 100%;
}
.flex-contents {
display: contents;
flex: 1;
}
.flex-fill {
display: flex;
flex: 1 1 auto;
min-width: 0;
min-height: 0;
}
.gap-8px {
gap: 8px;
}
.gap-10px {
gap: 10px;
}
.gap-12px {
gap: 12px;
}
.gap-1percent {
gap: 1%;
}
.gap-2percent {
gap: 2%;
}
.gap-3percent {
gap: 3%;
}
.gap-4percent {
gap: 4%;
}
.gap-5percent {
gap: 5%;
}
.gap-15percent {
gap: 15%;
}
.gap-20percent {
gap: 20%;
}
.gap-25percent {
gap: 25%;
}
.gap-70percent {
gap: 70%;
}
.flex {
flex: 1 1 0%;
}
.layout-row-reverse {
display: flex;
flex-direction: row-reverse;
}
.flex-gt-sm-30 {
@media (width >=600px) {
flex: 1 0 30%;
}
}
@media (width <=1199px) {
.hide-lt-lg {
display: none !important;
}
}
@media (width <=768px) {
.flex-25 {
flex: 0 0 50%;
}
}
@media (width <=599px) {
.layout-xs-column {
flex-direction: column;
}
}
.flex-50-minus-25px {
flex: 1 1 calc(50% - 25px);
}
.flex-85-minus-20px {
flex: 1 1 calc(85% - 20px);
}
.flex-90-minus-20px {
flex: 1 1 calc(90% - 20px);
}
.layout-lt-md-column {
@media (width <=768px) {
flex-direction: column;
}
}
.layout-column.lt-md {
@media (width <=599px) {
flex-direction: column !important;
}
}
.responsive-flex-full {
@media (width <=768px) {
flex: 0 0 100% !important;
}
}
.align-space-evenly-center {
justify-content: space-evenly;
align-items: center;
}
.mat-mdc-form-field {
margin-bottom: 16px;
.mat-mdc-input-element::placeholder {
font-size: 14px !important;
color: #999 !important;
}
.mdc-floating-label {
font-size: 14px !important;
}
}
mat-stepper {
::ng-deep .mat-vertical-content {
padding: 16px;
}
::ng-deep .mat-vertical-stepper-content {
padding-top: 16px;
}
}
@media (width <=768px) {
.flex-lt-md-50 {
flex: 0 0 50%;
}
}
@media (width <=768px) {
.flex-50-lt-md {
flex: 0 0 50%;
}
}
@media (width <=599px) {
.layout-column-xs {
flex-direction: column !important;
}
}
.menu-explanation {
font-size: 14px;
margin: 0;
word-wrap: break-word;
overflow-wrap: break-word;
}
.menu-list-item-content {
display: flex;
width: 100%;
overflow: hidden;
}
.menu-left-section {
display: flex;
align-items: center;
width: 100%;
gap: 10px;
min-width: 0;
flex: 1;
overflow: hidden;
}
.menu-right-section fa-icon {
z-index: 1000;
}
.menu-right-section {
margin-left: auto;
display: flex;
gap: 4px;
margin-right: 10px;
flex-shrink: 0;
}
mat-nav-list {
overflow: hidden;
mat-list-item {
overflow: hidden;
.mat-list-item-content {
overflow: hidden;
}
}
}
.content {
display: contents;
flex: 1;
}
mifosx-notifications-page td {
text-align: center;
padding: 16px;
color: #999;
}
.red {
color: red;
}
// ===== Global Delete/Trash Icon Styling =====
// Makes standalone delete icons red, but keeps them white inside warn (red) buttons
.fa-trash {
color: #f44336 !important;
}
.mat-mdc-raised-button.mat-warn .fa-trash {
color: inherit !important;
}
// ===== Global Button Icon Alignment =====
// Handles the span + mat-icon pattern used throughout the application
.mat-mdc-button,
.mat-mdc-raised-button,
.mat-mdc-outlined-button {
span {
display: inline-flex;
align-items: center;
gap: 8px;
mat-icon {
display: inline-flex;
align-items: center;
justify-content: center;
}
}
}
.full-width-flex {
display: flex;
justify-content: flex-start;
width: 100%;
}
/* Global overflow helpers to avoid repeated component overrides */
.overflow-hidden {
overflow: hidden;
}
mat-card {
overflow: hidden;
}
.layout-row.responsive-column {
overflow: hidden;
> [class] {
overflow: hidden;
}
}
.dark-theme {
.tox.tox-tinymce {
border-color: #444 !important;
}
.tox .tox-editor-header,
.tox .tox-toolbar-overlord,
.tox .tox-toolbar,
.tox .tox-toolbar__overflow,
.tox .tox-toolbar__primary {
background-color: #303135 !important;
}
.tox .tox-tbtn {
background-color: transparent !important;
color: rgb(255 255 255 / 87%) !important;
svg {
fill: rgb(255 255 255 / 87%) !important;
}
&:hover {
background-color: rgb(255 255 255 / 12%) !important;
}
&:focus {
background-color: rgb(255 255 255 / 8%) !important;
}
}
.tox .tox-tbtn--bevel {
background: transparent !important;
}
.tox .tox-tbtn--select {
background-color: transparent !important;
}
.tox .tox-split-button {
background-color: transparent !important;
&:hover {
box-shadow: none !important;
}
}
.tox .tox-edit-area {
background-color: #303135 !important;
iframe {
background-color: transparent !important;
}
}
.tox .tox-sidebar-wrap {
background-color: #303135 !important;
}
.tox .tox-menubar {
background-color: #303135 !important;
}
.tox .tox-menu {
background-color: #303135 !important;
border-color: #444 !important;
}
.tox .tox-collection__item {
color: rgb(255 255 255 / 87%) !important;
&:hover {
background-color: rgb(255 255 255 / 8%) !important;
}
}
.tox .tox-statusbar {
background-color: #303135 !important;
border-color: #444 !important;
color: rgb(255 255 255 / 60%) !important;
}
}
.app-sidenav {
.mat-mdc-nav-list .mat-mdc-list-item {
.mdc-list-item__primary-text {
display: flex;
align-items: center;
gap: 8px;
}
[matlisticon] {
flex-shrink: 0;
width: 24px;
min-width: 24px;
display: inline-flex;
align-items: center;
justify-content: center;
fa-icon {
display: inline-flex;
align-items: center;
justify-content: center;
}
.fa {
display: inline-block;
width: 1em;
text-align: center;
}
}
}
}
/* Print styles — hide app shell, show only receipt content */
@media print {
mat-sidenav,
mifosx-toolbar,
mifosx-breadcrumb,
mifosx-footer,
.sidebar-panel,
.sidebar-handle,
.mat-mdc-tab-header,
.mat-stepper-vertical-line,
.mat-step-header,
/* Account-view pages (Shares, Savings, Current, Deposits…) use `<nav mat-tab-nav-bar
class="navigation-tabs">` for their General/Passbook/Charges/… tab links — a DIFFERENT
Material component from mat-tab-group, so it never carries `.mat-mdc-tab-header` and slipped
past the rule above. Its own style (theme/_content.scss) gives it a grey background and
`overflow: auto`, which is exactly the grey box with a baked-in scrollbar seen in print/PDF
output — printing it is as pointless as printing the tab-group header already excluded above. */
.navigation-tabs,
[mat-tab-nav-bar],
.mat-mdc-tab-nav-bar,
.mat-mdc-tab-link-container,
/* The real 2-row nav menu (Client Master / Approvals / Cashier … and the row below it) and the
live KPI ticker live directly in shell.component.html as .main-header / .kpi-ticker, not
inside <mifosx-toolbar> — hiding only the toolbar left this menu printing on every page. */
.main-header,
.kpi-ticker,
.cashier-nav,
.gl-backdrop,
.gl-mega-menu {
display: none !important;
}
mat-sidenav-content.sidenav {
margin-left: 0 !important;
}
/* THE root clip: assets/styles/_overflow.scss sets `html, body { overflow: hidden }` and
index.html puts `h-full` (height: 100%) on both, so the document itself is locked to exactly
one viewport and everything past it is cut away. Every inner container fix below is useless
while this stands — it is why printing any page produced a blank sheet with only a sliver of
whatever happened to sit at the fold. */
html,
body {
height: auto !important;
overflow: visible !important;
width: 100% !important;
background: #fff !important;
/* Keep backgrounds/colours (certificate rules, table shading) instead of dropping them. */
print-color-adjust: exact;
}
/* The shell then scrolls inside CDK's own clipped viewport —
#mifosx-shell-container { height: 100vh }, .mat-drawer-content { height: 100%; overflow: auto }
— so these have to be freed as well. */
#mifosx-shell-container,
mat-sidenav-container,
mat-drawer-container,
mat-sidenav-content,
mat-drawer-content,
.mat-drawer-container,
.mat-drawer-content,
.mat-sidenav-content {
overflow: visible !important;
height: auto !important;
max-height: none !important;
/* Material's own theme paints a background-color on .mat-drawer-container — without
overriding it here, that grey shows behind every printed page even though html/body are
already forced white above. */
background: #fff !important;
}
/* shell.component.scss:247-271 scopes `mifosx-content { overflow-x: hidden; max-width: 100% }`
specifically to `.sidenav mifosx-content` so tables/cards shrink to fit whenever the sidebar
is open on screen — this rule has nothing to do with the sidebar being hidden for print, and
without overriding it too, the routed page content keeps clipping/scrolling horizontally to
whatever width was last measured on screen, which is exactly the narrow box with a baked-in
scrollbar seen in print/PDF output. */
mifosx-content,
.sidenav mifosx-content,
mat-tab-nav-panel,
.mat-mdc-tab-nav-panel {
overflow: visible !important;
width: auto !important;
max-width: 100% !important;
height: auto !important;
}
/* Angular Material clips a tab's content to a JS-measured on-screen height via
`.mat-mdc-tab-body-wrapper { overflow: hidden }` (for the tab-switch height animation) and
`.mat-mdc-tab-body-content { height: 100%; overflow: auto }` — printing only what fit that
clip left every account/tab page (Shares Account General included) blank apart from a
stray border. Printing needs the full content, not the animated viewport. */
.mat-mdc-tab-body-wrapper,
.mat-mdc-tab-body,
.mat-mdc-tab-body-content {
position: static !important;
overflow: visible !important;
height: auto !important;
}
@page {
/* stylelint-disable-next-line unit-allowed-list */
margin: 1.5cm;
}
}
/* ─── Ensure mat-menu overlays appear above header ─── */
.cdk-overlay-container {
z-index: 1001 !important;
}
/* ─── CRR/SLR Dialog Panel ─── */
.crr-slr-dialog-panel {
.mat-mdc-dialog-container {
padding: 0;
border-radius: 16px;
overflow: hidden;
}
.mat-mdc-dialog-surface {
padding: 0 !important;
border-radius: 16px !important;
}
}
/* ─── Full-Screen Dialog Panel (e.g. FD/RD Entry) — edge-to-edge, no rounded corners ─── */
.fdrd-fullscreen-panel {
max-width: 100vw !important;
width: 100vw !important;
height: 100vh !important;
max-height: 100vh !important;
.mat-mdc-dialog-container {
border-radius: 0 !important;
}
.mat-mdc-dialog-surface {
border-radius: 0 !important;
}
}
/* ─── CIC DQR Dialog Backdrop — ensure outside clicks register ─── */
.cic-dlg-backdrop {
background: rgb(15 23 42 / 45%);
pointer-events: auto;
}
/* ─── PSL Report Dialog Backdrop ─── */
.psl-dlg-backdrop {
background: rgb(15 23 42 / 45%);
pointer-events: auto;
}
/* ─── ALM Report Dialog Backdrop ─── */
.alm-dlg-backdrop {
background: rgb(15 23 42 / 45%);
pointer-events: auto;
}
/* ─── CIMS / XBRL Returns Dialog Backdrop ─── */
.cims-dlg-backdrop {
background: rgb(15 23 42 / 45%);
pointer-events: auto;
}
/* ─── CKYC Compliance Reports Dialog Backdrop ─── */
.ckyc-rpt-dlg-backdrop {
background: rgb(15 23 42 / 45%);
pointer-events: auto;
}
/* ─── Accounting Reports Dialog Backdrop ─── */
.acct-rpt-dlg-backdrop {
background: rgb(15 23 42 / 45%);
pointer-events: auto;
}
/* ─── NEFT / RTGS Entry Dialog Panel ─── */
.nr-entry-dialog {
.mat-mdc-dialog-container {
padding: 0;
border-radius: 14px;
overflow: hidden;
}
.mat-mdc-dialog-surface {
padding: 0 !important;
border-radius: 14px !important;
box-shadow:
0 24px 48px rgb(15 23 42 / 25%),
0 12px 24px rgb(15 23 42 / 15%) !important;
}
}
/* NEFT / RTGS Entry Dialog Backdrop — darker so the report behind dims out */
.nr-entry-backdrop {
background: rgb(15 23 42 / 55%);
pointer-events: auto;
}
/* ─── Savings Account Actions Menu ───
Modern Nexora dropdown for the kebab on the savings account view hero.
Groups actions semantically (Transact · Restrict · Interest · Admin ·
Danger zone) and colour-codes each row's icon by category. */
.sav-action-menu.mat-mdc-menu-panel {
min-width: 280px !important;
max-width: 320px !important;
border-radius: 14px !important;
border: 1px solid #e2e8f0;
box-shadow:
0 12px 32px -8px rgb(15 23 42 / 18%),
0 4px 12px -4px rgb(15 23 42 / 10%) !important;
padding: 0 !important;
overflow: hidden;
}
.sav-action-menu .mat-mdc-menu-content {
padding: 0 !important;
overflow: hidden !important;
}
.sav-menu {
display: flex;
flex-direction: column;
font-family: Inter, 'DM Sans', Roboto, sans-serif;
max-height: 440px;
overflow: hidden;
}
.sav-menu__body {
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: #cbd5e1 transparent;
}
.sav-menu__body::-webkit-scrollbar {
width: 4px;
}
.sav-menu__body::-webkit-scrollbar-track {
background: transparent;
}
.sav-menu__body::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 4px;
}
.sav-menu__head {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 14px;
background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 45%, #4338ca 100%);
color: #fff;
}
.sav-menu__head-ico {
width: 28px;
height: 28px;
border-radius: 8px;
background: rgb(255 255 255 / 18%);
border: 1px solid rgb(255 255 255 / 28%);
display: inline-flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 12px;
flex-shrink: 0;
}
.sav-menu__head-title {
font-size: 13px;
font-weight: 800;
letter-spacing: 0.01em;
line-height: 1.1;
}
.sav-menu__head-sub {
margin-top: 1px;
font-size: 10.5px;
color: rgb(255 255 255 / 78%);
}
.sav-menu__group {
padding: 6px 0;
& + & {
border-top: 1px solid #f1f5f9;
}
&--danger {
background: #fefafa;
}
&:empty {
display: none;
}
}
.sav-menu__group-title {
font-size: 9.5px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #94a3b8;
padding: 4px 14px 2px;
}
.sav-menu__item.mat-mdc-menu-item {
display: flex !important;
align-items: center;
gap: 10px;
min-height: 38px !important;
height: 38px !important;
padding: 0 14px !important;
font-size: 13px !important;
font-weight: 500 !important;
color: #0d1b2a !important;
background: transparent !important;
transition: background 0.12s ease;
/* Hide Material's default trailing chevron/state container so our
icon + label are the only visual elements. */
.mat-mdc-menu-item-text {
display: contents;
}
&:hover {
background: #f1f5f9 !important;
}
}
.sav-menu__ico {
width: 26px;
height: 26px;
border-radius: 7px;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 11.5px;
flex-shrink: 0;
background: #e0e7ff;
color: #4338ca;
border: 1px solid transparent;
transition:
transform 0.12s ease,
background 0.12s ease,
color 0.12s ease;
}
.sav-menu__label {
flex: 1 1 auto;
min-width: 0;
}
.sav-menu__item.mat-mdc-menu-item .mat-mdc-menu-item-text,
.sav-menu__item.mat-mdc-menu-item .mdc-list-item__primary-text,
.sav-menu__item.mat-mdc-menu-item .mdc-list-item__content {
display: flex !important;
flex-direction: row !important;
align-items: center !important;
gap: 10px !important;
width: 100%;
}
/* Hover lift on the icon */
.sav-menu__item:hover .sav-menu__ico {
transform: scale(1.06);
}
/* Variant tints */
.sav-menu__item--transact .sav-menu__ico {
background: #ecfdf5;
color: #047857;
}
.sav-menu__item--block .sav-menu__ico {
background: #fff7ed;
color: #c2410c;
}
.sav-menu__item--interest .sav-menu__ico {
background: #eff6ff;
color: #1d4ed8;
}
.sav-menu__item--admin .sav-menu__ico {
background: #f5f3ff;
color: #6d28d9;
}
.sav-menu__item--danger.mat-mdc-menu-item {
color: #991b1b !important;
}
.sav-menu__item--danger .sav-menu__ico {
background: #fee2e2;
color: #b91c1c;
}
.sav-menu__item--danger:hover {
background: #fef2f2 !important;
}
/* ─── Current Account action menu (mirrors sav-action-menu styling) ─────── */
.cur-action-menu.mat-mdc-menu-panel {
min-width: 280px !important;
max-width: 320px !important;
border-radius: 14px !important;
box-shadow:
0 8px 30px -6px rgb(15 23 42 / 22%),
0 0 0 1px rgb(15 23 42 / 6%) !important;
border: none !important;
overflow: hidden;
}
.cur-action-menu .mat-mdc-menu-content {
padding: 0 !important;
overflow: hidden !important;
}
.cur-menu {
display: flex;
flex-direction: column;
font-family: Inter, 'DM Sans', Roboto, sans-serif;
max-height: 440px;
overflow: hidden;
}
.cur-menu__body {
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: #cbd5e1 transparent;
}
.cur-menu__body::-webkit-scrollbar {
width: 4px;
}
.cur-menu__body::-webkit-scrollbar-track {
background: transparent;
}
.cur-menu__body::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 4px;
}
.cur-menu__head {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 14px;
background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 45%, #4338ca 100%);
color: #fff;
}
.cur-menu__head-ico {
width: 28px;
height: 28px;
border-radius: 8px;
background: rgb(255 255 255 / 18%);
border: 1px solid rgb(255 255 255 / 28%);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
flex-shrink: 0;
}
.cur-menu__head-title {
font-size: 13px;
font-weight: 800;
letter-spacing: 0.01em;
line-height: 1.1;
}
.cur-menu__head-sub {
margin-top: 1px;
font-size: 10.5px;
color: rgb(255 255 255 / 78%);
}
.cur-menu__group {
padding: 6px 0;
& + & {
border-top: 1px solid #f1f5f9;
}
&--danger {
background: #fff8f8;
& + & {
border-top-color: #fee2e2;
}
}
}
.cur-menu__group-title {
font-size: 9.5px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #94a3b8;
padding: 4px 14px 2px;
}
.cur-menu__item.mat-mdc-menu-item {
display: flex !important;
align-items: center;
gap: 10px;
min-height: 38px !important;
padding: 5px 14px !important;
font-size: 13px !important;
font-weight: 600;
color: #1e293b;
transition:
background 0.12s ease,
color 0.12s ease;
}
.cur-menu__ico {
width: 26px;
height: 26px;
border-radius: 7px;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
flex-shrink: 0;
background: #f1f5f9;
color: #64748b;
transition:
transform 0.12s ease,
background 0.12s ease,
color 0.12s ease;
}
.cur-menu__label {
flex: 1 1 auto;
min-width: 0;
}
/* Material 20 wraps projected content in .mat-mdc-menu-item-text — make it
flex so the icon square and label sit side-by-side instead of stacking. */
.cur-menu__item.mat-mdc-menu-item .mat-mdc-menu-item-text,
.cur-menu__item.mat-mdc-menu-item .mdc-list-item__primary-text,
.cur-menu__item.mat-mdc-menu-item .mdc-list-item__content {
display: flex !important;
flex-direction: row !important;
align-items: center !important;
gap: 10px !important;
width: 100%;
}
.cur-menu__item:hover .cur-menu__ico {
transform: scale(1.06);
}
/* Variant tints */
.cur-menu__item--transact .cur-menu__ico {
background: #ecfdf5;
color: #047857;
}
.cur-menu__item--block .cur-menu__ico {
background: #fff7ed;
color: #c2410c;
}
.cur-menu__item--interest .cur-menu__ico {
background: #eff6ff;
color: #1d4ed8;
}
.cur-menu__item--admin .cur-menu__ico {
background: #f5f3ff;
color: #6d28d9;
}
.cur-menu__item--danger.mat-mdc-menu-item {
color: #991b1b !important;
}
.cur-menu__item--danger .cur-menu__ico {
background: #fee2e2;
color: #b91c1c;
}
.cur-menu__item--danger:hover {
background: #fef2f2 !important;
}
/* ─── Identity-Verify Dialog Panel ───
Strip Material's default surface padding so the teal gradient header
on the Withdraw "Verify Customer Identity" pop-up reaches edge-to-edge
(no white gutter around the gradient). */
.idv-panel {
.mat-mdc-dialog-container {
padding: 0 !important;
border-radius: 14px;
overflow: hidden;
}
.mat-mdc-dialog-surface {
padding: 0 !important;
border-radius: 14px !important;
overflow: hidden;
}
.mat-mdc-dialog-content {
padding: 0 !important;
max-height: 72vh;
}
.mat-mdc-dialog-actions {
padding: 0 !important;
margin: 0 !important;
}
}
/* ─── Transaction-Confirm Dialog Panel ───
Same flush surface treatment for the Deposit/Withdraw confirmation. */
.tcd-panel {
.mat-mdc-dialog-container {
padding: 0 !important;
border-radius: 14px;
overflow: hidden;
}
.mat-mdc-dialog-surface {
padding: 0 !important;
border-radius: 14px !important;
overflow: hidden;
}
.mat-mdc-dialog-content {
padding: 0 !important;
max-height: 72vh;
}
.mat-mdc-dialog-actions {
padding: 0 !important;
margin: 0 !important;
}
}
/* ─── Add Beneficiary Dialog Panel ─── */
.abd-dialog-panel {
.mat-mdc-dialog-container {
padding: 0;
border-radius: 14px;
overflow: hidden;
}
.mat-mdc-dialog-surface {
padding: 0 !important;
border-radius: 14px !important;
}
.mat-mdc-dialog-content {
padding: 0 20px !important;
max-height: 72vh;
}
.mat-mdc-dialog-actions {
padding: 0 !important;
margin: 0 !important;
}
}
/* ─── Add Related Client Dialog Panel ─── */
.arc-dialog-panel {
.mat-mdc-dialog-container {
padding: 0;
border-radius: 14px;
overflow: hidden;
}
.mat-mdc-dialog-surface {
padding: 0 !important;
border-radius: 14px !important;
}
.mat-mdc-dialog-content {
padding: 0 20px !important;
max-height: 70vh;
}
.mat-mdc-dialog-actions {
padding: 0 !important;
margin: 0 !important;
}
}
/* ===================== Two-factor authentication dialog ===================== */
.tfa-dialog-panel {
.mat-mdc-dialog-surface {
background: linear-gradient(160deg, #0b1220 0%, #0f172a 60%, #111c33 100%) !important;
border-radius: 18px !important;
padding: 0 !important;
box-shadow: 0 30px 80px rgb(0 0 0 / 55%) !important;
overflow: hidden;
}
.mat-mdc-dialog-container {
--mdc-dialog-container-color: transparent;
padding: 0 !important;
}
}
.cdk-overlay-pane.tfa-dialog-panel {
border-radius: 18px;
}
.tfa-dialog-backdrop {
background: rgb(2 6 23 / 75%) !important;
backdrop-filter: blur(4px);
}
/* ─── DSC Enroll Dialog Panel — edge-to-edge hero ─── */
.ed-dialog-panel {
.mat-mdc-dialog-container {
padding: 0;
border-radius: 16px;
overflow: hidden;
}
.mat-mdc-dialog-surface {
padding: 0 !important;
border-radius: 16px !important;
overflow: hidden !important;
}
}
/* ═══════════════════════════════════════════════════════════════
Client stepper — disabled (read-only) form-field overrides
─── Applied GLOBALLY so they bypass component view-encapsulation.
`::ng-deep` inside a component SCSS sometimes loses specificity
battles with Material 3's MDC token cascade — a global rule scoped
to the stepper's component selectors avoids that entirely.
═══════════════════════════════════════════════════════════════ */
mifosx-client-general-step,
mifosx-client-india-address-step,
mifosx-client-address-step,
mifosx-client-kyc-step,
mifosx-client-entity-kyc-step,
mifosx-client-family-members-step,
mifosx-client-datatable-step {
/* Token-level overrides — these are the colours MDC reads when computing
disabled state. Forcing them at the host avoids fighting MDC rule by rule. */
--mdc-outlined-text-field-disabled-input-text-color: #0f172a;
--mdc-outlined-text-field-disabled-label-text-color: #64748b;
--mdc-outlined-text-field-disabled-outline-color: #cbd5e1;
--mdc-outlined-text-field-disabled-supporting-text-color: #64748b;
--mdc-outlined-text-field-disabled-leading-icon-color: #475569;
--mdc-outlined-text-field-disabled-trailing-icon-color: #475569;
--mdc-filled-text-field-disabled-input-text-color: #0f172a;
--mdc-filled-text-field-disabled-label-text-color: #64748b;
--mat-select-disabled-trigger-text-color: #0f172a;
--mat-form-field-disabled-input-text-color: #0f172a;
--mat-form-field-disabled-input-text-placeholder-color: #64748b;
.mat-mdc-form-field.mat-form-field-disabled,
.mat-mdc-form-field-disabled {
opacity: 1 !important;
.mat-mdc-input-element,
input.mat-mdc-input-element,
textarea.mat-mdc-input-element {
color: #0f172a !important;
-webkit-text-fill-color: #0f172a !important;
font-weight: 600;
caret-color: transparent;
opacity: 1 !important;
}
.mat-mdc-floating-label,
.mdc-floating-label,
.mat-mdc-form-field-required-marker {
color: #64748b !important;
opacity: 1 !important;
}
.mdc-notched-outline__leading,
.mdc-notched-outline__notch,
.mdc-notched-outline__trailing {
border-color: #cbd5e1 !important;
}
.mat-mdc-select-value,
.mat-mdc-select-value-text,
.mat-mdc-select-min-line,
.mat-mdc-select-placeholder {
color: #0f172a !important;
-webkit-text-fill-color: #0f172a !important;
font-weight: 600;
opacity: 1 !important;
}
.mat-mdc-select-arrow {
color: #94a3b8 !important;
}
.mat-mdc-form-field-icon-prefix,
.mat-mdc-form-field-icon-suffix,
.field-prefix-icon mat-icon,
.mat-mdc-form-field-icon-prefix mat-icon,
.mat-mdc-form-field-icon-suffix mat-icon {
color: #475569 !important;
opacity: 1 !important;
}
.mat-mdc-form-field-hint {
color: #64748b !important;
opacity: 1 !important;
}
}
/* The disabled mat-select element itself (sibling of mat-form-field-disabled
in some Material 3 builds) — drop the opacity drop. */
.mat-mdc-select-disabled,
.mat-mdc-select-disabled .mat-mdc-select-trigger,
.mat-mdc-select-disabled .mat-mdc-select-value,
.mat-mdc-select-disabled .mat-mdc-select-value-text,
.mat-mdc-select-disabled .mat-mdc-select-min-line {
color: #0f172a !important;
-webkit-text-fill-color: #0f172a !important;
font-weight: 600;
opacity: 1 !important;
}
/* MDC text-field root with its own disabled modifier */
.mdc-text-field--disabled {
opacity: 1 !important;
.mdc-text-field__input,
input,
textarea,
.mat-mdc-select-min-line {
color: #0f172a !important;
-webkit-text-fill-color: #0f172a !important;
opacity: 1 !important;
}
}
/* Native UA stylesheet — Chrome/Safari force `-webkit-text-fill-color: rgb(84,84,84)`
on any disabled control. This beats `color`, so reset both. */
input:disabled,
select:disabled,
textarea:disabled {
color: #0f172a !important;
-webkit-text-fill-color: #0f172a !important;
opacity: 1 !important;
}
/* Disabled checkboxes — Material 3's MDC checkbox uses `border-color` to
paint the filled box (not `background-color`), so we force BOTH and also
target the SVG path's stroke for the tick. Specificity is bumped via
chained selectors to beat MDC's own rules. */
/* Checked + disabled — solid green box, white tick */
mat-checkbox.mat-mdc-checkbox.mat-mdc-checkbox-checked.mat-mdc-checkbox-disabled
.mdc-checkbox
.mdc-checkbox__background,
.mat-mdc-checkbox.mat-mdc-checkbox-checked.mat-mdc-checkbox-disabled .mdc-checkbox__background,
.mat-mdc-checkbox.mat-mdc-checkbox-disabled.mat-mdc-checkbox-checked .mdc-checkbox__background,
.mat-mdc-checkbox-disabled .mdc-checkbox__native-control:checked ~ .mdc-checkbox__background,
.mdc-checkbox--selected.mdc-checkbox--disabled .mdc-checkbox__background {
background-color: #059669 !important;
border-color: #059669 !important;
opacity: 1 !important;
}
/* Tick (white SVG path) */
mat-checkbox.mat-mdc-checkbox-checked.mat-mdc-checkbox-disabled .mdc-checkbox__checkmark,
mat-checkbox.mat-mdc-checkbox-checked.mat-mdc-checkbox-disabled .mdc-checkbox__checkmark-path,
.mat-mdc-checkbox-disabled.mat-mdc-checkbox-checked .mdc-checkbox__checkmark-path {
color: #fff !important;
stroke: #fff !important;
opacity: 1 !important;
}
/* Unchecked + disabled — outlined slate box (visible but empty) */
.mat-mdc-checkbox-disabled:not(.mat-mdc-checkbox-checked) .mdc-checkbox__background {
background-color: transparent !important;
border-color: #94a3b8 !important;
opacity: 1 !important;
}
/* Full opacity at every layer of MDC's checkbox tree */
mat-checkbox.mat-mdc-checkbox-disabled,
.mat-mdc-checkbox-disabled,
.mat-mdc-checkbox-disabled .mdc-checkbox,
.mat-mdc-checkbox-disabled .mdc-checkbox__ripple,
.mat-mdc-checkbox-disabled .mdc-form-field {
opacity: 1 !important;
}
/* Label */
.mat-mdc-checkbox-disabled .mdc-form-field > label,
.mat-mdc-checkbox-disabled .mat-mdc-checkbox-label,
.mat-mdc-checkbox-disabled .mdc-label {
color: #0f172a !important;
opacity: 1 !important;
font-weight: 500;
}
}
/* Token-level overrides at :root so they cascade EVERYWHERE under the stepper
(MDC sometimes reads tokens at the component root, which lives outside our
`mifosx-client-*-step` host element). Limiting to a class scope to avoid
bleeding into other parts of the app. Descendant variants intentionally
use `*` so the CSS variables are picked up by Material's deeply nested
host elements. */
/* stylelint-disable selector-max-universal */
mifosx-client-general-step,
mifosx-client-india-address-step,
mifosx-client-address-step,
mifosx-client-kyc-step,
mifosx-client-entity-kyc-step,
mifosx-client-family-members-step,
mifosx-client-datatable-step,
mifosx-client-general-step *,
mifosx-client-india-address-step *,
mifosx-client-address-step *,
mifosx-client-kyc-step *,
mifosx-client-entity-kyc-step *,
mifosx-client-family-members-step *,
mifosx-client-datatable-step * {
--mdc-checkbox-disabled-selected-icon-color: #059669;
--mdc-checkbox-disabled-unselected-icon-color: #94a3b8;
--mdc-checkbox-selected-icon-color: #059669;
--mdc-checkbox-selected-focus-icon-color: #059669;
--mdc-checkbox-selected-hover-icon-color: #059669;
--mdc-checkbox-selected-pressed-icon-color: #059669;
}
/* stylelint-enable selector-max-universal */
/* ==========================================================================
Global Print Styles for Material Dialogs & Certificates
========================================================================== */
@media print {
html,
body {
height: auto !important;
overflow: visible !important;
background: #fff !important;
}
/* Hide main application shell during dialog printing */
body > :not(.cdk-overlay-container) {
display: none !important;
}
/* Remove fixed positioning on CDK overlay elements so content flows naturally */
.cdk-overlay-backdrop {
display: none !important;
}
.cdk-overlay-container,
.cdk-global-overlay-wrapper,
.cdk-overlay-pane,
.mat-mdc-dialog-container,
.mdc-dialog__container,
.mdc-dialog__surface {
position: static !important;
display: block !important;
max-height: none !important;
max-width: none !important;
height: auto !important;
width: auto !important;
overflow: visible !important;
transform: none !important;
box-shadow: none !important;
background: transparent !important;
padding: 0 !important;
}
.no-print,
.mat-mdc-dialog-actions {
display: none !important;
}
}
/* Apply Collection Dialog Panel Styling */
/* No overflow:hidden here. The dialog's own .dialog-wrapper already clips to the same radius, and
clipping at the surface as well cut off the voucher-search and receipt-detail popups, which the
dialog renders as its own fixed-position children. */
.apply-collection-dialog-panel {
.mat-mdc-dialog-container,
.mdc-dialog__surface {
border-radius: 12px !important;
padding: 0 !important;
box-shadow: 0 25px 60px -15px rgb(15 23 42 / 30%) !important;
}
// Fix Material MDC button icon + text alignment inside both dialogs
.mat-mdc-button-base {
// The MDC internal label span — make it flex so icon & text sit on the same axis
.mdc-button__label {
display: inline-flex !important;
align-items: center !important;
gap: 0.3rem !important;
line-height: 1 !important;
}
// mat-icon inside any button in these dialogs
.mat-icon {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
width: 18px !important;
height: 18px !important;
font-size: 18px !important;
line-height: 1 !important;
vertical-align: middle !important;
overflow: visible !important;
flex-shrink: 0;
}
}
}