/** * 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/. */ $primary: #0f766e; .dte-container { // Wider than a normal form page: a collection row carries six fields side by side, and a clerk // keying a round should see the whole of it. max-width: 1280px; margin: 0 auto; padding: 20px 16px; } .dte-header { display: flex; align-items: center; gap: 16px; margin-bottom: 20px; &__title { margin: 0; font-size: 22px; font-weight: 500; } } .dte-back { color: $primary; } .dte-card { background: var(--md-sys-color-surface, #fff); border-radius: 8px; box-shadow: 0 2px 8px rgb(0 0 0 / 8%); padding: 20px 24px 24px; } .dte-info-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 20px; } .dte-info-panel { border: 1px solid rgb(0 0 0 / 10%); border-radius: 8px; padding: 12px 16px; background: rgb(15 118 110 / 4%); &__title { font-weight: 600; font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; color: $primary; margin-bottom: 8px; } &__hint { margin: 0; color: rgb(0 0 0 / 50%); font-size: 13px; } dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0; } dt { font-weight: 500; color: rgb(0 0 0 / 60%); font-size: 13px; } dd { margin: 0; font-size: 13px; } } .dte-controls { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; } // A sensible floor for the fields laid out with flex in .dte-controls, where there is room to spare. .dte-field { min-width: 180px; &--wide { grid-column: span 2; } } // Inside the collection grid the track decides the width, not the field. Left to its own 180px // floor a field refuses to shrink into a narrower track and overruns the one beside it. .dte-collection-row .dte-field { width: 100%; min-width: 0; } .dte-section { padding: 16px 0; border-top: 1px solid rgb(0 0 0 / 8%); // A very narrow window scrolls the grid sideways rather than the whole page. overflow-x: auto; &__header { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; i { color: $primary; } h3 { margin: 0; font-size: 16px; font-weight: 600; flex: 1; } } } .dte-add-row { color: $primary; } .dte-empty { color: rgb(0 0 0 / 50%); font-size: 14px; margin: 0; } .dte-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px 16px; } /* * One collection per row. Fixed columns rather than an even split, so the row holds its shape as * fields come and go - Cheque No and Token No only appear for a non-cash entry - and the party * picker gets the width its "code · name · daily amount" needs. */ .dte-collection-row { display: grid; grid-template-columns: minmax(0, 2.2fr) /* Party */ minmax(0, 1fr) /* TRTP */ minmax(0, 1fr) /* AC Type */ minmax(0, 1.4fr) /* A/C No. */ minmax(0, 1fr) /* Amount */ minmax(0, 1.6fr) /* Description */ auto; /* remove */ gap: 8px 12px; align-items: start; padding: 10px 0; border-top: 1px dashed rgb(0 0 0 / 10%); &:first-of-type { border-top: none; } // Cheque No and Token No push Description and the remove button onto a second line, which is // what a non-cash entry should look like rather than a row running off the screen. &:has(.dte-field--instrument) { grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.6fr) auto; } } .dte-collection-row .dte-field--wide { grid-column: span 2; } @media (width <= 1200px) { .dte-collection-row, .dte-collection-row:has(.dte-field--instrument) { grid-template-columns: repeat(3, minmax(0, 1fr)) auto; } } .dte-remove-row { color: #b91c1c; margin-top: 8px; } .dte-action-bar { display: flex; justify-content: flex-end; gap: 12px; margin-top: 20px; padding-top: 16px; border-top: 1px solid rgb(0 0 0 / 8%); flex-wrap: wrap; } @media (width <= 1000px) { .dte-info-panels { grid-template-columns: 1fr; } .dte-grid { grid-template-columns: repeat(2, 1fr); } .dte-collection-row { grid-template-columns: repeat(2, 1fr); } } /* Resolved name under an Agent / Party Code field — the check that the right record was found. */ .dte-hint--found { color: #15803d; font-weight: 500; } .dte-hint--missing { color: #b91c1c; font-weight: 500; } /* Marks an agent in the list who is no longer collecting - only offered for settlement. */ .dte-agent-off { color: #b45309; font-size: 12px; font-style: italic; margin-left: 6px; } /* The figure the clerk actually verifies against the passbook before saving. */ .dte-after { font-weight: 600; color: #0f766e; } /* What the agent should be handing over for this round. */ .dte-total { display: flex; justify-content: flex-end; align-items: baseline; gap: 14px; padding: 10px 4px 2px; border-top: 1px solid rgb(0 0 0 / 10%); font-size: 0.88rem; color: rgb(0 0 0 / 60%); strong { font-size: 1.1rem; color: rgb(0 0 0 / 85%); font-variant-numeric: tabular-nums; } } /* Marks a transaction type the system does not handle yet, so it reads as pending rather than broken. */ .dte-soon { font-size: 0.78rem; font-style: italic; color: rgb(0 0 0 / 45%); } /* * Marks a party this agent has already collected from today, on the row where it is picked. * * Amber, not red: a customer paying twice in a day is legitimate - arrears, or two days at once - * so this is a second look, not an error. Blocking it would stop real work; saying nothing lets a * whole round be credited twice. */ .dte-hint--again { color: #b45309; font-weight: 500; } /* * Where a party stands against its instalments. Three states rather than one colour, because they * call for three different things from the clerk: ahead means take nothing, behind means take more * than the daily amount, level means take the daily amount as usual. * * Behind is amber, not red - falling a few days behind is ordinary in daily collection and is the * agent's job to recover, not an error. Red here would cry wolf on most rows. */ .dte-hint--ahead, .dte-sched--ahead { color: #15803d; font-weight: 500; } .dte-hint--behind, .dte-sched--behind { color: #b45309; font-weight: 500; } .dte-hint--level, .dte-sched--level { color: rgb(0 0 0 / 55%); } /* In the party panel the schedule line carries more weight than the fields around it. */ .dte-sched { font-weight: 500; } /* Says why a party in the list cannot be picked, beside the party rather than in a tooltip. */ .dte-covered { color: #15803d; font-size: 0.8rem; } /* * An amount that looks like a slip. Red rather than the amber used for arrears: arrears are ordinary * and the agent's job to recover, while this is a figure that probably was not handed over at all, * and once saved it cannot be taken back. It still does not block - the clerk decides. */ .dte-hint--overpay { color: #b91c1c; font-weight: 500; } /* The agent's written-down round, as the counter reads it. Laid out as lines rather than as the input grid this replaced: there is nothing to fill in here, only a list to check a bag of cash against, and controls would invite editing something the clerk has no business editing. */ .dte-pending-row { display: flex; align-items: baseline; gap: 12px; padding: 10px 2px; border-bottom: 1px solid rgb(0 0 0 / 8%); &:last-of-type { border-bottom: none; } /* First, and in the quieter weight: the date is context for the line, not what is being read. */ &__date { min-width: 96px; opacity: 0.7; font-variant-numeric: tabular-nums; } &__code { font-weight: 600; min-width: 84px; } &__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: 0.75; } &__mode { font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; opacity: 0.6; } /* Amounts are read down the column and compared, so the digits have to line up. */ &__amount { font-variant-numeric: tabular-nums; font-weight: 600; min-width: 96px; text-align: right; } } /* The one figure the clerk acts on, said as a sentence so it is not read as another column total. */ .dte-expected { margin: 14px 2px 0; font-size: 14px; line-height: 1.5; strong { font-variant-numeric: tabular-nums; } } /* Quieter than the figure above it: a note about how the screen behaves, not part of the count. */ .dte-expected--note { font-size: 13px; opacity: 0.65; margin-top: 4px; } .dte-apply-receipt { margin-left: 8px; } /* Agent Tran: what the agent owes, what the cashier has taken in, and what is left. */ .dte-money { display: flex; gap: 12px; margin: 8px 0 12px; flex-wrap: wrap; &__box { flex: 1; min-width: 160px; padding: 10px 14px; border: 1px solid rgb(0 0 0 / 10%); border-radius: 8px; display: flex; flex-direction: column; gap: 4px; font-variant-numeric: tabular-nums; strong { font-size: 18px; } &--due { border-color: rgb(198 40 40 / 40%); background: rgb(198 40 40 / 4%); } } &__label { font-size: 12px; opacity: 0.7; text-transform: uppercase; letter-spacing: 0.04em; } } .dte-subhead { margin: 16px 0 4px; font-size: 14px; font-weight: 600; } .dte-pending-row--day { cursor: pointer; } .dte-day-lines { margin-left: 24px; max-height: 280px; overflow-y: auto; border-left: 3px solid rgb(25 118 210 / 30%); padding-left: 10px; } .dte-status { font-size: 12px; padding: 2px 8px; border-radius: 10px; background: rgb(237 108 2 / 12%); color: #b45309; &--ok { background: rgb(46 125 50 / 12%); color: #2e7d32; } } .dte-list-arrow { cursor: pointer; } .dte-same-party { color: #c62828; font-weight: 600; }