diff --git a/components.js b/components.js index f8fd74c..597580d 100644 --- a/components.js +++ b/components.js @@ -115,7 +115,7 @@ customElements.define('sm-button', set disabled(value) { if (value) { this.setAttribute('disabled', '') - }else { + } else { this.removeAttribute('disabled') } } @@ -164,80 +164,80 @@ smForm.innerHTML = ` width: 100%; } -
+
` customElements.define('sm-form', class extends HTMLElement { - constructor() { - super() - this.attachShadow({ - mode: 'open' - }).append(smForm.content.cloneNode(true)) + constructor() { + super() + this.attachShadow({ + mode: 'open' + }).append(smForm.content.cloneNode(true)) - this.form = this.shadowRoot.querySelector('form') - this.formElements - this.requiredElements - this.submitButton - this.resetButton - this.allRequiredValid = false + this.form = this.shadowRoot.querySelector('form') + this.formElements + this.requiredElements + this.submitButton + this.resetButton + this.allRequiredValid = false - this.debounce = this.debounce.bind(this) - this.handleInput = this.handleInput.bind(this) - this.handleKeydown = this.handleKeydown.bind(this) - this.reset = this.reset.bind(this) - } - debounce(callback, wait) { - let timeoutId = null; - return (...args) => { - window.clearTimeout(timeoutId); - timeoutId = window.setTimeout(() => { - callback.apply(null, args); - }, wait); - }; - } - handleInput(e) { - this.allRequiredValid = this.requiredElements.every(elem => elem.isValid) - if (!this.submitButton) return; - if (this.allRequiredValid) { - this.submitButton.disabled = false; - } - else { - this.submitButton.disabled = true; - } - } - handleKeydown(e) { - if (e.key === 'Enter' && e.target.tagName !== 'SM-TEXTAREA' ) { - if (this.allRequiredValid) { - this.submitButton.click() - } - else { - this.requiredElements.find(elem => !elem.isValid).vibrate() - } - } - } - reset() { - this.formElements.forEach(elem => elem.reset()) - } - connectedCallback() { - const slot = this.shadowRoot.querySelector('slot') - slot.addEventListener('slotchange', e => { - this.formElements = [...this.querySelectorAll('sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio')] - this.requiredElements = this.formElements.filter(elem => elem.hasAttribute('required')) - this.submitButton = e.target.assignedElements().find(elem => elem.getAttribute('variant') === 'primary' || elem.getAttribute('type') === 'submit'); - this.resetButton = e.target.assignedElements().find(elem => elem.getAttribute('type') === 'reset'); - if (this.resetButton) { - this.resetButton.addEventListener('click', this.reset) - } - }) - this.addEventListener('input', this.debounce(this.handleInput, 100)) - this.addEventListener('keydown', this.debounce(this.handleKeydown, 100)) - } - disconnectedCallback() { - this.removeEventListener('input', this.debounce(this.handleInput, 100)) - this.removeEventListener('keydown', this.debounce(this.handleKeydown, 100)) - } + this.debounce = this.debounce.bind(this) + this.handleInput = this.handleInput.bind(this) + this.handleKeydown = this.handleKeydown.bind(this) + this.reset = this.reset.bind(this) + } + debounce(callback, wait) { + let timeoutId = null; + return (...args) => { + window.clearTimeout(timeoutId); + timeoutId = window.setTimeout(() => { + callback.apply(null, args); + }, wait); + }; + } + handleInput(e) { + this.allRequiredValid = this.requiredElements.every(elem => elem.isValid) + if (!this.submitButton) return; + if (this.allRequiredValid) { + this.submitButton.disabled = false; + } + else { + this.submitButton.disabled = true; + } + } + handleKeydown(e) { + if (e.key === 'Enter' && e.target.tagName !== 'SM-TEXTAREA') { + if (this.allRequiredValid) { + this.submitButton.click() + } + else { + this.requiredElements.find(elem => !elem.isValid).vibrate() + } + } + } + reset() { + this.formElements.forEach(elem => elem.reset()) + } + connectedCallback() { + const slot = this.shadowRoot.querySelector('slot') + slot.addEventListener('slotchange', e => { + this.formElements = [...this.querySelectorAll('sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio')] + this.requiredElements = this.formElements.filter(elem => elem.hasAttribute('required')) + this.submitButton = e.target.assignedElements().find(elem => elem.getAttribute('variant') === 'primary' || elem.getAttribute('type') === 'submit'); + this.resetButton = e.target.assignedElements().find(elem => elem.getAttribute('type') === 'reset'); + if (this.resetButton) { + this.resetButton.addEventListener('click', this.reset) + } + }) + this.addEventListener('input', this.debounce(this.handleInput, 100)) + this.addEventListener('keydown', this.debounce(this.handleKeydown, 100)) + } + disconnectedCallback() { + this.removeEventListener('input', this.debounce(this.handleInput, 100)) + this.removeEventListener('keydown', this.debounce(this.handleKeydown, 100)) + } }) const smInput = document.createElement('template') @@ -488,7 +488,7 @@ customElements.define('sm-input', this.isRequired = false this.validationFunction this.reflectedAttributes = ['value', 'required', 'disabled', 'type', 'inputmode', 'readonly', 'min', 'max', 'pattern', 'minlength', 'maxlength', 'step'] - + this.reset = this.reset.bind(this) this.focusIn = this.focusIn.bind(this) this.focusOut = this.focusOut.bind(this) @@ -545,7 +545,7 @@ customElements.define('sm-input', } } set customValidation(val) { - + this.validationFunction = val } set errorText(val) { @@ -578,19 +578,19 @@ customElements.define('sm-input', return (_isValid && _customValid) } } - reset(){ + reset() { this.value = '' } - focusIn(){ + focusIn() { this.input.focus() } - focusOut(){ + focusOut() { this.input.blur() } - fireEvent(){ + fireEvent() { let event = new Event('input', { bubbles: true, cancelable: true, @@ -599,7 +599,7 @@ customElements.define('sm-input', this.dispatchEvent(event); } - checkInput(e){ + checkInput(e) { if (!this.hasAttribute('readonly')) { if (this.input.value.trim() !== '') { this.clearBtn.classList.remove('hide') @@ -643,7 +643,7 @@ customElements.define('sm-input', this.input.addEventListener('input', this.checkInput) this.clearBtn.addEventListener('click', this.reset) } - + attributeChangedCallback(name, oldValue, newValue) { if (oldValue !== newValue) { if (this.reflectedAttributes.includes(name)) { @@ -680,7 +680,7 @@ customElements.define('sm-input', } else { this.feedbackText.textContent = '' - this.setAttribute('aria-required', 'false') + this.setAttribute('aria-required', 'false') } } else if (name === 'readonly') { @@ -1175,7 +1175,7 @@ customElements.define('sm-popup', class extends HTMLElement { } show(options = {}) { - const {pinned = false, popupStack = undefined} = options + const { pinned = false, popupStack = undefined } = options if (popupStack) this.popupStack = popupStack if (this.popupStack && !this.hasAttribute('open')) { @@ -1311,8 +1311,8 @@ customElements.define('sm-popup', class extends HTMLElement { } }); resizeObserver.observe(this) - - + + this.popupHeader.addEventListener('touchstart', (e) => { this.handleTouchStart(e) }, { passive: true }) this.popupHeader.addEventListener('touchmove', (e) => { this.handleTouchMove(e) }, { passive: true }) this.popupHeader.addEventListener('touchend', (e) => { this.handleTouchEnd(e) }, { passive: true }) @@ -1487,7 +1487,7 @@ class ThemeToggle extends HTMLElement { document.body.dataset.theme = 'light' this.setAttribute('aria-checked', 'false') } - + nightlight() { this.hasTheme = 'dark' document.body.dataset.theme = 'dark' @@ -1509,7 +1509,7 @@ class ThemeToggle extends HTMLElement { this.setAttribute('checked', '') } else { - this.removeAttribute('checked') + this.removeAttribute('checked') } } } @@ -1549,7 +1549,7 @@ class ThemeToggle extends HTMLElement { this.addEventListener("keydown", this.handleKeyDown); document.addEventListener('themechange', this.handleThemeChange) } - + disconnectedCallback() { this.removeEventListener("click", this.toggleState); this.removeEventListener("keydown", this.handleKeyDown); @@ -1648,7 +1648,7 @@ customElements.define('sm-copy', this.attachShadow({ mode: 'open' }).append(smCopy.content.cloneNode(true)) - + this.copyContent = this.shadowRoot.querySelector('.copy-content') this.copyButton = this.shadowRoot.querySelector('.copy-button') diff --git a/css/main.css b/css/main.css index 0e9939e..f421d1a 100644 --- a/css/main.css +++ b/css/main.css @@ -579,6 +579,7 @@ details[open] > summary .icon { } .quick-action { + color: inherit; display: -webkit-box; display: -ms-flexbox; display: flex; @@ -722,21 +723,34 @@ details[open] > summary .icon { .status-tag:not(:empty) .icon { margin-right: 0.3rem; } -.status-tag:not(:empty).success, .status-tag:not(:empty).active { +.status-tag:not(:empty).active { color: var(--green); background-color: rgba(0, 230, 118, 0.1); } +.status-tag:not(:empty).closed { + color: rgba(var(--text-color), 0.7); + background-color: rgba(var(--text-color), 0.06); +} +.status-tag:not(:empty).success { + color: var(--green); + background-color: rgba(0, 230, 118, 0.1); +} +.status-tag:not(:empty).success .icon { + fill: var(--green); +} .status-tag:not(:empty).failed { color: var(--danger-color); background-color: rgba(255, 75, 75, 0.1); } +.status-tag:not(:empty).failed .icon { + fill: var(--danger-color); +} .status-tag:not(:empty).pending { color: var(--yellow); background-color: rgba(255, 252, 75, 0.1); } -.status-tag:not(:empty).closed { - color: rgba(var(--text-color), 0.7); - background-color: rgba(var(--text-color), 0.06); +.status-tag:not(:empty).pending .icon { + fill: var(--yellow); } .activity-card--response { @@ -758,14 +772,14 @@ details[open] > summary .icon { fill: var(--green); } -.pending .icon { - fill: var(--yellow); -} - .failed .icon { fill: var(--danger-color); } +.pending .icon { + fill: var(--yellow); +} + #user_section { display: grid; -ms-flex-line-pack: start; @@ -950,7 +964,6 @@ details[open] > summary .icon { .account-step { opacity: 0; grid-template-columns: auto minmax(0, 1fr); - grid-template-areas: "step-icon step-title" ". step-description"; gap: 0.3rem 0.8rem; -webkit-animation: slide-down 0.3s forwards; animation: slide-down 0.3s forwards; @@ -971,31 +984,24 @@ details[open] > summary .icon { --height: 1rem; --width: 1rem; } -.account-step:not(:last-of-type)::after { +.account-step:not(:last-of-type) .step__line { position: relative; - content: ""; height: 3rem; width: 0.1rem; margin: 0.5rem 0 1rem 0; - margin-left: 0.7rem; + justify-self: center; background-color: var(--green); } -.account-step .step__icon { - grid-area: step-icon; -} .account-step .icon { height: 1.5rem; width: 1.5rem; } .account-step:not(.loading) .step__title { - text-transform: capitalize; - grid-area: step-title; font-weight: 500; font-size: 0.9rem; padding: 0.2rem 0; } .account-step .step__description { - grid-area: step-description; font-size: 0.8rem; } @@ -1024,6 +1030,104 @@ details[open] > summary .icon { transform: none; } } +#deposit, +#loan { + padding: 1.5rem 0; + grid-template-rows: auto 1fr; +} +#deposit sm-form, +#loan sm-form { + justify-self: center; + margin-top: 3rem; + width: min(24rem, 100%); +} +#deposit sm-form::part(form), +#loan sm-form::part(form) { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} + +#deposit__icon .icon, +#loan__icon .icon { + height: 1.8rem; + width: 1.8rem; + fill: var(--accent-color); +} + +#get_deposit_amount, +#get_loan_amount { + --font-size: 1.5rem; + margin-top: 1rem; +} + +#result { + place-content: center; +} +#result section { + text-align: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} +#result__icon { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + border-radius: 50%; + padding: 1rem; + margin: -5rem 0 1.5rem 0; + -webkit-animation: pop-in 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275); + animation: pop-in 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275); +} +#result__icon .icon { + height: 1.8rem; + width: 1.8rem; +} +#result__description { + margin: 0.5rem 0; +} +#result__back_button { + margin-top: 3rem; +} + +@-webkit-keyframes pop-in { + 0% { + opacity: 0; + -webkit-transform: scale(0.4) translateY(6rem); + transform: scale(0.4) translateY(6rem); + } + 40% { + opacity: 1; + -webkit-transform: scale(0.4) translateY(0); + transform: scale(0.4) translateY(0); + } + 100% { + -webkit-transform: none; + transform: none; + } +} + +@keyframes pop-in { + 0% { + opacity: 0; + -webkit-transform: scale(0.4) translateY(6rem); + transform: scale(0.4) translateY(6rem); + } + 40% { + opacity: 1; + -webkit-transform: scale(0.4) translateY(0); + transform: scale(0.4) translateY(0); + } + 100% { + -webkit-transform: none; + transform: none; + } +} @media screen and (max-width: 640px) { sm-button { --padding: 1rem; @@ -1058,7 +1162,8 @@ details[open] > summary .icon { } #transaction_action_button, -#account_action_button { +#account_action_button, +#deposit_button { margin-top: auto; } diff --git a/css/main.min.css b/css/main.min.css index 86b84c1..c9eb0e7 100644 --- a/css/main.min.css +++ b/css/main.min.css @@ -1 +1 @@ -*{padding:0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:"Roboto",sans-serif}:root{font-size:clamp(1rem, 1.2vmax, 3rem)}html,body{height:100%;scroll-behavior:smooth}body{color:rgba(var(--text-color), 1);background:rgba(var(--background-color), 1)}body,body *{--accent-color: #2672ff;--accent-color--light: rgba(38, 114, 255, 0.06);--text-color: 36, 36, 36;--background-color: 247, 250, 255;--foreground-color: rgb(250, 252, 255);--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: #f3a600;scrollbar-width:thin}body[data-theme=dark],body[data-theme=dark] *{--accent-color: rgb(170, 190, 255);--accent-color--light: rgba(231, 239, 255, 0.06);--text-color: 230, 230, 230;--text-color-light: 170, 170, 170;--background-color: 10, 10, 10;--foreground-color: rgb(20, 20, 20);--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: #ffd13a}p{font-size:.9rem;max-width:70ch;line-height:1.7;color:rgba(var(--text-color), 0.8)}p:not(:last-of-type){margin-bottom:1.5rem}a:where([class]){color:inherit;text-decoration:none}a:where([class]):focus-visible{-webkit-box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset;box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}a{color:var(--accent-color)}button,.button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;border:none;background-color:transparent;overflow:hidden;color:inherit;cursor:pointer;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s}.button{padding:.4rem .6rem;border-radius:.3rem;font-weight:500;font-size:.8rem;border:solid thin rgba(var(--text-color), 0.5)}button:disabled{opacity:.5}a:-webkit-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-moz-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}sm-button{--border-radius: 0.5rem;--padding: 0.8rem 1rem}sm-button[variant=primary] .icon{fill:rgba(var(--background-color), 1)}sm-button[disabled] .icon{fill:rgba(var(--text-color), 0.6)}ul{list-style:none}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.grid{display:grid}.hide{opacity:0;pointer-events:none}.hide-completely{display:none !important}.no-transformations{-webkit-transform:none !important;transform:none !important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.full-bleed{grid-column:1/4}.h1{font-size:2.5rem}.h2{font-size:2rem}.h3{font-size:1.4rem}.h4{font-size:1rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.text-center{text-align:center}.justify-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:start}.justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-right{margin-left:auto}.align-self-center{-ms-flex-item-align:center;align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.space-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.stretch{-webkit-box-pack:stretch;-ms-flex-pack:stretch;justify-content:stretch;justify-items:stretch}.stretch>*{width:100%}.ripple{position:absolute;border-radius:50%;-webkit-transform:scale(0);transform:scale(0);background:rgba(var(--text-color), 0.16);pointer-events:none}.interact{position:relative;cursor:pointer;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s;-webkit-tap-highlight-color:transparent}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}.icon{width:1.2rem;height:1.2rem;fill:rgba(var(--text-color), 0.8)}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.button__icon--right{margin-left:.5rem}.icon-button{padding:.6rem;border-radius:.8rem;background-color:var(--accent-color--light)}.icon-button .icon{fill:var(--accent-color)}#confirmation_popup,#prompt_popup{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-weight:500;margin-bottom:.5rem}#confirmation_popup sm-button,#prompt_popup sm-button{margin:0}#confirmation_popup .flex,#prompt_popup .flex{padding:0;margin-top:1rem}#confirmation_popup .flex sm-button:first-of-type,#prompt_popup .flex sm-button:first-of-type{margin-right:.6rem;margin-left:auto}button:active,.button:active,.interact:active,.nav-item:active{-webkit-transform:scale(0.96);transform:scale(0.96)}#main_page{padding:1.5rem}#main_page>section:nth-of-type(1){-ms-flex-line-pack:start;align-content:flex-start}#logo{display:grid;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;grid-template-columns:auto 1fr;gap:0 .3rem;margin-right:1rem}#logo h4{text-transform:capitalize;font-size:1rem;font-weight:600}#logo #main_logo{height:1.4rem;width:1.4rem;fill:rgba(var(--text-color), 1);stroke:none}details summary{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer}details[open]>summary{margin-bottom:1rem}details[open]>summary .icon{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.card{padding:1rem;border-radius:.5rem;background-color:var(--accent-color--light)}.page-layout{display:grid;grid-template-columns:1.5rem minmax(0, 1fr) 1.5rem}.page-layout>*{grid-column:2/3}.page{height:100%}#sign_in,#sign_up{place-items:center}#sign_in section,#sign_up section{width:min(24rem, 100%)}#sign_in sm-form,#sign_up sm-form{margin:2rem 0}#sign_up sm-copy{font-size:.9rem;--button-border-radius: 0.5rem}#sign_up .h2{margin-bottom:.5rem}#sign_up .card{margin:1.5rem 0}#sign_up h5{font-weight:500;color:rgba(var(--text-color), 0.8)}#loading{place-content:center;text-align:center}#loading sm-spinner{margin-bottom:1.5rem}#homepage{height:100%;display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:minmax(0, 1fr);grid-template-areas:"main-header" "subpages" "main-nav"}#main_nav{grid-area:main-nav;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex}.nav-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:.8rem;border-radius:.5rem;color:inherit;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.nav-item--active .icon{fill:var(--accent-color)}.nav-item--active .nav-item__title{color:var(--accent-color)}#main_header{grid-area:main-header;padding:1.5rem;display:grid;gap:1rem;-webkit-box-align:center;-ms-flex-align:center;align-items:center;grid-template-columns:1fr auto auto}#subpage_container{grid-area:subpages;overflow-y:auto}#dashboard{display:grid;gap:1.5rem;padding:0 1.5rem}#quick_actions_container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:1.5rem;margin:2rem 0}.quick-action{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.quick-action__icon{padding:1rem;border-radius:1rem;background-color:var(--accent-color--light);margin-bottom:.8rem}.quick-action__icon .icon{height:1.5rem;width:1.5rem;fill:var(--accent-color)}.quick-action__title{font-size:.8rem;font-weight:500}#recent_transactions_container{display:grid;margin:1.5rem 0;padding-bottom:5rem}.activity-card{display:grid;padding:1rem 0;gap:.4rem 1rem;border-radius:.5rem;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;color:inherit;grid-template-columns:auto minmax(0, 1fr) auto}.activity-card__icon{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-line-pack:center;align-content:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:.5rem;border-radius:.8rem;background-color:var(--accent-color--light)}.activity-card__icon .icon{height:1.3rem;width:1.3rem;fill:var(--accent-color)}.activity-card__title{font-size:.95rem;font-weight:500}.activity-card__title::first-letter{text-transform:uppercase}.activity-card__time{font-size:.8rem;color:rgba(var(--text-color), 0.8)}#notifications,#history{padding-bottom:5rem}#notifications .activity-card,#history .activity-card{padding:1rem 1.5rem}#user_accounts{margin-top:1.5rem;display:grid;gap:1rem;padding-bottom:5rem;grid-template-columns:repeat(auto-fill, minmax(12rem, 1fr))}.activity-card--account{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;gap:1.5rem;padding:1.5rem;background-color:var(--foreground-color);border:solid thin rgba(var(--text-color), 0.2);grid-template-columns:minmax(0, 1fr)}.activity-card--account .activity-card__icon{padding:0;margin-bottom:.5rem;background-color:transparent}.activity-card--account .activity-card__type{font-size:.9rem;color:rgba(var(--text-color), 0.6);font-weight:500}.activity-card--account .activity-card__amount{margin-top:.3rem;font-size:1.3rem}.activity-card--request{grid-template-areas:"icon . amount" "icon time ."}.activity-card--request .activity-card__icon{grid-area:icon}.activity-card--request .activity-card__time{grid-area:time}.activity-card--request .activity-card__amount{grid-area:amount;text-align:end}.status-tag:not(:empty){text-transform:uppercase;letter-spacing:.05em;font-size:.7rem;border-radius:.2rem;padding:.3rem .4rem;font-weight:500;color:rgba(0,0,0,.7)}.status-tag:not(:empty) .icon{margin-right:.3rem}.status-tag:not(:empty).success,.status-tag:not(:empty).active{color:var(--green);background-color:rgba(0,230,118,.1)}.status-tag:not(:empty).failed{color:var(--danger-color);background-color:rgba(255,75,75,.1)}.status-tag:not(:empty).pending{color:var(--yellow);background-color:rgba(255,252,75,.1)}.status-tag:not(:empty).closed{color:rgba(var(--text-color), 0.7);background-color:rgba(var(--text-color), 0.06)}.activity-card--response{grid-template-areas:"icon . time" "icon description description"}.activity-card--response .activity-card__icon{grid-area:icon}.activity-card--response .activity-card__description{grid-area:description;font-size:.8rem;color:rgba(var(--text-color), 0.8)}.activity-card--response .activity-card__time{grid-area:time}.success .icon{fill:var(--green)}.pending .icon{fill:var(--yellow)}.failed .icon{fill:var(--danger-color)}#user_section{display:grid;-ms-flex-line-pack:start;align-content:flex-start;gap:2rem;overflow-y:auto;padding:1.5rem;grid-template-columns:minmax(0, 1fr)}#user_section h4{margin-bottom:1rem}#account_chart_container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:15rem;padding-bottom:3rem;margin:1.5rem 0}#chart_legend{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:1rem}.legend{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:.8rem;margin-right:1rem;margin-bottom:1rem}.legend::before{content:"";margin-right:.5rem;width:1rem;height:1rem;border-radius:25%}.legend:nth-of-type(1)::before{background-color:var(--green)}.legend:nth-of-type(2)::before{background-color:#ffbb61}.balance-card{display:grid;grid-template-columns:auto 1fr;grid-template-areas:"icon ." "icon .";padding:1rem 0;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:.3rem 1rem;border-radius:.5rem}.balance-card__icon{grid-area:icon;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-line-pack:center;align-content:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:.5rem;border-radius:.8rem;background-color:var(--accent-color--light)}.balance-card__icon .icon{height:1.3rem;width:1.3rem;fill:var(--accent-color)}.balance-card__token{font-size:.8rem}.balance-card__amount{font-size:1rem;font-weight:700}#transaction,#account{grid-template-rows:auto 1fr;gap:1.5rem 0;padding:1.5rem 0;-ms-flex-line-pack:start;align-content:flex-start}#transaction section,#account_details{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}#transaction_top,#account_top{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;justify-items:flex-start;position:relative}#transaction_detail__icon,#account_detail__icon{display:-webkit-box;display:-ms-flexbox;display:flex;background-color:var(--accent-color);border-radius:40%;padding:.8rem;justify-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}#transaction_detail__icon .icon,#account_detail__icon .icon{height:1.5rem;width:1.5rem;fill:rgba(var(--background-color), 1)}#transaction_detail__amount,#account_detail__amount{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:1.8rem;font-weight:700}#transaction_detail__time{font-size:.8rem;color:rgba(var(--text-color), 0.8);margin-right:1rem}#account_process{display:grid;-ms-flex-line-pack:start;align-content:flex-start;gap:2rem}.account-step{opacity:0;grid-template-columns:auto minmax(0, 1fr);grid-template-areas:"step-icon step-title" ". step-description";gap:.3rem .8rem;-webkit-animation:slide-down .3s forwards;animation:slide-down .3s forwards}.account-step:nth-of-type(2){-webkit-animation-delay:.1s;animation-delay:.1s}.account-step:nth-of-type(3){-webkit-animation-delay:.2s;animation-delay:.2s}.account-step:nth-of-type(4){-webkit-animation-delay:.3s;animation-delay:.3s}.account-step sm-spinner{--height: 1rem;--width: 1rem}.account-step:not(:last-of-type)::after{position:relative;content:"";height:3rem;width:.1rem;margin:.5rem 0 1rem 0;margin-left:.7rem;background-color:var(--green)}.account-step .step__icon{grid-area:step-icon}.account-step .icon{height:1.5rem;width:1.5rem}.account-step:not(.loading) .step__title{text-transform:capitalize;grid-area:step-title;font-weight:500;font-size:.9rem;padding:.2rem 0}.account-step .step__description{grid-area:step-description;font-size:.8rem}@-webkit-keyframes slide-down{from{opacity:0;-webkit-transform:translateY(-1rem);transform:translateY(-1rem)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes slide-down{from{opacity:0;-webkit-transform:translateY(-1rem);transform:translateY(-1rem)}to{opacity:1;-webkit-transform:none;transform:none}}@media screen and (max-width: 640px){sm-button{--padding: 1rem}#dashboard{padding:0 1.5rem}#main_nav{border-radius:1rem 1rem 0 0;background-color:var(--foreground-color)}.nav-item{-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.nav-item__title{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:.7rem;font-weight:500;color:rgba(var(--text-color), 0.8);margin-top:.3rem}#transaction_action_button,#account_action_button{margin-top:auto}#account_process{margin-top:3rem}}@media screen and (min-width: 640px){#confirmation_popup,#prompt_popup{--width: 24rem}.page-layout{grid-template-columns:1fr 90vw 1fr}#homepage{background-color:var(--foreground-color);grid-template-rows:auto 1fr;grid-template-columns:auto minmax(0, 1fr);grid-template-areas:"main-header main-header user-section" "main-nav subpages user-section"}#main_nav{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:0 1rem}#main_nav::after{position:absolute;right:0;content:"";width:1px;background-color:rgba(var(--text-color), 0.3);height:80%}.nav-item--active{background-color:var(--accent-color--light)}.nav-item:not(:last-of-type){margin-bottom:.5rem}.nav-item:last-of-type{margin-top:auto;margin-bottom:1.5rem}.nav-item__title{display:none}#user_section{grid-area:user-section;background-color:rgba(var(--background-color), 1)}#transaction_top,#account_top,#account_process{overflow:hidden;padding:1.8rem;border-radius:.5rem;border:solid thin rgba(var(--text-color), 0.2)}#transaction_detail__status{justify-self:flex-start}#transaction_detail__icon{justify-self:flex-start}}@media screen and (max-width: 1024px){#user_section{position:fixed;background-color:rgba(var(--background-color), 1);z-index:2;-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@media screen and (min-width: 1024px){.page-layout{grid-template-columns:1fr 80vw 1fr}.card{padding:2rem}#homepage{grid-template-columns:14rem minmax(0, 1fr) 24rem}.nav-item__title{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:.9rem;font-weight:500;color:rgba(var(--text-color), 0.8);margin-left:.5rem}#transaction section,#account_details{display:grid;gap:1.5rem;grid-template-columns:18rem minmax(0, 1fr)}}@media screen and (min-width: 1920px){.page-layout{grid-template-columns:1fr 70vw 1fr}}@media(any-hover: hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color), 0.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color), 0.5)}.nav-item,.interact{-webkit-transition:background-color .3s,-webkit-transform .3s;transition:background-color .3s,-webkit-transform .3s;transition:background-color .3s,transform .3s;transition:background-color .3s,transform .3s,-webkit-transform .3s}.nav-item:hover,.interact:hover{background-color:var(--accent-color--light)}} \ No newline at end of file +*{padding:0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:"Roboto",sans-serif}:root{font-size:clamp(1rem, 1.2vmax, 3rem)}html,body{height:100%;scroll-behavior:smooth}body{color:rgba(var(--text-color), 1);background:rgba(var(--background-color), 1)}body,body *{--accent-color: #2672ff;--accent-color--light: rgba(38, 114, 255, 0.06);--text-color: 36, 36, 36;--background-color: 247, 250, 255;--foreground-color: rgb(250, 252, 255);--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: #f3a600;scrollbar-width:thin}body[data-theme=dark],body[data-theme=dark] *{--accent-color: rgb(170, 190, 255);--accent-color--light: rgba(231, 239, 255, 0.06);--text-color: 230, 230, 230;--text-color-light: 170, 170, 170;--background-color: 10, 10, 10;--foreground-color: rgb(20, 20, 20);--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: #ffd13a}p{font-size:.9rem;max-width:70ch;line-height:1.7;color:rgba(var(--text-color), 0.8)}p:not(:last-of-type){margin-bottom:1.5rem}a:where([class]){color:inherit;text-decoration:none}a:where([class]):focus-visible{-webkit-box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset;box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}a{color:var(--accent-color)}button,.button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;border:none;background-color:transparent;overflow:hidden;color:inherit;cursor:pointer;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s}.button{padding:.4rem .6rem;border-radius:.3rem;font-weight:500;font-size:.8rem;border:solid thin rgba(var(--text-color), 0.5)}button:disabled{opacity:.5}a:-webkit-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-moz-any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:any-link:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}sm-button{--border-radius: 0.5rem;--padding: 0.8rem 1rem}sm-button[variant=primary] .icon{fill:rgba(var(--background-color), 1)}sm-button[disabled] .icon{fill:rgba(var(--text-color), 0.6)}ul{list-style:none}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.grid{display:grid}.hide{opacity:0;pointer-events:none}.hide-completely{display:none !important}.no-transformations{-webkit-transform:none !important;transform:none !important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.full-bleed{grid-column:1/4}.h1{font-size:2.5rem}.h2{font-size:2rem}.h3{font-size:1.4rem}.h4{font-size:1rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.text-center{text-align:center}.justify-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:start}.justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-right{margin-left:auto}.align-self-center{-ms-flex-item-align:center;align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.space-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.stretch{-webkit-box-pack:stretch;-ms-flex-pack:stretch;justify-content:stretch;justify-items:stretch}.stretch>*{width:100%}.ripple{position:absolute;border-radius:50%;-webkit-transform:scale(0);transform:scale(0);background:rgba(var(--text-color), 0.16);pointer-events:none}.interact{position:relative;cursor:pointer;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s;-webkit-tap-highlight-color:transparent}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}.icon{width:1.2rem;height:1.2rem;fill:rgba(var(--text-color), 0.8)}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.button__icon--right{margin-left:.5rem}.icon-button{padding:.6rem;border-radius:.8rem;background-color:var(--accent-color--light)}.icon-button .icon{fill:var(--accent-color)}#confirmation_popup,#prompt_popup{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-weight:500;margin-bottom:.5rem}#confirmation_popup sm-button,#prompt_popup sm-button{margin:0}#confirmation_popup .flex,#prompt_popup .flex{padding:0;margin-top:1rem}#confirmation_popup .flex sm-button:first-of-type,#prompt_popup .flex sm-button:first-of-type{margin-right:.6rem;margin-left:auto}button:active,.button:active,.interact:active,.nav-item:active{-webkit-transform:scale(0.96);transform:scale(0.96)}#main_page{padding:1.5rem}#main_page>section:nth-of-type(1){-ms-flex-line-pack:start;align-content:flex-start}#logo{display:grid;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;grid-template-columns:auto 1fr;gap:0 .3rem;margin-right:1rem}#logo h4{text-transform:capitalize;font-size:1rem;font-weight:600}#logo #main_logo{height:1.4rem;width:1.4rem;fill:rgba(var(--text-color), 1);stroke:none}details summary{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer}details[open]>summary{margin-bottom:1rem}details[open]>summary .icon{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.card{padding:1rem;border-radius:.5rem;background-color:var(--accent-color--light)}.page-layout{display:grid;grid-template-columns:1.5rem minmax(0, 1fr) 1.5rem}.page-layout>*{grid-column:2/3}.page{height:100%}#sign_in,#sign_up{place-items:center}#sign_in section,#sign_up section{width:min(24rem, 100%)}#sign_in sm-form,#sign_up sm-form{margin:2rem 0}#sign_up sm-copy{font-size:.9rem;--button-border-radius: 0.5rem}#sign_up .h2{margin-bottom:.5rem}#sign_up .card{margin:1.5rem 0}#sign_up h5{font-weight:500;color:rgba(var(--text-color), 0.8)}#loading{place-content:center;text-align:center}#loading sm-spinner{margin-bottom:1.5rem}#homepage{height:100%;display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:minmax(0, 1fr);grid-template-areas:"main-header" "subpages" "main-nav"}#main_nav{grid-area:main-nav;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex}.nav-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:.8rem;border-radius:.5rem;color:inherit;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s, -webkit-transform .3s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.nav-item--active .icon{fill:var(--accent-color)}.nav-item--active .nav-item__title{color:var(--accent-color)}#main_header{grid-area:main-header;padding:1.5rem;display:grid;gap:1rem;-webkit-box-align:center;-ms-flex-align:center;align-items:center;grid-template-columns:1fr auto auto}#subpage_container{grid-area:subpages;overflow-y:auto}#dashboard{display:grid;gap:1.5rem;padding:0 1.5rem}#quick_actions_container{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:1.5rem;margin:2rem 0}.quick-action{color:inherit;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.quick-action__icon{padding:1rem;border-radius:1rem;background-color:var(--accent-color--light);margin-bottom:.8rem}.quick-action__icon .icon{height:1.5rem;width:1.5rem;fill:var(--accent-color)}.quick-action__title{font-size:.8rem;font-weight:500}#recent_transactions_container{display:grid;margin:1.5rem 0;padding-bottom:5rem}.activity-card{display:grid;padding:1rem 0;gap:.4rem 1rem;border-radius:.5rem;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;color:inherit;grid-template-columns:auto minmax(0, 1fr) auto}.activity-card__icon{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-line-pack:center;align-content:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:.5rem;border-radius:.8rem;background-color:var(--accent-color--light)}.activity-card__icon .icon{height:1.3rem;width:1.3rem;fill:var(--accent-color)}.activity-card__title{font-size:.95rem;font-weight:500}.activity-card__title::first-letter{text-transform:uppercase}.activity-card__time{font-size:.8rem;color:rgba(var(--text-color), 0.8)}#notifications,#history{padding-bottom:5rem}#notifications .activity-card,#history .activity-card{padding:1rem 1.5rem}#user_accounts{margin-top:1.5rem;display:grid;gap:1rem;padding-bottom:5rem;grid-template-columns:repeat(auto-fill, minmax(12rem, 1fr))}.activity-card--account{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;gap:1.5rem;padding:1.5rem;background-color:var(--foreground-color);border:solid thin rgba(var(--text-color), 0.2);grid-template-columns:minmax(0, 1fr)}.activity-card--account .activity-card__icon{padding:0;margin-bottom:.5rem;background-color:transparent}.activity-card--account .activity-card__type{font-size:.9rem;color:rgba(var(--text-color), 0.6);font-weight:500}.activity-card--account .activity-card__amount{margin-top:.3rem;font-size:1.3rem}.activity-card--request{grid-template-areas:"icon . amount" "icon time ."}.activity-card--request .activity-card__icon{grid-area:icon}.activity-card--request .activity-card__time{grid-area:time}.activity-card--request .activity-card__amount{grid-area:amount;text-align:end}.status-tag:not(:empty){text-transform:uppercase;letter-spacing:.05em;font-size:.7rem;border-radius:.2rem;padding:.3rem .4rem;font-weight:500;color:rgba(0,0,0,.7)}.status-tag:not(:empty) .icon{margin-right:.3rem}.status-tag:not(:empty).active{color:var(--green);background-color:rgba(0,230,118,.1)}.status-tag:not(:empty).closed{color:rgba(var(--text-color), 0.7);background-color:rgba(var(--text-color), 0.06)}.status-tag:not(:empty).success{color:var(--green);background-color:rgba(0,230,118,.1)}.status-tag:not(:empty).success .icon{fill:var(--green)}.status-tag:not(:empty).failed{color:var(--danger-color);background-color:rgba(255,75,75,.1)}.status-tag:not(:empty).failed .icon{fill:var(--danger-color)}.status-tag:not(:empty).pending{color:var(--yellow);background-color:rgba(255,252,75,.1)}.status-tag:not(:empty).pending .icon{fill:var(--yellow)}.activity-card--response{grid-template-areas:"icon . time" "icon description description"}.activity-card--response .activity-card__icon{grid-area:icon}.activity-card--response .activity-card__description{grid-area:description;font-size:.8rem;color:rgba(var(--text-color), 0.8)}.activity-card--response .activity-card__time{grid-area:time}.success .icon{fill:var(--green)}.failed .icon{fill:var(--danger-color)}.pending .icon{fill:var(--yellow)}#user_section{display:grid;-ms-flex-line-pack:start;align-content:flex-start;gap:2rem;overflow-y:auto;padding:1.5rem;grid-template-columns:minmax(0, 1fr)}#user_section h4{margin-bottom:1rem}#account_chart_container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:15rem;padding-bottom:3rem;margin:1.5rem 0}#chart_legend{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:1rem}.legend{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:.8rem;margin-right:1rem;margin-bottom:1rem}.legend::before{content:"";margin-right:.5rem;width:1rem;height:1rem;border-radius:25%}.legend:nth-of-type(1)::before{background-color:var(--green)}.legend:nth-of-type(2)::before{background-color:#ffbb61}.balance-card{display:grid;grid-template-columns:auto 1fr;grid-template-areas:"icon ." "icon .";padding:1rem 0;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:.3rem 1rem;border-radius:.5rem}.balance-card__icon{grid-area:icon;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-line-pack:center;align-content:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:.5rem;border-radius:.8rem;background-color:var(--accent-color--light)}.balance-card__icon .icon{height:1.3rem;width:1.3rem;fill:var(--accent-color)}.balance-card__token{font-size:.8rem}.balance-card__amount{font-size:1rem;font-weight:700}#transaction,#account{grid-template-rows:auto 1fr;gap:1.5rem 0;padding:1.5rem 0;-ms-flex-line-pack:start;align-content:flex-start}#transaction section,#account_details{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}#transaction_top,#account_top{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;justify-items:flex-start;position:relative}#transaction_detail__icon,#account_detail__icon{display:-webkit-box;display:-ms-flexbox;display:flex;background-color:var(--accent-color);border-radius:40%;padding:.8rem;justify-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}#transaction_detail__icon .icon,#account_detail__icon .icon{height:1.5rem;width:1.5rem;fill:rgba(var(--background-color), 1)}#transaction_detail__amount,#account_detail__amount{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:1.8rem;font-weight:700}#transaction_detail__time{font-size:.8rem;color:rgba(var(--text-color), 0.8);margin-right:1rem}#account_process{display:grid;-ms-flex-line-pack:start;align-content:flex-start;gap:2rem}.account-step{opacity:0;grid-template-columns:auto minmax(0, 1fr);gap:.3rem .8rem;-webkit-animation:slide-down .3s forwards;animation:slide-down .3s forwards}.account-step:nth-of-type(2){-webkit-animation-delay:.1s;animation-delay:.1s}.account-step:nth-of-type(3){-webkit-animation-delay:.2s;animation-delay:.2s}.account-step:nth-of-type(4){-webkit-animation-delay:.3s;animation-delay:.3s}.account-step sm-spinner{--height: 1rem;--width: 1rem}.account-step:not(:last-of-type) .step__line{position:relative;height:3rem;width:.1rem;margin:.5rem 0 1rem 0;justify-self:center;background-color:var(--green)}.account-step .icon{height:1.5rem;width:1.5rem}.account-step:not(.loading) .step__title{font-weight:500;font-size:.9rem;padding:.2rem 0}.account-step .step__description{font-size:.8rem}@-webkit-keyframes slide-down{from{opacity:0;-webkit-transform:translateY(-1rem);transform:translateY(-1rem)}to{opacity:1;-webkit-transform:none;transform:none}}@keyframes slide-down{from{opacity:0;-webkit-transform:translateY(-1rem);transform:translateY(-1rem)}to{opacity:1;-webkit-transform:none;transform:none}}#deposit,#loan{padding:1.5rem 0;grid-template-rows:auto 1fr}#deposit sm-form,#loan sm-form{justify-self:center;margin-top:3rem;width:min(24rem, 100%)}#deposit sm-form::part(form),#loan sm-form::part(form){display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}#deposit__icon .icon,#loan__icon .icon{height:1.8rem;width:1.8rem;fill:var(--accent-color)}#get_deposit_amount,#get_loan_amount{--font-size: 1.5rem;margin-top:1rem}#result{place-content:center}#result section{text-align:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}#result__icon{display:-webkit-box;display:-ms-flexbox;display:flex;border-radius:50%;padding:1rem;margin:-5rem 0 1.5rem 0;-webkit-animation:pop-in 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275);animation:pop-in 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275)}#result__icon .icon{height:1.8rem;width:1.8rem}#result__description{margin:.5rem 0}#result__back_button{margin-top:3rem}@-webkit-keyframes pop-in{0%{opacity:0;-webkit-transform:scale(0.4) translateY(6rem);transform:scale(0.4) translateY(6rem)}40%{opacity:1;-webkit-transform:scale(0.4) translateY(0);transform:scale(0.4) translateY(0)}100%{-webkit-transform:none;transform:none}}@keyframes pop-in{0%{opacity:0;-webkit-transform:scale(0.4) translateY(6rem);transform:scale(0.4) translateY(6rem)}40%{opacity:1;-webkit-transform:scale(0.4) translateY(0);transform:scale(0.4) translateY(0)}100%{-webkit-transform:none;transform:none}}@media screen and (max-width: 640px){sm-button{--padding: 1rem}#dashboard{padding:0 1.5rem}#main_nav{border-radius:1rem 1rem 0 0;background-color:var(--foreground-color)}.nav-item{-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.nav-item__title{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:.7rem;font-weight:500;color:rgba(var(--text-color), 0.8);margin-top:.3rem}#transaction_action_button,#account_action_button,#deposit_button{margin-top:auto}#account_process{margin-top:3rem}}@media screen and (min-width: 640px){#confirmation_popup,#prompt_popup{--width: 24rem}.page-layout{grid-template-columns:1fr 90vw 1fr}#homepage{background-color:var(--foreground-color);grid-template-rows:auto 1fr;grid-template-columns:auto minmax(0, 1fr);grid-template-areas:"main-header main-header user-section" "main-nav subpages user-section"}#main_nav{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:0 1rem}#main_nav::after{position:absolute;right:0;content:"";width:1px;background-color:rgba(var(--text-color), 0.3);height:80%}.nav-item--active{background-color:var(--accent-color--light)}.nav-item:not(:last-of-type){margin-bottom:.5rem}.nav-item:last-of-type{margin-top:auto;margin-bottom:1.5rem}.nav-item__title{display:none}#user_section{grid-area:user-section;background-color:rgba(var(--background-color), 1)}#transaction_top,#account_top,#account_process{overflow:hidden;padding:1.8rem;border-radius:.5rem;border:solid thin rgba(var(--text-color), 0.2)}#transaction_detail__status{justify-self:flex-start}#transaction_detail__icon{justify-self:flex-start}}@media screen and (max-width: 1024px){#user_section{position:fixed;background-color:rgba(var(--background-color), 1);z-index:2;-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@media screen and (min-width: 1024px){.page-layout{grid-template-columns:1fr 80vw 1fr}.card{padding:2rem}#homepage{grid-template-columns:14rem minmax(0, 1fr) 24rem}.nav-item__title{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:.9rem;font-weight:500;color:rgba(var(--text-color), 0.8);margin-left:.5rem}#transaction section,#account_details{display:grid;gap:1.5rem;grid-template-columns:18rem minmax(0, 1fr)}}@media screen and (min-width: 1920px){.page-layout{grid-template-columns:1fr 70vw 1fr}}@media(any-hover: hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color), 0.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color), 0.5)}.nav-item,.interact{-webkit-transition:background-color .3s,-webkit-transform .3s;transition:background-color .3s,-webkit-transform .3s;transition:background-color .3s,transform .3s;transition:background-color .3s,transform .3s,-webkit-transform .3s}.nav-item:hover,.interact:hover{background-color:var(--accent-color--light)}} \ No newline at end of file diff --git a/css/main.scss b/css/main.scss index d0aea8e..93a6651 100644 --- a/css/main.scss +++ b/css/main.scss @@ -512,6 +512,7 @@ details { margin: 2rem 0; } .quick-action { + color: inherit; display: flex; flex-direction: column; align-items: center; @@ -629,22 +630,34 @@ details { .icon { margin-right: 0.3rem; } - &.success, &.active { color: var(--green); background-color: rgb(0, 230, 118, 0.1); } + &.closed { + color: rgba(var(--text-color), 0.7); + background-color: rgba(var(--text-color), 0.06); + } + &.success { + color: var(--green); + background-color: rgb(0, 230, 118, 0.1); + .icon { + fill: var(--green); + } + } &.failed { color: var(--danger-color); background-color: rgb(255, 75, 75, 0.1); + .icon { + fill: var(--danger-color); + } } &.pending { color: var(--yellow); background-color: rgba(255, 252, 75, 0.1); - } - &.closed { - color: rgba(var(--text-color), 0.7); - background-color: rgba(var(--text-color), 0.06); + .icon { + fill: var(--yellow); + } } } .activity-card--response { @@ -666,16 +679,16 @@ details { fill: var(--green); } } -.pending { - .icon { - fill: var(--yellow); - } -} .failed { .icon { fill: var(--danger-color); } } +.pending { + .icon { + fill: var(--yellow); + } +} #user_section { display: grid; align-content: flex-start; @@ -810,7 +823,6 @@ details { .account-step { opacity: 0; grid-template-columns: auto minmax(0, 1fr); - grid-template-areas: "step-icon step-title" ". step-description"; gap: 0.3rem 0.8rem; animation: slide-down 0.3s forwards; &:nth-of-type(2) { @@ -826,33 +838,26 @@ details { --height: 1rem; --width: 1rem; } - &:not(:last-of-type)::after { + &:not(:last-of-type) .step__line { position: relative; - content: ""; height: 3rem; width: 0.1rem; margin: 0.5rem 0 1rem 0; - margin-left: 0.7rem; + justify-self: center; background-color: var(--green); } - .step__icon { - grid-area: step-icon; - } .icon { height: 1.5rem; width: 1.5rem; } &:not(.loading) { .step__title { - text-transform: capitalize; - grid-area: step-title; font-weight: 500; font-size: 0.9rem; padding: 0.2rem 0; } } .step__description { - grid-area: step-description; font-size: 0.8rem; } } @@ -866,6 +871,71 @@ details { transform: none; } } + +#deposit, +#loan { + padding: 1.5rem 0; + grid-template-rows: auto 1fr; + sm-form { + justify-self: center; + margin-top: 3rem; + width: min(24rem, 100%); + &::part(form) { + display: flex; + flex-direction: column; + } + } +} +#deposit__icon, +#loan__icon { + .icon { + height: 1.8rem; + width: 1.8rem; + fill: var(--accent-color); + } +} +#get_deposit_amount, +#get_loan_amount { + --font-size: 1.5rem; + margin-top: 1rem; +} +#result { + place-content: center; + section { + text-align: center; + align-items: center; + } + &__icon { + display: flex; + border-radius: 50%; + padding: 1rem; + margin: -5rem 0 1.5rem 0; + animation: pop-in 1s forwards cubic-bezier(0.175, 0.885, 0.32, 1.275); + .icon { + height: 1.8rem; + width: 1.8rem; + } + } + &__description { + margin: 0.5rem 0; + } + &__back_button { + margin-top: 3rem; + } +} +@keyframes pop-in { + 0% { + opacity: 0; + transform: scale(0.4) translateY(6rem); + } + 40% { + opacity: 1; + transform: scale(0.4) translateY(0); + } + 100% { + transform: none; + } +} @media screen and (max-width: 640px) { sm-button { --padding: 1rem; @@ -889,7 +959,8 @@ details { } } #transaction_action_button, - #account_action_button { + #account_action_button, + #deposit_button { margin-top: auto; } #account_process { diff --git a/index.html b/index.html index 2f5a0da..6a68d16 100644 --- a/index.html +++ b/index.html @@ -174,7 +174,7 @@ Quick actions
- - +
@@ -309,6 +309,70 @@
+
+ + +
+ + + + + + +
+
+

Deposit

+

+
+ + + Deposit +
+
+
+ + +
+ + + + +
+
+

Loan

+

+
+ + + Request loan +
+
+
+
+
+

+

+ Done +
+
@@ -391,6 +454,7 @@
+

@@ -632,7 +696,7 @@ return `${month} ${year}`; } else - return `${finalHours} ${month} ${date} ${year}`; + return `${month} ${date} ${year}, ${finalHours}`; } catch (e) { console.error(e); return time; @@ -707,6 +771,14 @@ getRef('generated_flo_id').value = floID getRef('generated_private_key').value = privKey break; + case 'deposit': + const { I_s } = bank_app.getRates() + getRef('deposit_interest_rate').textContent = `Make a deposit at ${I_s * 100}% rate of interest` + break; + case 'loan': + const { I_b } = bank_app.getRates() + getRef('loan_interest_rate').textContent = `Get a loan at ${I_b * 100}% rate of interest` + break; case 'transaction': showTransactionDetails(params) break; @@ -981,7 +1053,7 @@ card.querySelector('.activity-card__icon').innerHTML = icon card.querySelector('.activity-card__type').textContent = type card.querySelector('.activity-card__time').textContent = getFormattedTime(parseInt(openTime)) - card.querySelector('.activity-card__amount').textContent = amount.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR' }) + card.querySelector('.activity-card__amount').textContent = netAmt.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR' }) card.querySelector('.activity-card__status').classList.add(status) card.querySelector('.activity-card__status').textContent = status return card @@ -1068,7 +1140,6 @@ function showTransactionDetails(params) { const { requestID } = params const { amount, rtype, timestamp, status, index } = getRequestDetails(requestID) - const { status: accountStatus } = bank_app.accounts[index] let type = (rtype === 'openDeposit' || rtype === 'closeDeposit') ? 'deposit' : 'loan' const icon = utils.getRelatedIcon(rtype) @@ -1079,22 +1150,6 @@ getRef('transaction_detail__type').textContent = type getRef('transaction_detail__amount').textContent = amount.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR' }) getRef('transaction_detail__time').textContent = getFormattedTime(timestamp) - getRef('transaction_action_button').classList.remove('hide-completely') - - if (accountStatus === 'active') { - getRef('transaction_action_button').classList.remove('hide-completely') - } else { - getRef('transaction_action_button').classList.add('hide-completely') - } - - switch (rtype) { - case 'openDeposit': - getRef('transaction_action_button').textContent = 'Withdraw' - break - case 'openLoan': - getRef('transaction_action_button').textContent = 'Repay' - break - } } function getAccountStatus(index) { @@ -1131,19 +1186,19 @@ function renderAccountProgress(index) { const { type, status, openTime, closeTime = 0, amount, netAmt } = bank_app.accounts[index] getRef('account_process__steps').innerHTML = '' - getRef('account_process__steps').append(render.accountProgressStep('success', `${type}ed`, getFormattedTime(openTime))) + getRef('account_process__steps').append(render.accountProgressStep('success', type === "deposit" ? 'Deposited' : 'Got loan', getFormattedTime(openTime))) const { isPending, pendingRequest } = getAccountStatus(index) if (type === 'deposit') { if (isPending) { getRef('account_process__steps').append(render.accountProgressStep('success', 'Sent withdrawal request', getFormattedTime(pendingRequest.split('_')[0]))) - getRef('account_process__steps').append(render.accountProgressStep('pending', 'Waiting for confirmation', `Once your request is processed, your withdrawn amount will reflect in your balance.
meanwhile you can go back and continue using the app.`)) + getRef('account_process__steps').append(render.accountProgressStep('pending', 'Waiting for withdrawal confirmation', `Once your request is processed, your withdrawn amount will reflect in your balance.
meanwhile you can go back and continue using the app.`)) } else { getRef('account_process__steps').append(render.accountProgressStep('success', 'Withdrawal complete', getFormattedTime(closeTime))) } } else { if (isPending) { getRef('account_process__steps').append(render.accountProgressStep('success', 'Sent repay request', getFormattedTime(pendingRequest.split('_')[0]))) - getRef('account_process__steps').append(render.accountProgressStep('pending', 'Waiting for confirmation', `Once your request is processed, your loan will be closed,`)) + getRef('account_process__steps').append(render.accountProgressStep('pending', 'Waiting for repayment confirmation', `Once your request is processed, your loan will be closed,`)) } else { getRef('account_process__steps').append(render.accountProgressStep('success', 'Repayment complete', getFormattedTime(closeTime))) } @@ -1223,8 +1278,8 @@ accountChart.data.datasets[0].data = [depositTotal, loanTotal] accountChart.update() } - getRef('total_deposit').textContent = depositTotal - getRef('total_loan').textContent = loanTotal + getRef('total_deposit').textContent = depositTotal.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR' }) + getRef('total_loan').textContent = loanTotal.toLocaleString(`en-IN`, { style: 'currency', currency: 'INR' }) } document.querySelector('theme-toggle').addEventListener('themechange', e => { @@ -1279,6 +1334,79 @@ } }) }) + + getRef('get_deposit_amount').addEventListener('input', e => { + if (e.target.value.trim() !== '') { + getRef('deposit_button').textContent = `Deposit ${parseFloat(e.target.value).toLocaleString('en-IN', { currency: 'INR', style: 'currency' })}` + } else { + getRef('deposit_button').textContent = `Deposit` + } + }) + getRef('get_loan_amount').addEventListener('input', e => { + if (e.target.value.trim() !== '') { + getRef('loan_button').textContent = `Request loan of ${parseFloat(e.target.value).toLocaleString('en-IN', { currency: 'INR', style: 'currency' })}` + } else { + getRef('loan_button').textContent = `Request loan` + } + }) + + function showActionResult(details = {}) { + const { type, amount, status, reason = '' } = details + getRef('result__icon').innerHTML = utils.getRelatedIcon(status) + if (type === 'deposit') { + getRef('result__title').textContent = 'Sent deposit request' + getRef('result__description').textContent = 'Waiting for deposit confirmation. Meanwhile you can go back and continue using app.' + } else if (type === 'loan') { + getRef('result__title').textContent = 'Sent loan request' + getRef('result__description').textContent = 'Waiting for loan confirmation. Meanwhile you can go back and continue using app.' + } + showPage('result') + } + + async function initDeposit() { + const amount = parseFloat(getRef('get_deposit_amount').value) + const confirm = await getConfirmation(`Confirm deposit of ${amount.toLocaleString('en-IN', { currency: 'INR', style: 'currency' })}?`) + if (confirm) { + bank_app.makeDeposit(amount) + .then(() => { + showActionResult({ + type: 'deposit', + amount, + status: 'pending' + }) + }) + .catch(err => { + showActionResult({ + type: 'deposit', + amount, + status: 'failed', + reason: err + }) + }) + } + } + async function initLoan() { + const amount = parseFloat(getRef('get_loan_amount').value) + const confirm = await getConfirmation(`Confirm loan of ${amount.toLocaleString('en-IN', { currency: 'INR', style: 'currency' })}?`) + if (confirm) { + bank_app.requestLoan(amount) + .then(() => { + showActionResult({ + type: 'loan', + amount, + status: 'pending' + }) + }) + .catch(err => { + showActionResult({ + type: 'loan', + amount, + status: 'failed', + reason: err + }) + }) + } + }