From 3caa81efd563ed4609ac833544b596683b07a3c4 Mon Sep 17 00:00:00 2001 From: sairaj mote Date: Mon, 31 Oct 2022 13:28:43 +0530 Subject: [PATCH] Code refactoring --- css/main.css | 334 +++- css/main.min.css | 2 +- css/main.scss | 1427 ++++++++------- index.html | 3488 ++++++++----------------------------- scripts/components.min.js | 6 + 5 files changed, 1734 insertions(+), 3523 deletions(-) create mode 100644 scripts/components.min.js diff --git a/css/main.css b/css/main.css index f00bcac..f6e9c5f 100644 --- a/css/main.css +++ b/css/main.css @@ -3,25 +3,26 @@ padding: 0; margin: 0; box-sizing: border-box; - font-family: "Inter", sans-serif; + font-family: "Roboto", sans-serif; } :root { - font-size: clamp(1rem, 1.2vmax, 3rem); + font-size: clamp(1rem, 1.2vmax, 1.2rem); } -html, body { +html, +body { height: 100%; scroll-behavior: smooth; } body { - --accent-color: #2353FF; + --accent-color: #2353ff; --light-shade: rgba(var(--text-color), 0.06); --text-color: 17, 17, 17; --text-color-light: 100, 100, 100; --foreground-color: 255, 255, 255; - --background-color: #F6f6f6; + --background-color: #f6f6f6; --error-color: red; --green: #00843b; color: rgba(var(--text-color), 1); @@ -29,7 +30,7 @@ body { } body[data-theme=dark] { - --accent-color: #2353FF; + --accent-color: #2353ff; --green: #13ff5a; --text-color: 240, 240, 240; --text-color-light: 170, 170, 170; @@ -84,7 +85,8 @@ p { } img { - object-fit: cover; + -o-object-fit: cover; + object-fit: cover; } a { @@ -124,6 +126,42 @@ button:focus-visible { outline: rgba(var(--text-color), 1) 0.1rem solid; } +a:-webkit-any-link { + position: relative; + display: inline-flex; + align-items: center; + background: none; + cursor: pointer; + outline: none; + color: inherit; + font-weight: 500; + font-size: 0.8rem; + border-radius: 0.3rem; + padding: 0.4rem 0.6rem; + align-self: flex-start; + text-decoration: none; + -webkit-tap-highlight-color: transparent; + border: 1px solid rgba(var(--text-color), 0.8); +} + +a:-moz-any-link { + position: relative; + display: inline-flex; + align-items: center; + background: none; + cursor: pointer; + outline: none; + color: inherit; + font-weight: 500; + font-size: 0.8rem; + border-radius: 0.3rem; + padding: 0.4rem 0.6rem; + align-self: flex-start; + text-decoration: none; + -webkit-tap-highlight-color: transparent; + border: 1px solid rgba(var(--text-color), 0.8); +} + a:any-link { position: relative; display: inline-flex; @@ -142,28 +180,26 @@ a:any-link { border: 1px solid rgba(var(--text-color), 0.8); } +a:-webkit-any-link:focus-visible { + outline: rgba(var(--text-color), 1) 0.1rem solid; +} + +a:-moz-any-link:focus-visible { + outline: rgba(var(--text-color), 1) 0.1rem solid; +} + a:any-link:focus-visible { outline: rgba(var(--text-color), 1) 0.1rem solid; } sm-input, sm-textarea { - --border-radius: 0.2rem; + --border-radius: 0.5rem; --background: rgba(var(--text-color), 0.06); } sm-button { - --border-radius: 0.2rem; -} - -sm-tab-header { - align-self: flex-start; - --active-tab-color: white; - margin-bottom: 1rem; - justify-self: flex-start; - padding: 0.3rem; - border-radius: 0.5rem; - background-color: rgba(var(--text-color), 0.06); + --border-radius: 0.5rem; } ul { @@ -178,6 +214,10 @@ ul { display: flex; } +.flex-wrap { + flex-wrap: wrap; +} + .grid { display: grid; } @@ -367,17 +407,17 @@ ul { word-wrap: break-word; -ms-word-break: break-all; word-break: break-word; - -ms-hyphens: auto; - -moz-hyphens: auto; -webkit-hyphens: auto; hyphens: auto; } .ripple { + height: 8rem; + width: 8rem; position: absolute; border-radius: 50%; transform: scale(0); - background: rgba(var(--text-color), 0.16); + background: radial-gradient(circle, rgba(var(--text-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%); pointer-events: none; } @@ -418,10 +458,24 @@ ul { } .sad-face .eyes { transform-origin: center; - animation: blink 1s infinite alternate; + -webkit-animation: blink 1s infinite alternate; + animation: blink 1s infinite alternate; } .sad-face .face { - animation: nod 2s 1s; + -webkit-animation: nod 2s 1s; + animation: nod 2s 1s; +} + +@-webkit-keyframes blink { + 0% { + transform: scaleY(1); + } + 80% { + transform: scaleY(1); + } + 100% { + transform: scaleY(0); + } } @keyframes blink { @@ -435,6 +489,38 @@ ul { transform: scaleY(0); } } +@-webkit-keyframes nod { + 0% { + transform: translateX(0); + } + 20% { + transform: translateX(-1.5rem); + } + 30% { + transform: translateX(1.5rem); + } + 40% { + transform: translateX(-1rem); + } + 50% { + transform: translateX(1rem); + } + 60% { + transform: translateX(-0.7rem); + } + 70% { + transform: translateX(0.7rem); + } + 80% { + transform: translateX(-0.5rem); + } + 90% { + transform: translateX(0.5rem); + } + 100% { + transform: translateX(0); + } +} @keyframes nod { 0% { transform: translateX(0); @@ -493,7 +579,20 @@ ul { #loader polyline:nth-of-type(3), #loader polyline:nth-of-type(4) { stroke-dasharray: 60; - animation: loading infinite 1s; + -webkit-animation: loading infinite 1s; + animation: loading infinite 1s; +} + +@-webkit-keyframes loading { + 0% { + stroke-dashoffset: -60; + } + 50% { + stroke-dashoffset: 0; + } + 100% { + stroke-dashoffset: 60; + } } @keyframes loading { @@ -549,15 +648,6 @@ ul { margin-right: 1rem; } -sm-select { - min-width: 6rem; - --selection-font-size: 0.9rem; -} - -sm-option { - --color: rgba(var(--text-color), 1); -} - .dropdown { display: flex; justify-content: flex-end; @@ -576,7 +666,7 @@ sm-option { grid-template-columns: 1fr; justify-content: flex-start; color: rgba(var(--text-color), 1); - width: min(24rem, calc(100vw - 2rem)); + width: min(24rem, 100vw - 2rem); background-color: rgba(var(--foreground-color), 1); box-shadow: 0 2rem 2rem -0.5rem rgba(0, 0, 0, 0.16); } @@ -607,20 +697,24 @@ sm-option { .page-layout { display: grid; - grid-template-columns: 1rem 1fr 1rem; + grid-template-columns: 1rem minmax(0, 1fr) 1rem; } .page-layout > * { grid-column: 2/3; } #home_page { + --side-padding: 8vw; + display: flex; + flex-direction: column; + padding: 0 max(1rem, var(--side-padding)); padding-bottom: 6rem; } #homepage__hero-section { color: white; padding: 2rem 0 12rem 0; - margin-bottom: -8rem; + margin: 0 calc(-1 * max(1rem, var(--side-padding))) -8rem calc(-1 * max(1rem, var(--side-padding))); background-image: url(../assets/bg-1.svg); background-color: var(--accent-color); background-size: cover; @@ -636,36 +730,27 @@ sm-option { } #search_investor { - --font-weight: 500; - --padding: 0.5rem 1rem; --background: rgba(var(--foreground-color), 1); color: rgba(var(--text-color), 1); grid-area: search; - width: min(24rem, 100%); + width: min(20rem, 100%); justify-self: flex-end; } -#search_investor .icon { - height: 1.2rem; - width: 1.2rem; - margin-left: -0.5rem; -} .label { font-weight: 500; - font-size: 0.75rem; - margin-bottom: 0.2rem; + font-size: 0.85rem; + margin-bottom: 0.3rem; color: rgba(var(--text-color), 0.8); } .value { - font-weight: 600; - font-size: 0.9rem; + font-weight: 700; + font-size: 1rem; overflow-wrap: break-word; word-wrap: break-word; -ms-word-break: break-all; word-break: break-word; - -ms-hyphens: auto; - -moz-hyphens: auto; -webkit-hyphens: auto; hyphens: auto; } @@ -775,13 +860,16 @@ form select option { width: min(24rem, 100%); } .fund-placeholder:nth-of-type(2) .placeholder__block { - animation-delay: 0.3s; + -webkit-animation-delay: 0.3s; + animation-delay: 0.3s; } .fund-placeholder:nth-of-type(3) .placeholder__block { - animation-delay: 0.6s; + -webkit-animation-delay: 0.6s; + animation-delay: 0.6s; } .fund-placeholder:nth-of-type(4) .placeholder__block { - animation-delay: 0.8s; + -webkit-animation-delay: 0.8s; + animation-delay: 0.8s; } .placeholder__block { @@ -789,10 +877,20 @@ form select option { border-radius: 0.3rem; min-width: 9rem; padding: 1.2rem 1rem; - animation: pulse alternate 0.6s ease infinite; + -webkit-animation: pulse alternate 0.6s ease infinite; + animation: pulse alternate 0.6s ease infinite; background-color: rgba(var(--text-color), 0.1); } +@-webkit-keyframes pulse { + from { + opacity: 0.4; + } + to { + opacity: 1; + } +} + @keyframes pulse { from { opacity: 0.4; @@ -801,95 +899,189 @@ form select option { opacity: 1; } } +.fund-investor { + display: grid; + gap: 1rem; + padding: 1rem 0; + background-color: rgba(var(--foreground-color), 1); +} + +.transaction-column { + display: flex; + flex-direction: column; +} + +.space-between { + justify-content: space-between; +} + +.fund-block { + border-radius: 0.5rem; + padding: 1rem; + background-color: rgba(var(--foreground-color), 1); + box-shadow: 0 1rem 2rem -1rem rgba(0, 0, 0, 0.16); +} + +.fund-block__details { + gap: 1.5rem; +} + +.tapout-container, +.investment-container { + grid-column: 1/3; +} + +.investment-container { + gap: 1.5rem; + justify-content: flex-start; + grid-template-columns: 1fr 1fr; +} + +.tapout-list { + display: grid; + gap: 1.5rem; + overflow-x: auto; + grid-auto-flow: column; + justify-content: flex-start; +} + +.tapout-list li { + min-width: 8rem; +} + +.fund-link { + justify-self: flex-end; +} + +.investor-group { + display: grid; + padding: 0.5rem; + margin-top: 1.8rem; + border-radius: 0.3rem; + box-shadow: 0 0 0 1px rgba(var(--text-color), 0.3); +} + +.investor-group header { + margin-top: -1.5rem; + margin-bottom: 0.5rem; + justify-self: flex-end; +} + +.investor-group > * { + background-color: rgba(var(--foreground-color), 1); +} + +.investor-group h4 { + padding: 0 0.5rem; + margin-left: -0.5rem; +} + +.investor-group__list { + display: grid; + gap: 0.8rem; + grid-template-columns: minmax(0, 1fr); +} + @media only screen and (max-width: 640px) { .h1 { font-size: 2rem; } - .h2 { font-size: 1.8rem; } - .h3 { font-size: 1.3rem; } - .h4 { font-size: 1rem; } - .h5 { font-size: 0.8rem; } - #main_header { grid-template-areas: ". profile-button"; } #main_header .dropdown { grid-area: profile-button; } - #homepage__hero-section { padding: 2rem 0 20rem 0; margin-bottom: -16rem; } - .fund-list__header { grid-template-columns: auto 1fr; grid-template-areas: ". ." "search search"; } - .investor-input { grid-template-columns: 1fr auto; grid-template-areas: ". close" ". close"; } + .fund-link { + grid-column: 2/3; + } } @media only screen and (min-width: 640px) { #main_header { - padding: 2rem calc((10vw / 2) - 0.4rem); + padding: 2rem calc(5vw - 0.4rem); grid-template-columns: auto 1fr auto; } #main_header::after { height: 5rem; } - .page-layout { grid-template-columns: 1fr 90vw 1fr; } - + .value { + min-width: 9rem; + } #current_price { justify-self: flex-end; } - .dropdown__panel { left: auto; } - .fund-list__header { grid-template-columns: auto 1fr auto; grid-template-areas: ". search ."; } - .investor-input { grid-template-columns: 1.5fr 1fr auto; grid-template-areas: ". . close"; } + .fund-block { + padding: 1.5rem; + } + .fund-block__details { + grid-template-columns: 1fr 1fr; + } + .investor-group { + padding: 0.5rem 1rem; + } + .justify-self-end { + justify-self: flex-end; + text-align: right; + } + .investment-container { + grid-template-columns: auto auto 1fr; + } } @media only screen and (min-width: 1280px) { .page-layout { grid-template-columns: 1fr 90vw 1fr; } - .multi-form { grid-template-columns: 1fr 1fr; } + .fund-investor { + gap: 1.5rem; + grid-template-columns: 1fr auto; + } } @media (any-hover: hover) { ::-webkit-scrollbar { width: 0.5rem; height: 0.5rem; } - ::-webkit-scrollbar-thumb { background: rgba(var(--text-color), 0.3); border-radius: 1rem; diff --git a/css/main.min.css b/css/main.min.css index d3751ee..896a4cd 100644 --- a/css/main.min.css +++ b/css/main.min.css @@ -1 +1 @@ -@charset "UTF-8";a,button{color:inherit}a:any-link,button{display:inline-flex;outline:0;position:relative}a,a:any-link{text-decoration:none}.hide,.ripple{pointer-events:none}.interact,a:any-link,button{cursor:pointer;-webkit-tap-highlight-color:transparent}.pos-relative,a:any-link,button{position:relative}*{padding:0;margin:0;box-sizing:border-box;font-family:Inter,sans-serif}:root{font-size:clamp(1rem,1.2vmax,3rem)}body,html{height:100%;scroll-behavior:smooth}body{--accent-color:#2353FF;--light-shade:rgba(var(--text-color), 0.06);--text-color:17,17,17;--text-color-light:100,100,100;--foreground-color:255,255,255;--background-color:#F6f6f6;--error-color:red;--green:#00843b;color:rgba(var(--text-color),1);background:var(--background-color)}body[data-theme=dark]{--accent-color:#2353FF;--green:#13ff5a;--text-color:240,240,240;--text-color-light:170,170,170;--foreground-color:20,20,20;--background-color:#0a0a0a;--error-color:rgb(255, 106, 106)}body[data-theme=dark] ::-webkit-calendar-picker-indicator{filter:invert(1)}body[data-theme=dark] sm-input.outlined{--active-placeholder-color:rgba(var(--text-color), 1)}.full-bleed{grid-column:1/4!important}.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}p{font-size:.8;max-width:70ch;line-height:1.5;color:rgba(var(--text-color),.8)}img{object-fit:cover}a:focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color),1) inset}button{overflow:hidden;align-items:center;background:0 0;font-size:.9rem;font-weight:500;border-radius:.2rem;padding:.5rem .6rem;border:none}.button--primary{background:var(--accent-color);color:#fff}.button--primary .icon{fill:rgba(var(--foreground-color),1)}button:focus-visible{outline:solid rgba(var(--text-color),1)}a:any-link{align-items:center;background:0 0;color:inherit;font-weight:500;font-size:.8rem;border-radius:.3rem;padding:.4rem .6rem;align-self:flex-start;border:1px solid}#loader,.flex{display:flex}a:any-link:focus-visible{outline:solid rgba(var(--text-color),1)}sm-input,sm-textarea{--border-radius:0.2rem;--background:rgba(var(--text-color), 0.06)}sm-button{--border-radius:0.2rem}sm-tab-header{align-self:flex-start;--active-tab-color:white;margin-bottom:1rem;justify-self:flex-start;padding:.3rem;border-radius:.5rem;background-color:rgba(var(--text-color),.06)}ul{list-style:none}.accent-color{color:var(--accent-color)}.grid{display:grid}.grid-3{grid-template-columns:repeat(auto-fill,minmax(8rem,1fr))}.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{align-items:flex-start}.align-center{align-items:center}.align-end{align-content:flex-end}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-end{justify-content:end}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{flex-direction:column}.space-between{justify-content:space-between}.w-100{width:100%}.margin-top-1-5{margin-top:1.5rem}.margin-bottom-0-5r{margin-bottom:.5rem}.margin-bottom-1r{margin-bottom:1rem}.margin-bottom-1-5r{margin-bottom:1.5rem}.margin-bottom-2r{margin-bottom:2rem}.margin-bottom-3r{margin-bottom:3rem}.margin-bottom-4r{margin-bottom:4rem}.margin-left-0-5{margin-left:.5rem}.margin-right-0-5{margin-right:.5rem}.color-0-9{color:rgba(var(--text-color),.9)}.color-0-8{color:rgba(var(--text-color),.8)}.color-0-7{color:rgba(var(--text-color),.7)}.weight-400{font-weight:400}.header__company-name,.label,.weight-500{font-weight:500}.weight-700{font-weight:700}.weight-900{font-weight:900}.hide{opacity:0}.hide-completely{display:none!important}.no-transformations{transform:none!important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable,.value{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;-ms-hyphens:auto;-moz-hyphens:auto}.breakable{word-break:break-word;-webkit-hyphens:auto;hyphens:auto}.ripple{position:absolute;border-radius:50%;transform:scale(0);background:rgba(var(--text-color),.16)}#fund_list__empty-state,.dropdown__panel,.warning-container{border-radius:.3rem;background-color:rgba(var(--foreground-color),1)}.interact{position:relative;overflow:hidden}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}.icon{width:1.5rem;height:1.5rem;fill:rgba(var(--text-color),.9)}#rm_logo,.sad-face{fill:rgba(var(--text-color),1)}#error_page,#loading_page{position:relative;display:grid;height:100%;place-content:center;justify-items:center}.sad-face{height:6rem;margin:1rem}.sad-face .eyes{transform-origin:center;animation:blink 1s infinite alternate}.sad-face .face{animation:nod 2s 1s}@keyframes blink{0%,80%{transform:scaleY(1)}100%{transform:scaleY(0)}}@keyframes nod{0%,100%{transform:translateX(0)}20%{transform:translateX(-1.5rem)}30%{transform:translateX(1.5rem)}40%{transform:translateX(-1rem)}50%{transform:translateX(1rem)}60%{transform:translateX(-.7rem)}70%{transform:translateX(.7rem)}80%{transform:translateX(-.5rem)}90%{transform:translateX(.5rem)}}.page__footer{position:absolute;padding:3rem;bottom:0}#main_header,.dropdown__panel li{padding:1rem}#rm_logo{width:auto;height:2rem}#loader{position:relative;width:4rem;height:8rem;fill:none;stroke-width:4;stroke-linecap:round;stroke:rgba(var(--text-color),1)}#loader polyline:nth-of-type(2),#loader polyline:nth-of-type(3),#loader polyline:nth-of-type(4){stroke-dasharray:60;animation:loading infinite 1s}@keyframes loading{0%{stroke-dashoffset:-60}50%{stroke-dashoffset:0}100%{stroke-dashoffset:60}}#main_header{position:relative;display:grid;gap:1.5rem;align-items:center;background-color:var(--accent-color);color:#fff}#main_header__logo{fill:#fff;height:2.4rem;width:2.4rem;margin-left:-.3rem}.header__app-name{font-weight:700;font-size:1.2rem}#current_price{justify-self:flex-start}#usd-rate{display:flex;align-items:center}#usd-rate::before{content:"";width:1px;height:2rem;background-color:#fff;margin-right:1rem}sm-select{min-width:6rem;--selection-font-size:0.9rem}sm-option{--color:rgba(var(--text-color), 1)}.dropdown{display:flex;justify-content:flex-end;z-index:5}.dropdown__panel{position:absolute;display:grid;left:0;right:0;top:100%;margin:0 1rem;margin-top:.5rem;grid-template-columns:1fr;justify-content:flex-start;color:rgba(var(--text-color),1);width:min(24rem,calc(100vw - 2rem));box-shadow:0 2rem 2rem -.5rem rgba(0,0,0,.16)}#profile_button{align-items:center;justify-content:center;border:none;height:2.2rem;width:2.2rem;justify-self:flex-end;border-radius:50%;background-color:rgba(0,0,0,.16)}#profile_button .icon{height:1rem;width:1rem;fill:#fff}#theme_switcher{overflow:hidden;width:100%}.page-layout{display:grid;grid-template-columns:1rem 1fr 1rem}.page-layout>*{grid-column:2/3}#home_page{padding-bottom:6rem}#homepage__hero-section{color:#fff;padding:2rem 0 12rem;margin-bottom:-8rem;background-image:url(../assets/bg-1.svg);background-color:var(--accent-color);background-size:cover}#homepage__hero-section p{color:rgba(255,255,255,.8)}.fund-list__header{color:#fff;align-items:center;gap:1rem}#search_investor{--font-weight:500;--padding:0.5rem 1rem;--background:rgba(var(--foreground-color), 1);color:rgba(var(--text-color),1);grid-area:search;width:min(24rem,100%);justify-self:flex-end}#search_investor .icon{height:1.2rem;width:1.2rem;margin-left:-.5rem}.label{font-size:.75rem;margin-bottom:.2rem;color:rgba(var(--text-color),.8)}.value{font-weight:600;font-size:.9rem;word-break:break-word;-webkit-hyphens:auto;hyphens:auto}.warning-container{padding:1rem;margin-bottom:1rem;box-shadow:0 1rem 2rem -1rem rgba(0,0,0,.16)}#fund_list{display:grid;gap:1.5rem}#fund_list__empty-state{padding:4rem 0;place-content:center;margin-bottom:3rem;box-shadow:0 1rem 2rem -1rem rgba(0,0,0,.16)}#fund_list__empty-state .icon--big{height:6rem;width:6rem;justify-self:center}fund-block:first-of-type::before{display:inline-flex;content:"• Latest Fund";padding:.4rem .8rem;font-weight:700;font-size:1rem;color:#fff;background-color:var(--accent-color);border-radius:.3rem .3rem 0 0}fund-block:not(:last-of-type)::after{display:flex;content:"";padding:.4rem 0;font-weight:700;width:100%;background-color:var(--error-color);border-radius:0 0 .5rem .5rem}form{padding:1rem;border-radius:.3rem;width:min(32rem,100%);margin-bottom:3rem;background:rgba(var(--foreground-color),1)}form input{display:inline-flex;color:inherit;font-family:inherit;padding:.6rem;border:none;box-shadow:0 0 0 1px rgba(var(--text-color),.3);background-color:rgba(var(--text-color),.06);flex:1}form select option{color:inherit;background-color:rgba(var(--text-color),.1)}.investor-input{gap:.5rem}.remove-investor{grid-area:close}#fund_details,#term_details{line-height:1.7;margin-bottom:2rem}.flex-grid{display:grid;gap:1rem;justify-content:start;grid-template-columns:repeat(auto-fill,minmax(9rem,1fr))}.fund-placeholder{gap:1rem;padding:1rem;border-radius:.3rem;background-color:rgba(var(--foreground-color),1);box-shadow:0 1rem 2rem -1rem rgba(0,0,0,.16)}.fund-placeholder .placeholder__block:first-of-type{width:min(24rem,100%)}.fund-placeholder:nth-of-type(2) .placeholder__block{animation-delay:.3s}.fund-placeholder:nth-of-type(3) .placeholder__block{animation-delay:.6s}.fund-placeholder:nth-of-type(4) .placeholder__block{animation-delay:.8s}.placeholder__block{display:flex;border-radius:.3rem;min-width:9rem;padding:1.2rem 1rem;animation:pulse alternate .6s ease infinite;background-color:rgba(var(--text-color),.1)}@keyframes pulse{from{opacity:.4}to{opacity:1}}@media only screen and (max-width:640px){.h1{font-size:2rem}.h2{font-size:1.8rem}.h3{font-size:1.3rem}.h4{font-size:1rem}.h5{font-size:.8rem}#main_header{grid-template-areas:". profile-button"}#main_header .dropdown{grid-area:profile-button}#homepage__hero-section{padding:2rem 0 20rem;margin-bottom:-16rem}.fund-list__header{grid-template-columns:auto 1fr;grid-template-areas:". ." "search search"}.investor-input{grid-template-columns:1fr auto;grid-template-areas:". close" ". close"}}@media only screen and (min-width:640px){#main_header{padding:2rem calc((10vw / 2) - .4rem);grid-template-columns:auto 1fr auto}#main_header::after{height:5rem}.page-layout{grid-template-columns:1fr 90vw 1fr}#current_price{justify-self:flex-end}.dropdown__panel{left:auto}.fund-list__header{grid-template-columns:auto 1fr auto;grid-template-areas:". search ."}.investor-input{grid-template-columns:1.5fr 1fr auto;grid-template-areas:". . close"}}@media only screen and (min-width:1280px){.page-layout{grid-template-columns:1fr 90vw 1fr}.multi-form{grid-template-columns:1fr 1fr}}@media (any-hover:hover){::-webkit-scrollbar{width:.5rem;height:.5rem}::-webkit-scrollbar-thumb{background:rgba(var(--text-color),.3);border-radius:1rem}::-webkit-scrollbar-thumb:hover{background:rgba(var(--text-color),.5)}} \ No newline at end of file +*{padding:0;margin:0;box-sizing:border-box;font-family:"Roboto",sans-serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%;scroll-behavior:smooth}body{--accent-color: #2353ff;--light-shade: rgba(var(--text-color), 0.06);--text-color: 17, 17, 17;--text-color-light: 100, 100, 100;--foreground-color: 255, 255, 255;--background-color: #f6f6f6;--error-color: red;--green: #00843b;color:rgba(var(--text-color), 1);background:var(--background-color)}body[data-theme=dark]{--accent-color: #2353ff;--green: #13ff5a;--text-color: 240, 240, 240;--text-color-light: 170, 170, 170;--foreground-color: 20, 20, 20;--background-color: #0a0a0a;--error-color: rgb(255, 106, 106)}body[data-theme=dark] ::-webkit-calendar-picker-indicator{filter:invert(1)}body[data-theme=dark] sm-input.outlined{--active-placeholder-color: rgba(var(--text-color), 1)}.full-bleed{grid-column:1/4 !important}.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}p{font-size:.8;max-width:70ch;line-height:1.5;color:rgba(var(--text-color), 0.8)}img{-o-object-fit:cover;object-fit:cover}a{color:inherit;text-decoration:none}a:focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color), 1) inset}button{position:relative;display:inline-flex;overflow:hidden;align-items:center;background:none;cursor:pointer;outline:none;color:inherit;font-size:.9rem;font-weight:500;border-radius:.2rem;padding:.5rem .6rem;-webkit-tap-highlight-color:rgba(0,0,0,0);border:none}.button--primary{background:var(--accent-color);color:#fff}.button--primary .icon{fill:rgba(var(--foreground-color), 1)}button:focus-visible{outline:rgba(var(--text-color), 1) .1rem solid}a:-webkit-any-link{position:relative;display:inline-flex;align-items:center;background:none;cursor:pointer;outline:none;color:inherit;font-weight:500;font-size:.8rem;border-radius:.3rem;padding:.4rem .6rem;align-self:flex-start;text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0);border:1px solid rgba(var(--text-color), 0.8)}a:-moz-any-link{position:relative;display:inline-flex;align-items:center;background:none;cursor:pointer;outline:none;color:inherit;font-weight:500;font-size:.8rem;border-radius:.3rem;padding:.4rem .6rem;align-self:flex-start;text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0);border:1px solid rgba(var(--text-color), 0.8)}a:any-link{position:relative;display:inline-flex;align-items:center;background:none;cursor:pointer;outline:none;color:inherit;font-weight:500;font-size:.8rem;border-radius:.3rem;padding:.4rem .6rem;align-self:flex-start;text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0);border:1px solid rgba(var(--text-color), 0.8)}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-input,sm-textarea{--border-radius: 0.5rem;--background: rgba(var(--text-color), 0.06)}sm-button{--border-radius: 0.5rem}ul{list-style:none}.accent-color{color:var(--accent-color)}.flex{display:flex}.flex-wrap{flex-wrap:wrap}.grid{display:grid}.grid-3{grid-template-columns:repeat(auto-fill, minmax(8rem, 1fr))}.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}.pos-relative{position:relative}.text-align-right{text-align:right}.align-start{align-items:flex-start}.align-center{align-items:center}.align-end{align-content:flex-end}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-end{justify-content:end}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{flex-direction:column}.space-between{justify-content:space-between}.w-100{width:100%}.margin-top-1-5{margin-top:1.5rem}.margin-bottom-0-5r{margin-bottom:.5rem}.margin-bottom-1r{margin-bottom:1rem}.margin-bottom-1-5r{margin-bottom:1.5rem}.margin-bottom-2r{margin-bottom:2rem}.margin-bottom-3r{margin-bottom:3rem}.margin-bottom-4r{margin-bottom:4rem}.margin-left-0-5{margin-left:.5rem}.margin-right-0-5{margin-right:.5rem}.color-0-9{color:rgba(var(--text-color), 0.9)}.color-0-8{color:rgba(var(--text-color), 0.8)}.color-0-7{color:rgba(var(--text-color), 0.7)}.weight-400{font-weight:400}.weight-500{font-weight:500}.weight-700{font-weight:700}.weight-900{font-weight:900}.hide{opacity:0;pointer-events:none}.hide-completely{display:none !important}.no-transformations{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;-webkit-hyphens:auto;hyphens:auto}.ripple{height:8rem;width:8rem;position:absolute;border-radius:50%;transform:scale(0);background:radial-gradient(circle, rgba(var(--text-color), 0.3) 0%, rgba(0, 0, 0, 0) 50%);pointer-events:none}.interact{position:relative;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}.icon{width:1.5rem;height:1.5rem;fill:rgba(var(--text-color), 0.9)}#loading_page,#error_page{position:relative;display:grid;height:100%;place-content:center;justify-items:center}.sad-face{height:6rem;margin:1rem;fill:rgba(var(--text-color), 1)}.sad-face .eyes{transform-origin:center;-webkit-animation:blink 1s infinite alternate;animation:blink 1s infinite alternate}.sad-face .face{-webkit-animation:nod 2s 1s;animation:nod 2s 1s}@-webkit-keyframes blink{0%{transform:scaleY(1)}80%{transform:scaleY(1)}100%{transform:scaleY(0)}}@keyframes blink{0%{transform:scaleY(1)}80%{transform:scaleY(1)}100%{transform:scaleY(0)}}@-webkit-keyframes nod{0%{transform:translateX(0)}20%{transform:translateX(-1.5rem)}30%{transform:translateX(1.5rem)}40%{transform:translateX(-1rem)}50%{transform:translateX(1rem)}60%{transform:translateX(-0.7rem)}70%{transform:translateX(0.7rem)}80%{transform:translateX(-0.5rem)}90%{transform:translateX(0.5rem)}100%{transform:translateX(0)}}@keyframes nod{0%{transform:translateX(0)}20%{transform:translateX(-1.5rem)}30%{transform:translateX(1.5rem)}40%{transform:translateX(-1rem)}50%{transform:translateX(1rem)}60%{transform:translateX(-0.7rem)}70%{transform:translateX(0.7rem)}80%{transform:translateX(-0.5rem)}90%{transform:translateX(0.5rem)}100%{transform:translateX(0)}}.page__footer{position:absolute;padding:3rem;bottom:0}#rm_logo{width:auto;height:2rem;fill:rgba(var(--text-color), 1)}#loader{display:flex;position:relative;width:4rem;height:8rem;fill:none;stroke-width:4;stroke-linecap:round;stroke:rgba(var(--text-color), 1)}#loader polyline:nth-of-type(2),#loader polyline:nth-of-type(3),#loader polyline:nth-of-type(4){stroke-dasharray:60;-webkit-animation:loading infinite 1s;animation:loading infinite 1s}@-webkit-keyframes loading{0%{stroke-dashoffset:-60}50%{stroke-dashoffset:0}100%{stroke-dashoffset:60}}@keyframes loading{0%{stroke-dashoffset:-60}50%{stroke-dashoffset:0}100%{stroke-dashoffset:60}}#main_header{position:relative;display:grid;gap:1.5rem;padding:1rem;align-items:center;background-color:var(--accent-color);color:#fff}#main_header__logo{fill:#fff;height:2.4rem;width:2.4rem;margin-left:-0.3rem}.header__company-name{font-weight:500}.header__app-name{font-weight:700;font-size:1.2rem}#current_price{justify-self:flex-start}#usd-rate{display:flex;align-items:center}#usd-rate::before{content:"";width:1px;height:2rem;background-color:#fff;margin-right:1rem}.dropdown{display:flex;justify-content:flex-end;z-index:5}.dropdown__panel{position:absolute;display:grid;left:0;right:0;top:100%;margin:0 1rem;margin-top:.5rem;border-radius:.3rem;grid-template-columns:1fr;justify-content:flex-start;color:rgba(var(--text-color), 1);width:min(24rem,100vw - 2rem);background-color:rgba(var(--foreground-color), 1);box-shadow:0 2rem 2rem -0.5rem rgba(0,0,0,.16)}.dropdown__panel li{padding:1rem}#profile_button{align-items:center;justify-content:center;border:none;height:2.2rem;width:2.2rem;justify-self:flex-end;border-radius:50%;background-color:rgba(0,0,0,.16)}#profile_button .icon{height:1rem;width:1rem;fill:#fff}#theme_switcher{overflow:hidden;width:100%}.page-layout{display:grid;grid-template-columns:1rem minmax(0, 1fr) 1rem}.page-layout>*{grid-column:2/3}#home_page{--side-padding: 8vw;display:flex;flex-direction:column;padding:0 max(1rem,var(--side-padding));padding-bottom:6rem}#homepage__hero-section{color:#fff;padding:2rem 0 12rem 0;margin:0 calc(-1*max(1rem,var(--side-padding))) -8rem calc(-1*max(1rem,var(--side-padding)));background-image:url(../assets/bg-1.svg);background-color:var(--accent-color);background-size:cover}#homepage__hero-section p{color:rgba(255,255,255,.8)}.fund-list__header{color:#fff;align-items:center;gap:1rem}#search_investor{--background: rgba(var(--foreground-color), 1);color:rgba(var(--text-color), 1);grid-area:search;width:min(20rem,100%);justify-self:flex-end}.label{font-weight:500;font-size:.85rem;margin-bottom:.3rem;color:rgba(var(--text-color), 0.8)}.value{font-weight:700;font-size:1rem;overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-webkit-hyphens:auto;hyphens:auto}.warning-container{padding:1rem;margin-bottom:1rem;border-radius:.3rem;background-color:rgba(var(--foreground-color), 1);box-shadow:0 1rem 2rem -1rem rgba(0,0,0,.16)}#fund_list{display:grid;gap:1.5rem}#fund_list__empty-state{padding:4rem 0;border-radius:.3rem;place-content:center;margin-bottom:3rem;background-color:rgba(var(--foreground-color), 1);box-shadow:0 1rem 2rem -1rem rgba(0,0,0,.16)}#fund_list__empty-state .icon--big{height:6rem;width:6rem;justify-self:center}fund-block:first-of-type::before{display:inline-flex;content:"• Latest Fund";padding:.4rem .8rem;font-weight:700;font-size:1rem;color:#fff;background-color:var(--accent-color);border-radius:.3rem .3rem 0 0}fund-block:not(:last-of-type)::after{display:flex;content:"";padding:.4rem 0;font-weight:700;width:100%;background-color:var(--error-color);border-radius:0 0 .5rem .5rem}.flex-grid{grid-template-columns:repeat(auto-fill, minmax(24rem, 1fr))}form{padding:1rem;border-radius:.3rem;width:min(32rem,100%);margin-bottom:3rem;background:rgba(var(--foreground-color), 1)}form input{display:inline-flex;color:inherit;font-family:inherit;padding:.6rem;border:none;box-shadow:0 0 0 1px rgba(var(--text-color), 0.3);background-color:rgba(var(--text-color), 0.06);flex:1}form select option{color:inherit;background-color:rgba(var(--text-color), 0.1)}.investor-input{gap:.5rem}.remove-investor{grid-area:close}#term_details,#fund_details{line-height:1.7;margin-bottom:2rem}.flex-grid{display:grid;gap:1rem;justify-content:start;grid-template-columns:repeat(auto-fill, minmax(9rem, 1fr))}.fund-placeholder{gap:1rem;padding:1rem;border-radius:.3rem;background-color:rgba(var(--foreground-color), 1);box-shadow:0 1rem 2rem -1rem rgba(0,0,0,.16)}.fund-placeholder .placeholder__block:first-of-type{width:min(24rem,100%)}.fund-placeholder:nth-of-type(2) .placeholder__block{-webkit-animation-delay:.3s;animation-delay:.3s}.fund-placeholder:nth-of-type(3) .placeholder__block{-webkit-animation-delay:.6s;animation-delay:.6s}.fund-placeholder:nth-of-type(4) .placeholder__block{-webkit-animation-delay:.8s;animation-delay:.8s}.placeholder__block{display:flex;border-radius:.3rem;min-width:9rem;padding:1.2rem 1rem;-webkit-animation:pulse alternate .6s ease infinite;animation:pulse alternate .6s ease infinite;background-color:rgba(var(--text-color), 0.1)}@-webkit-keyframes pulse{from{opacity:.4}to{opacity:1}}@keyframes pulse{from{opacity:.4}to{opacity:1}}.fund-investor{display:grid;gap:1rem;padding:1rem 0;background-color:rgba(var(--foreground-color), 1)}.transaction-column{display:flex;flex-direction:column}.space-between{justify-content:space-between}.fund-block{border-radius:.5rem;padding:1rem;background-color:rgba(var(--foreground-color), 1);box-shadow:0 1rem 2rem -1rem rgba(0,0,0,.16)}.fund-block__details{gap:1.5rem}.tapout-container,.investment-container{grid-column:1/3}.investment-container{gap:1.5rem;justify-content:flex-start;grid-template-columns:1fr 1fr}.tapout-list{display:grid;gap:1.5rem;overflow-x:auto;grid-auto-flow:column;justify-content:flex-start}.tapout-list li{min-width:8rem}.fund-link{justify-self:flex-end}.investor-group{display:grid;padding:.5rem;margin-top:1.8rem;border-radius:.3rem;box-shadow:0 0 0 1px rgba(var(--text-color), 0.3)}.investor-group header{margin-top:-1.5rem;margin-bottom:.5rem;justify-self:flex-end}.investor-group>*{background-color:rgba(var(--foreground-color), 1)}.investor-group h4{padding:0 .5rem;margin-left:-0.5rem}.investor-group__list{display:grid;gap:.8rem;grid-template-columns:minmax(0, 1fr)}@media only screen and (max-width: 640px){.h1{font-size:2rem}.h2{font-size:1.8rem}.h3{font-size:1.3rem}.h4{font-size:1rem}.h5{font-size:.8rem}#main_header{grid-template-areas:". profile-button"}#main_header .dropdown{grid-area:profile-button}#homepage__hero-section{padding:2rem 0 20rem 0;margin-bottom:-16rem}.fund-list__header{grid-template-columns:auto 1fr;grid-template-areas:". ." "search search"}.investor-input{grid-template-columns:1fr auto;grid-template-areas:". close" ". close"}.fund-link{grid-column:2/3}}@media only screen and (min-width: 640px){#main_header{padding:2rem calc(5vw - .4rem);grid-template-columns:auto 1fr auto}#main_header::after{height:5rem}.page-layout{grid-template-columns:1fr 90vw 1fr}.value{min-width:9rem}#current_price{justify-self:flex-end}.dropdown__panel{left:auto}.fund-list__header{grid-template-columns:auto 1fr auto;grid-template-areas:". search ."}.investor-input{grid-template-columns:1.5fr 1fr auto;grid-template-areas:". . close"}.fund-block{padding:1.5rem}.fund-block__details{grid-template-columns:1fr 1fr}.investor-group{padding:.5rem 1rem}.justify-self-end{justify-self:flex-end;text-align:right}.investment-container{grid-template-columns:auto auto 1fr}}@media only screen and (min-width: 1280px){.page-layout{grid-template-columns:1fr 90vw 1fr}.multi-form{grid-template-columns:1fr 1fr}.fund-investor{gap:1.5rem;grid-template-columns:1fr auto}}@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)}} \ No newline at end of file diff --git a/css/main.scss b/css/main.scss index b9b02c1..9ee80bc 100644 --- a/css/main.scss +++ b/css/main.scss @@ -1,815 +1,892 @@ -*{ - padding: 0; - margin: 0; - box-sizing: border-box; - font-family: 'Inter', sans-serif; +* { + padding: 0; + margin: 0; + box-sizing: border-box; + font-family: "Roboto", sans-serif; } -:root{ - font-size: clamp(1rem, 1.2vmax, 3rem); +:root { + font-size: clamp(1rem, 1.2vmax, 1.2rem); } -html, body{ - height: 100%; - scroll-behavior: smooth; +html, +body { + height: 100%; + scroll-behavior: smooth; } body { - --accent-color: #2353FF; - --light-shade: rgba(var(--text-color), 0.06); - --text-color: 17, 17, 17; - --text-color-light: 100, 100, 100; - --foreground-color: 255, 255, 255; - --background-color: #F6f6f6; - --error-color: red; - --green: #00843b; - color: rgba(var(--text-color), 1); - background: var(--background-color); + --accent-color: #2353ff; + --light-shade: rgba(var(--text-color), 0.06); + --text-color: 17, 17, 17; + --text-color-light: 100, 100, 100; + --foreground-color: 255, 255, 255; + --background-color: #f6f6f6; + --error-color: red; + --green: #00843b; + color: rgba(var(--text-color), 1); + background: var(--background-color); } -body[data-theme='dark']{ - --accent-color: #2353FF; - --green: #13ff5a; - --text-color: 240, 240, 240; - --text-color-light: 170, 170, 170; - --foreground-color: 20, 20, 20; - --background-color: #0a0a0a; - --error-color: rgb(255, 106, 106); - ::-webkit-calendar-picker-indicator { - filter: invert(1); - } - sm-input.outlined{ - --active-placeholder-color: rgba(var(--text-color), 1); - } +body[data-theme="dark"] { + --accent-color: #2353ff; + --green: #13ff5a; + --text-color: 240, 240, 240; + --text-color-light: 170, 170, 170; + --foreground-color: 20, 20, 20; + --background-color: #0a0a0a; + --error-color: rgb(255, 106, 106); + ::-webkit-calendar-picker-indicator { + filter: invert(1); + } + sm-input.outlined { + --active-placeholder-color: rgba(var(--text-color), 1); + } } -.full-bleed{ - grid-column: 1/4 !important; +.full-bleed { + grid-column: 1/4 !important; } -.h1{ - font-size: 2.5rem; +.h1 { + font-size: 2.5rem; } -.h2{ - font-size: 2rem; +.h2 { + font-size: 2rem; } -.h3{ - font-size: 1.4rem; +.h3 { + font-size: 1.4rem; } -.h4{ - font-size: 1rem; +.h4 { + font-size: 1rem; } -.h5{ - font-size: 0.8rem; +.h5 { + font-size: 0.8rem; } -.uppercase{ - text-transform: uppercase; +.uppercase { + text-transform: uppercase; } -.capitalize{ - text-transform: capitalize; +.capitalize { + text-transform: capitalize; } p { - font-size: 0.8; - max-width: 70ch; - line-height: 1.5; - color: rgba(var(--text-color), 0.8); + font-size: 0.8; + max-width: 70ch; + line-height: 1.5; + color: rgba(var(--text-color), 0.8); } -img{ - object-fit: cover; +img { + object-fit: cover; } -a{ - color: inherit; - text-decoration: none; - &:focus-visible{ - box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset; - } +a { + color: inherit; + text-decoration: none; + &:focus-visible { + box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset; + } } -button{ - position: relative; - display: inline-flex; - overflow: hidden; - align-items: center; - background: none; - cursor: pointer; - outline: none; - color: inherit; - font-size: 0.9rem; - font-weight: 500; - border-radius: 0.2rem; - padding: 0.5rem 0.6rem; - -webkit-tap-highlight-color: transparent; - border: none; +button { + position: relative; + display: inline-flex; + overflow: hidden; + align-items: center; + background: none; + cursor: pointer; + outline: none; + color: inherit; + font-size: 0.9rem; + font-weight: 500; + border-radius: 0.2rem; + padding: 0.5rem 0.6rem; + -webkit-tap-highlight-color: transparent; + border: none; } -.button--primary{ - background: var(--accent-color); - color: white; - .icon{ - fill: rgba(var(--foreground-color), 1); - } +.button--primary { + background: var(--accent-color); + color: white; + .icon { + fill: rgba(var(--foreground-color), 1); + } } -button:focus-visible{ - outline: rgba(var(--text-color), 1) 0.1rem solid; +button:focus-visible { + outline: rgba(var(--text-color), 1) 0.1rem solid; } -a:any-link{ - position: relative; - display: inline-flex; - align-items: center; - background: none; - cursor: pointer; - outline: none; - color: inherit; - font-weight: 500; - font-size: 0.8rem; - border-radius: 0.3rem; - padding: 0.4rem 0.6rem; - align-self: flex-start; - text-decoration: none; - -webkit-tap-highlight-color: transparent; - border: 1px solid rgba(var(--text-color), 0.8); +a:any-link { + position: relative; + display: inline-flex; + align-items: center; + background: none; + cursor: pointer; + outline: none; + color: inherit; + font-weight: 500; + font-size: 0.8rem; + border-radius: 0.3rem; + padding: 0.4rem 0.6rem; + align-self: flex-start; + text-decoration: none; + -webkit-tap-highlight-color: transparent; + border: 1px solid rgba(var(--text-color), 0.8); } -a:any-link:focus-visible{ - outline: rgba(var(--text-color), 1) 0.1rem solid; +a:any-link:focus-visible { + outline: rgba(var(--text-color), 1) 0.1rem solid; } - sm-input, -sm-textarea{ - --border-radius: 0.2rem; - --background: rgba(var(--text-color), 0.06); +sm-textarea { + --border-radius: 0.5rem; + --background: rgba(var(--text-color), 0.06); } -sm-button{ - --border-radius: 0.2rem; +sm-button { + --border-radius: 0.5rem; } -sm-tab-header{ - align-self: flex-start; - --active-tab-color: white; - margin-bottom: 1rem; - justify-self: flex-start; - padding: 0.3rem; - border-radius: 0.5rem; - background-color: rgba(var(--text-color), 0.06); +ul { + list-style: none; } -ul{ - list-style: none; +.accent-color { + color: var(--accent-color); } -.accent-color{ - color: var(--accent-color); +.flex { + display: flex; } -.flex{ - display: flex; +.flex-wrap { + flex-wrap: wrap; } -.grid{ - display: grid; +.grid { + display: grid; } -.grid-3{ - grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr)); +.grid-3 { + grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr)); } -.flow-column{ - grid-auto-flow: column; +.flow-column { + grid-auto-flow: column; } -.gap-0-5{ - gap: 0.5rem; +.gap-0-5 { + gap: 0.5rem; } -.gap-1{ - gap: 1rem; +.gap-1 { + gap: 1rem; } -.gap-1-5{ - gap: 1.5rem; +.gap-1-5 { + gap: 1.5rem; } -.gap-2{ - gap: 2rem; +.gap-2 { + gap: 2rem; } -.gap-3{ - gap: 3rem; +.gap-3 { + gap: 3rem; } -.pos-relative{ - position: relative; +.pos-relative { + position: relative; } -.text-align-right{ - text-align: right; +.text-align-right { + text-align: right; } -.align-start{ - align-items: flex-start; +.align-start { + align-items: flex-start; } -.align-center{ - align-items: center; +.align-center { + align-items: center; } -.align-end{ - align-content: flex-end; +.align-end { + align-content: flex-end; } -.text-center{ - text-align: center; +.text-center { + text-align: center; } -.justify-start{ - justify-content: start; +.justify-start { + justify-content: start; } -.justify-center{ - justify-content: center; +.justify-center { + justify-content: center; } -.justify-end{ - justify-content: end; +.justify-end { + justify-content: end; } -.justify-right{ - margin-left: auto; +.justify-right { + margin-left: auto; } -.align-self-center{ - align-self: center; +.align-self-center { + align-self: center; } -.justify-self-center{ - justify-self: center; +.justify-self-center { + justify-self: center; } -.justify-self-start{ - justify-self: start; +.justify-self-start { + justify-self: start; } -.justify-self-end{ - justify-self: end; +.justify-self-end { + justify-self: end; } -.direction-column{ - flex-direction: column; +.direction-column { + flex-direction: column; } -.space-between{ - justify-content: space-between; +.space-between { + justify-content: space-between; } -.w-100{ - width: 100%; +.w-100 { + width: 100%; } -.margin-top-1-5{ - margin-top: 1.5rem; +.margin-top-1-5 { + margin-top: 1.5rem; } -.margin-bottom-0-5r{ - margin-bottom: 0.5rem; +.margin-bottom-0-5r { + margin-bottom: 0.5rem; } -.margin-bottom-1r{ - margin-bottom: 1rem; +.margin-bottom-1r { + margin-bottom: 1rem; } -.margin-bottom-1-5r{ - margin-bottom: 1.5rem; +.margin-bottom-1-5r { + margin-bottom: 1.5rem; } -.margin-bottom-2r{ - margin-bottom: 2rem; +.margin-bottom-2r { + margin-bottom: 2rem; } -.margin-bottom-3r{ - margin-bottom: 3rem; +.margin-bottom-3r { + margin-bottom: 3rem; } -.margin-bottom-4r{ - margin-bottom: 4rem; +.margin-bottom-4r { + margin-bottom: 4rem; } -.margin-left-0-5{ - margin-left: 0.5rem; +.margin-left-0-5 { + margin-left: 0.5rem; } -.margin-right-0-5{ - margin-right: 0.5rem; +.margin-right-0-5 { + margin-right: 0.5rem; } -.color-0-9{ - color: rgba(var(--text-color), 0.9); +.color-0-9 { + color: rgba(var(--text-color), 0.9); } -.color-0-8{ - color: rgba(var(--text-color), 0.8); +.color-0-8 { + color: rgba(var(--text-color), 0.8); } -.color-0-7{ - color: rgba(var(--text-color), 0.7); +.color-0-7 { + color: rgba(var(--text-color), 0.7); } -.weight-400{ - font-weight: 400; +.weight-400 { + font-weight: 400; } -.weight-500{ - font-weight: 500; +.weight-500 { + font-weight: 500; } -.weight-700{ - font-weight: 700; +.weight-700 { + font-weight: 700; } -.weight-900{ - font-weight: 900; +.weight-900 { + font-weight: 900; } -.hide{ - opacity: 0; - pointer-events: none; +.hide { + opacity: 0; + pointer-events: none; } -.hide-completely{ - display: none !important; +.hide-completely { + display: none !important; } -.no-transformations{ - transform: none !important; +.no-transformations { + transform: none !important; } -.overflow-ellipsis{ - width: 100%; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; +.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; - -moz-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; +.breakable { + overflow-wrap: break-word; + word-wrap: break-word; + -ms-word-break: break-all; + word-break: break-word; + -ms-hyphens: auto; + -moz-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; } -.ripple{ - position: absolute; - border-radius: 50%; - transform: scale(0); - background: rgba(var(--text-color), 0.16); - pointer-events: none; +.ripple { + height: 8rem; + width: 8rem; + position: absolute; + border-radius: 50%; + transform: scale(0); + background: radial-gradient( + circle, + rgba(var(--text-color), 0.3) 0%, + rgba(0, 0, 0, 0) 50% + ); + pointer-events: none; } -.interact{ - position: relative; - overflow: hidden; - cursor: pointer; - -webkit-tap-highlight-color: transparent; +.interact { + position: relative; + overflow: hidden; + cursor: pointer; + -webkit-tap-highlight-color: transparent; } -.observe-empty-state:empty{ - display: none; +.observe-empty-state:empty { + display: none; } -.observe-empty-state:not(:empty) ~ .empty-state{ - display: none; +.observe-empty-state:not(:empty) ~ .empty-state { + display: none; } -.icon{ - width: 1.5rem; - height: 1.5rem; - fill: rgba(var(--text-color), 0.9); +.icon { + width: 1.5rem; + height: 1.5rem; + fill: rgba(var(--text-color), 0.9); } #loading_page, -#error_page{ - position: relative; - display: grid; - height: 100%; - place-content: center; - justify-items: center; +#error_page { + position: relative; + display: grid; + height: 100%; + place-content: center; + justify-items: center; } -.sad-face{ - height: 6rem; - margin: 1rem; - fill: rgba(var(--text-color), 1); - .eyes{ - transform-origin: center; - animation: blink 1s infinite alternate; - } - .face{ - animation: nod 2s 1s; - } +.sad-face { + height: 6rem; + margin: 1rem; + fill: rgba(var(--text-color), 1); + .eyes { + transform-origin: center; + animation: blink 1s infinite alternate; + } + .face { + animation: nod 2s 1s; + } } @keyframes blink { - 0%{ - transform: scaleY(1); - } - 80%{ - transform: scaleY(1); - } - 100%{ - transform: scaleY(0); - } + 0% { + transform: scaleY(1); + } + 80% { + transform: scaleY(1); + } + 100% { + transform: scaleY(0); + } } -@keyframes nod{ - 0%{ - transform: translateX(0); - } - 20%{ - transform: translateX(-1.5rem); - } - 30%{ - transform: translateX(1.5rem); - } - 40%{ - transform: translateX(-1rem); - } - 50%{ - transform: translateX(1rem); - } - 60%{ - transform: translateX(-0.7rem); - } - 70%{ - transform: translateX(0.7rem); - } - 80%{ - transform: translateX(-0.5rem); - } - 90%{ - transform: translateX(0.5rem); - } - 100%{ - transform: translateX(0); - } +@keyframes nod { + 0% { + transform: translateX(0); + } + 20% { + transform: translateX(-1.5rem); + } + 30% { + transform: translateX(1.5rem); + } + 40% { + transform: translateX(-1rem); + } + 50% { + transform: translateX(1rem); + } + 60% { + transform: translateX(-0.7rem); + } + 70% { + transform: translateX(0.7rem); + } + 80% { + transform: translateX(-0.5rem); + } + 90% { + transform: translateX(0.5rem); + } + 100% { + transform: translateX(0); + } } -.page__footer{ - position: absolute; - padding: 3rem; - bottom: 0; +.page__footer { + position: absolute; + padding: 3rem; + bottom: 0; } -#rm_logo{ - width: auto; - height: 2rem; - fill: rgba(var(--text-color), 1); +#rm_logo { + width: auto; + height: 2rem; + fill: rgba(var(--text-color), 1); } -#loader{ - display: flex; - position: relative; - width: 4rem; - height: 8rem; - fill: none; - stroke-width: 4; - stroke-linecap: round; - stroke: rgba(var(--text-color), 1); - polyline:nth-of-type(2), - polyline:nth-of-type(3), - polyline:nth-of-type(4){ - stroke-dasharray: 60; - animation: loading infinite 1s; - } +#loader { + display: flex; + position: relative; + width: 4rem; + height: 8rem; + fill: none; + stroke-width: 4; + stroke-linecap: round; + stroke: rgba(var(--text-color), 1); + polyline:nth-of-type(2), + polyline:nth-of-type(3), + polyline:nth-of-type(4) { + stroke-dasharray: 60; + animation: loading infinite 1s; + } } @keyframes loading { - 0%{ - stroke-dashoffset: -60; - } - 50%{ - stroke-dashoffset: 0; - } - 100%{ - stroke-dashoffset: 60; - } + 0% { + stroke-dashoffset: -60; + } + 50% { + stroke-dashoffset: 0; + } + 100% { + stroke-dashoffset: 60; + } } +#main_header { + position: relative; + display: grid; + gap: 1.5rem; + padding: 1rem; + align-items: center; + background-color: var(--accent-color); + color: white; +} +#main_header__logo { + fill: white; + height: 2.4rem; + width: 2.4rem; + margin-left: -0.3rem; +} +.header__company-name { + font-weight: 500; +} +.header__app-name { + font-weight: 700; + font-size: 1.2rem; +} +#current_price { + justify-self: flex-start; +} +#usd-rate { + display: flex; + align-items: center; + &::before { + content: ""; + width: 1px; + height: 2rem; + background-color: white; + margin-right: 1rem; + } +} -#main_header{ - position: relative; - display: grid; - gap: 1.5rem; +.dropdown { + display: flex; + justify-content: flex-end; + z-index: 5; +} +.dropdown__panel { + position: absolute; + display: grid; + left: 0; + right: 0; + top: 100%; + margin: 0 1rem; + margin-top: 0.5rem; + border-radius: 0.3rem; + grid-template-columns: 1fr; + justify-content: flex-start; + color: rgba(var(--text-color), 1); + width: min(24rem, calc(100vw - 2rem)); + background-color: rgba(var(--foreground-color), 1); + box-shadow: 0 2rem 2rem -0.5rem rgba($color: #000000, $alpha: 0.16); + li { padding: 1rem; - align-items: center; - background-color: var(--accent-color); - color: white; + } } -#main_header__logo{ + +#profile_button { + align-items: center; + justify-content: center; + border: none; + height: 2.2rem; + width: 2.2rem; + justify-self: flex-end; + border-radius: 50%; + background-color: rgba($color: #000000, $alpha: 0.16); + .icon { + height: 1rem; + width: 1rem; fill: white; - height: 2.4rem; - width: 2.4rem; - margin-left: -0.3rem; + } } -.header__company-name{ - font-weight: 500; + +#theme_switcher { + overflow: hidden; + width: 100%; } -.header__app-name{ + +.page-layout { + display: grid; + grid-template-columns: 1rem minmax(0, 1fr) 1rem; + & > * { + grid-column: 2/3; + } +} + +#home_page { + --side-padding: 8vw; + display: flex; + flex-direction: column; + padding: 0 max(1rem, var(--side-padding)); + padding-bottom: 6rem; +} +#homepage__hero-section { + color: white; + padding: 2rem 0 12rem 0; + margin: 0 calc(-1 * max(1rem, var(--side-padding))) -8rem calc(-1 * max(1rem, var(--side-padding))); + background-image: url(../assets/bg-1.svg); + background-color: var(--accent-color); + background-size: cover; + p { + color: rgba($color: #fff, $alpha: 0.8); + } +} + +.fund-list__header { + color: white; + align-items: center; + gap: 1rem; +} + +#search_investor { + --background: rgba(var(--foreground-color), 1); + color: rgba(var(--text-color), 1); + grid-area: search; + width: min(20rem, 100%); + justify-self: flex-end; +} + +.label { + font-weight: 500; + font-size: 0.85rem; + margin-bottom: 0.3rem; + color: rgba(var(--text-color), 0.8); +} +.value { + font-weight: 700; + font-size: 1rem; + overflow-wrap: break-word; + word-wrap: break-word; + -ms-word-break: break-all; + word-break: break-word; + -ms-hyphens: auto; + -moz-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +.warning-container { + padding: 1rem; + margin-bottom: 1rem; + border-radius: 0.3rem; + background-color: rgba(var(--foreground-color), 1); + box-shadow: 0 1rem 2rem -1rem rgba($color: #000000, $alpha: 0.16); +} + +#fund_list { + display: grid; + gap: 1.5rem; +} + +#fund_list__empty-state { + padding: 4rem 0; + border-radius: 0.3rem; + place-content: center; + margin-bottom: 3rem; + background-color: rgba(var(--foreground-color), 1); + box-shadow: 0 1rem 2rem -1rem rgba($color: #000000, $alpha: 0.16); + .icon--big { + height: 6rem; + width: 6rem; + justify-self: center; + } +} + +fund-block { + &:first-of-type::before { + display: inline-flex; + content: "• Latest Fund"; + padding: 0.4rem 0.8rem; font-weight: 700; - font-size: 1.2rem; -} -#current_price{ - justify-self: flex-start; -} -#usd-rate{ - display: flex; - align-items: center; - &::before{ - content: ''; - width: 1px; - height: 2rem; - background-color: white; - margin-right: 1rem; - } -} - -sm-select{ - min-width: 6rem; - --selection-font-size: 0.9rem; -} -sm-option{ - --color: rgba(var(--text-color), 1); -} - -.dropdown{ - display: flex; - justify-content: flex-end; - z-index: 5; -} -.dropdown__panel{ - position: absolute; - display: grid; - left: 0; - right: 0; - top: 100%; - margin: 0 1rem; - margin-top: 0.5rem; - border-radius: 0.3rem; - grid-template-columns: 1fr; - justify-content: flex-start; - color: rgba(var(--text-color), 1); - width: min(24rem, calc(100vw - 2rem)); - background-color: rgba(var(--foreground-color), 1); - box-shadow: 0 2rem 2rem -0.5rem rgba($color: #000000, $alpha: 0.16); - li{ - padding: 1rem; - } -} - -#profile_button{ - align-items: center; - justify-content: center; - border: none; - height: 2.2rem; - width: 2.2rem; - justify-self: flex-end; - border-radius: 50%; - background-color: rgba($color: #000000, $alpha: 0.16); - .icon{ - height: 1rem; - width: 1rem; - fill: white; - } -} - -#theme_switcher{ - overflow: hidden; - width: 100%; -} - -.page-layout{ - display: grid; - grid-template-columns: 1rem 1fr 1rem; - & > *{ - grid-column: 2/3; - } -} - -#home_page{ - padding-bottom: 6rem; -} - -#homepage__hero-section{ + font-size: 1rem; color: white; - padding: 2rem 0 12rem 0; - margin-bottom: -8rem; - background-image: url(../assets/bg-1.svg); background-color: var(--accent-color); - background-size: cover; - p{ - color: rgba($color: #fff, $alpha: 0.8); - } + border-radius: 0.3rem 0.3rem 0 0; + } + &:not(:last-of-type)::after { + display: flex; + content: ""; + // justify-content: center; + padding: 0.4rem 0; + font-weight: 700; + width: 100%; + // font-size: 0.9rem; + // color: var(--background-color); + background-color: var(--error-color); + border-radius: 0 0 0.5rem 0.5rem; + } } -.fund-list__header{ - color: white; - align-items: center; - gap: 1rem; +.flex-grid { + grid-template-columns: repeat(auto-fill, minmax(24rem, 1fr)); } -#search_investor{ - --font-weight: 500; - --padding: 0.5rem 1rem; - --background: rgba(var(--foreground-color), 1); - color: rgba(var(--text-color), 1); - grid-area: search; - width: min(24rem ,100%); - justify-self: flex-end; - .icon{ - height: 1.2rem; - width: 1.2rem; - margin-left: -0.5rem; - } +form { + padding: 1rem; + border-radius: 0.3rem; + width: min(32rem, 100%); + margin-bottom: 3rem; + background: rgba(var(--foreground-color), 1); + input { + display: inline-flex; + color: inherit; + font-family: inherit; + padding: 0.6rem; + border: none; + box-shadow: 0 0 0 1px rgba(var(--text-color), 0.3); + background-color: rgba(var(--text-color), 0.06); + flex: 1; + } + select option { + color: inherit; + background-color: rgba(var(--text-color), 0.1); + } } -.label{ - font-weight: 500; - font-size: 0.75rem; - margin-bottom: 0.2rem; - color: rgba(var(--text-color), 0.8); +.investor-input { + gap: 0.5rem; } -.value{ - font-weight: 600; - font-size: 0.9rem; - overflow-wrap: break-word; - word-wrap: break-word; - -ms-word-break: break-all; - word-break: break-word; - -ms-hyphens: auto; - -moz-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - -.warning-container{ - padding: 1rem; - margin-bottom: 1rem; - border-radius: 0.3rem; - background-color: rgba(var(--foreground-color), 1); - box-shadow: 0 1rem 2rem -1rem rgba($color: #000000, $alpha: 0.16); -} - -#fund_list{ - display: grid; - gap: 1.5rem; -} - -#fund_list__empty-state{ - padding: 4rem 0; - border-radius: 0.3rem; - place-content: center; - margin-bottom: 3rem; - background-color: rgba(var(--foreground-color), 1); - box-shadow: 0 1rem 2rem -1rem rgba($color: #000000, $alpha: 0.16); - .icon--big{ - height: 6rem; - width: 6rem; - justify-self: center; - } -} - -fund-block{ - &:first-of-type::before{ - display: inline-flex; - content: '• Latest Fund'; - padding: 0.4rem 0.8rem; - font-weight: 700; - font-size: 1rem; - color: white; - background-color: var(--accent-color); - border-radius: 0.3rem 0.3rem 0 0; - } - &:not(:last-of-type)::after{ - display: flex; - content: ''; - // justify-content: center; - padding: 0.4rem 0; - font-weight: 700; - width: 100%; - // font-size: 0.9rem; - // color: var(--background-color); - background-color: var(--error-color); - border-radius: 0 0 0.5rem 0.5rem; - } -} - -.flex-grid{ - grid-template-columns: repeat(auto-fill, minmax(24rem, 1fr)); -} - - -form{ - padding: 1rem; - border-radius: 0.3rem; - width: min(32rem, 100%); - margin-bottom: 3rem; - background: rgba(var(--foreground-color), 1); - input{ - display: inline-flex; - color: inherit; - font-family: inherit; - padding: 0.6rem; - border: none; - box-shadow: 0 0 0 1px rgba(var(--text-color), 0.3); - background-color: rgba(var(--text-color), 0.06); - flex: 1; - } - select option{ - color: inherit; - background-color: rgba(var(--text-color), 0.1); - } -} - -.investor-input{ - gap: 0.5rem; -} -.remove-investor{ - grid-area: close; +.remove-investor { + grid-area: close; } #term_details, -#fund_details{ - line-height: 1.7; - margin-bottom: 2rem; +#fund_details { + line-height: 1.7; + margin-bottom: 2rem; } -.flex-grid{ - display: grid; - gap: 1rem; - justify-content: start; - grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); +.flex-grid { + display: grid; + gap: 1rem; + justify-content: start; + grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); } -.fund-placeholder{ - gap: 1rem; - padding: 1rem; - border-radius: 0.3rem; - background-color: rgba(var(--foreground-color), 1); - box-shadow: 0 1rem 2rem -1rem rgba($color: #000000, $alpha: 0.16); - .placeholder__block:first-of-type{ - width: min(24rem, 100%); - } - &:nth-of-type(2) .placeholder__block{ - animation-delay: 0.3s; - } - &:nth-of-type(3) .placeholder__block{ - animation-delay: 0.6s; - } - &:nth-of-type(4) .placeholder__block{ - animation-delay: 0.8s; - } +.fund-placeholder { + gap: 1rem; + padding: 1rem; + border-radius: 0.3rem; + background-color: rgba(var(--foreground-color), 1); + box-shadow: 0 1rem 2rem -1rem rgba($color: #000000, $alpha: 0.16); + .placeholder__block:first-of-type { + width: min(24rem, 100%); + } + &:nth-of-type(2) .placeholder__block { + animation-delay: 0.3s; + } + &:nth-of-type(3) .placeholder__block { + animation-delay: 0.6s; + } + &:nth-of-type(4) .placeholder__block { + animation-delay: 0.8s; + } } -.placeholder__block{ - display: flex; - border-radius: 0.3rem; - min-width: 9rem; - padding: 1.2rem 1rem; - animation: pulse alternate 0.6s ease infinite; - background-color: rgba(var(--text-color), 0.1); +.placeholder__block { + display: flex; + border-radius: 0.3rem; + min-width: 9rem; + padding: 1.2rem 1rem; + animation: pulse alternate 0.6s ease infinite; + background-color: rgba(var(--text-color), 0.1); } -@keyframes pulse{ - from{ - opacity: 0.4; - } - to{ - opacity: 1; - } +@keyframes pulse { + from { + opacity: 0.4; + } + to { + opacity: 1; + } +} +.fund-investor { + display: grid; + gap: 1rem; + padding: 1rem 0; + background-color: rgba(var(--foreground-color), 1); +} +.transaction-column { + display: flex; + flex-direction: column; +} +.space-between { + justify-content: space-between; +} +.fund-block { + border-radius: 0.5rem; + padding: 1rem; + background-color: rgba(var(--foreground-color), 1); + box-shadow: 0 1rem 2rem -1rem rgba($color: #000000, $alpha: 0.16); +} +.fund-block__details { + gap: 1.5rem; +} +.tapout-container, +.investment-container { + grid-column: 1/3; +} +.investment-container { + gap: 1.5rem; + justify-content: flex-start; + grid-template-columns: 1fr 1fr; +} +.tapout-list { + display: grid; + gap: 1.5rem; + overflow-x: auto; + grid-auto-flow: column; + justify-content: flex-start; +} +.tapout-list li { + min-width: 8rem; +} +.fund-link { + justify-self: flex-end; +} +.investor-group { + display: grid; + padding: 0.5rem; + margin-top: 1.8rem; + border-radius: 0.3rem; + box-shadow: 0 0 0 1px rgba(var(--text-color), 0.3); +} +.investor-group header { + margin-top: -1.5rem; + margin-bottom: 0.5rem; + justify-self: flex-end; +} +.investor-group > * { + background-color: rgba(var(--foreground-color), 1); +} +.investor-group h4 { + padding: 0 0.5rem; + margin-left: -0.5rem; +} +.investor-group__list { + display: grid; + gap: 0.8rem; + grid-template-columns: minmax(0, 1fr); } - @media only screen and (max-width: 640px) { - .h1{ - font-size: 2rem; - } - .h2{ - font-size: 1.8rem; - } - .h3{ - font-size: 1.3rem; - } - .h4{ - font-size: 1rem; - } - .h5{ - font-size: 0.8rem; - } - #main_header{ - grid-template-areas: '. profile-button'; - .dropdown{ - grid-area: profile-button; - } - } - #homepage__hero-section{ - padding: 2rem 0 20rem 0; - margin-bottom: -16rem; - } - .fund-list__header{ - grid-template-columns: auto 1fr; - grid-template-areas: '. .' 'search search'; - } - .investor-input{ - grid-template-columns: 1fr auto; - grid-template-areas: '. close' '. close'; + .h1 { + font-size: 2rem; + } + .h2 { + font-size: 1.8rem; + } + .h3 { + font-size: 1.3rem; + } + .h4 { + font-size: 1rem; + } + .h5 { + font-size: 0.8rem; + } + #main_header { + grid-template-areas: ". profile-button"; + .dropdown { + grid-area: profile-button; } + } + #homepage__hero-section { + padding: 2rem 0 20rem 0; + margin-bottom: -16rem; + } + .fund-list__header { + grid-template-columns: auto 1fr; + grid-template-areas: ". ." "search search"; + } + .investor-input { + grid-template-columns: 1fr auto; + grid-template-areas: ". close" ". close"; + } + .fund-link { + grid-column: 2/3; + } } - - @media only screen and (min-width: 640px) { - #main_header{ - padding: 2rem calc((10vw / 2) - 0.4rem); - grid-template-columns: auto 1fr auto; - &::after{ - height: 5rem; - } - } - .page-layout{ - grid-template-columns: 1fr 90vw 1fr; - } - #current_price{ - justify-self: flex-end; - } - .dropdown__panel{ - left: auto; - } - .fund-list__header{ - grid-template-columns: auto 1fr auto; - grid-template-areas: '. search .'; - } - .investor-input{ - grid-template-columns: 1.5fr 1fr auto; - grid-template-areas: '. . close'; + #main_header { + padding: 2rem calc((10vw / 2) - 0.4rem); + grid-template-columns: auto 1fr auto; + &::after { + height: 5rem; } + } + .page-layout { + grid-template-columns: 1fr 90vw 1fr; + } + .value { + min-width: 9rem; + } + #current_price { + justify-self: flex-end; + } + .dropdown__panel { + left: auto; + } + .fund-list__header { + grid-template-columns: auto 1fr auto; + grid-template-areas: ". search ."; + } + .investor-input { + grid-template-columns: 1.5fr 1fr auto; + grid-template-areas: ". . close"; + } + .fund-block { + padding: 1.5rem; + } + .fund-block__details { + grid-template-columns: 1fr 1fr; + } + .investor-group { + padding: 0.5rem 1rem; + } + .justify-self-end { + justify-self: flex-end; + text-align: right; + } + .investment-container { + grid-template-columns: auto auto 1fr; + } } @media only screen and (min-width: 1280px) { - .page-layout{ - grid-template-columns: 1fr 90vw 1fr; - } - .multi-form{ - grid-template-columns: 1fr 1fr; - } + .page-layout { + grid-template-columns: 1fr 90vw 1fr; + } + .multi-form { + grid-template-columns: 1fr 1fr; + } + .fund-investor { + gap: 1.5rem; + grid-template-columns: 1fr auto; + } } -@media (any-hover: hover){ - ::-webkit-scrollbar{ - width: 0.5rem; - height: 0.5rem; +@media (any-hover: hover) { + ::-webkit-scrollbar { + width: 0.5rem; + height: 0.5rem; + } + + ::-webkit-scrollbar-thumb { + background: rgba(var(--text-color), 0.3); + border-radius: 1rem; + &:hover { + background: rgba(var(--text-color), 0.5); } - - ::-webkit-scrollbar-thumb{ - background: rgba(var(--text-color), 0.3); - border-radius: 1rem; - &:hover{ - background: rgba(var(--text-color), 0.5); - } - } -} \ No newline at end of file + } +} diff --git a/index.html b/index.html index 6d17555..3aac02b 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,17 @@ + Bob's Fund on Blockchain - - + + + + + + getRef('confirm_fund_button').onclick = () => { + const privKey = getRef('get_fund_private_key').value + console.log(privKey) + if (!floCrypto.verifyPrivKey(privKey, floGlobals.adminID)) { + notify("Access Denied! incorrect private key", 'error'); + return + } + floBlockchainAPI.writeData(floGlobals.adminID, fStr, privKey, floGlobals.adminID).then(result => { + console.log(result); + showPage('admin_page') + notify(createMod ? "New Fund created" : "Invesments added to fund", 'success'); + getRef("create_fund_form").reset() + clearAddedInvestors() + refresh(false) + }).catch(error => console.error(error)) + } + }) + + + \ No newline at end of file diff --git a/scripts/components.min.js b/scripts/components.min.js new file mode 100644 index 0000000..7033619 --- /dev/null +++ b/scripts/components.min.js @@ -0,0 +1,6 @@ +const smForm = document.createElement("template"); smForm.innerHTML = '\n \n
\n \n
\n ', customElements.define("sm-form", class extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(smForm.content.cloneNode(!0)), this.form = this.shadowRoot.querySelector("form"), this.formElements, this.requiredElements, this.submitButton, this.resetButton, this.invalidFields = !1, this.mutationObserver, this.debounce = this.debounce.bind(this), this._checkValidity = this._checkValidity.bind(this), this.handleKeydown = this.handleKeydown.bind(this), this.reset = this.reset.bind(this), this.elementsChanged = this.elementsChanged.bind(this) } debounce(t, e) { let i = null; return (...s) => { window.clearTimeout(i), i = window.setTimeout(() => { t.apply(null, s) }, e) } } _checkValidity() { this.submitButton && (this.invalidFields = this.requiredElements.filter(t => !t.isValid), this.submitButton.disabled = this.invalidFields.length) } handleKeydown(t) { "Enter" === t.key && t.target.tagName.includes("SM-INPUT") && (this.invalidFields.length ? this.requiredElements.forEach(t => { t.isValid || t.vibrate() }) : (this.submitButton && this.submitButton.click(), this.dispatchEvent(new CustomEvent("submit", { bubbles: !0, composed: !0 })))) } reset() { this.formElements.forEach(t => t.reset()) } elementsChanged() { this.formElements = [...this.querySelectorAll("sm-input, sm-textarea, sm-checkbox, tags-input, file-input, sm-switch, sm-radio")], this.requiredElements = this.formElements.filter(t => t.hasAttribute("required")), this.submitButton = this.querySelector('[variant="primary"], [type="submit"]'), this.resetButton = this.querySelector('[type="reset"]'), this.resetButton && this.resetButton.addEventListener("click", this.reset), this._checkValidity() } connectedCallback() { this.shadowRoot.querySelector("slot").addEventListener("slotchange", this.elementsChanged), this.addEventListener("input", this.debounce(this._checkValidity, 100)), this.addEventListener("keydown", this.debounce(this.handleKeydown, 100)), this.mutationObserver = new MutationObserver(t => { t.forEach(t => { "childList" === t.type && this.elementsChanged() }) }), this.mutationObserver.observe(this, { childList: !0, subtree: !0 }) } disconnectedCallback() { this.removeEventListener("input", this.debounce(this._checkValidity, 100)), this.removeEventListener("keydown", this.debounce(this.handleKeydown, 100)), this.mutationObserver.disconnect() } }); +const smInput = document.createElement("template"); smInput.innerHTML = '\n \n
\n \n \n \n
\n ', customElements.define("sm-input", class extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(smInput.content.cloneNode(!0)), this.inputParent = this.shadowRoot.querySelector(".input"), this.input = this.shadowRoot.querySelector("input"), this.clearBtn = this.shadowRoot.querySelector(".clear"), this.label = this.shadowRoot.querySelector(".label"), this.feedbackText = this.shadowRoot.querySelector(".feedback-text"), this.outerContainer = this.shadowRoot.querySelector(".outer-container"), this.optionList = this.shadowRoot.querySelector(".datalist"), this._helperText = "", this._errorText = "", this.isRequired = !1, this.datalist = [], this.validationFunction = void 0, this.reflectedAttributes = ["value", "required", "disabled", "type", "inputmode", "readonly", "min", "max", "pattern", "minlength", "maxlength", "step", "list", "autocomplete"], this.reset = this.reset.bind(this), this.clear = this.clear.bind(this), this.focusIn = this.focusIn.bind(this), this.focusOut = this.focusOut.bind(this), this.fireEvent = this.fireEvent.bind(this), this.checkInput = this.checkInput.bind(this), this.allowOnlyNum = this.allowOnlyNum.bind(this), this.vibrate = this.vibrate.bind(this), this.handleOptionClick = this.handleOptionClick.bind(this), this.handleInputNavigation = this.handleInputNavigation.bind(this), this.handleDatalistNavigation = this.handleDatalistNavigation.bind(this), this.handleFocus = this.handleFocus.bind(this), this.handleBlur = this.handleBlur.bind(this) } static get observedAttributes() { return ["value", "placeholder", "required", "disabled", "type", "inputmode", "readonly", "min", "max", "pattern", "minlength", "maxlength", "step", "helper-text", "error-text", "list"] } get value() { return this.input.value } set value(t) { t !== this.input.value && (this.input.value = t, this.checkInput()) } get placeholder() { return this.getAttribute("placeholder") } set placeholder(t) { this.setAttribute("placeholder", t) } get type() { return this.getAttribute("type") } set type(t) { this.setAttribute("type", t) } get validity() { return this.input.validity } get disabled() { return this.hasAttribute("disabled") } set disabled(t) { t ? this.inputParent.classList.add("disabled") : this.inputParent.classList.remove("disabled") } get readOnly() { return this.hasAttribute("readonly") } set readOnly(t) { t ? this.setAttribute("readonly", "") : this.removeAttribute("readonly") } set customValidation(t) { this.validationFunction = t } set errorText(t) { this._errorText = t } set helperText(t) { this._helperText = t } get isValid() { if ("" !== this.input.value) { const t = this.input.checkValidity(); let e = !0; return this.validationFunction && (e = Boolean(this.validationFunction(this.input.value))), t && e ? (this.feedbackText.classList.remove("error"), this.feedbackText.classList.add("success"), this.feedbackText.textContent = "") : this._errorText && (this.feedbackText.classList.add("error"), this.feedbackText.classList.remove("success"), this.feedbackText.innerHTML = `\n \n ${this._errorText}`), t && e } } reset() { this.value = "" } clear() { this.value = "", this.input.focus(), this.fireEvent() } focusIn() { this.input.focus() } focusOut() { this.input.blur() } fireEvent() { let t = new Event("input", { bubbles: !0, cancelable: !0, composed: !0 }); this.dispatchEvent(t) } searchDatalist(t) { const e = this.datalist.filter(e => e.toLowerCase().includes(t.toLowerCase())); if (e.sort((e, n) => { const i = e.toLowerCase().indexOf(t.toLowerCase()), s = n.toLowerCase().indexOf(t.toLowerCase()); return i - s }), e.length) { if (this.optionList.children.length > e.length) { const t = this.optionList.children.length - e.length; for (let e = 0; e < t; e++)this.optionList.removeChild(this.optionList.lastChild) } e.forEach((t, e) => { if (this.optionList.children[e]) this.optionList.children[e].textContent = t; else { const e = document.createElement("li"); e.textContent = t, e.classList.add("datalist-item"), e.setAttribute("tabindex", "0"), this.optionList.appendChild(e) } }), this.optionList.classList.remove("hidden") } else this.optionList.classList.add("hidden") } checkInput(t) { this.hasAttribute("readonly") || (this.clearBtn.style.visibility = "" !== this.input.value ? "visible" : "hidden"), this.hasAttribute("placeholder") && "" !== this.getAttribute("placeholder").trim() && ("" !== this.input.value ? (this.animate ? this.inputParent.classList.add("animate-placeholder") : this.label.classList.add("hidden"), this.datalist.length && (this.searchTimeout && clearTimeout(this.searchTimeout), this.searchTimeout = setTimeout(() => { this.searchDatalist(this.input.value.trim()) }, 100))) : (this.animate ? this.inputParent.classList.remove("animate-placeholder") : this.label.classList.remove("hidden"), this.feedbackText.textContent = "", this.datalist.length && (this.optionList.innerHTML = "", this.optionList.classList.add("hidden")))) } allowOnlyNum(t) { 1 === t.key.length && (("." !== t.key || !t.target.value.includes(".") && 0 !== t.target.value.length) && ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."].includes(t.key) || t.preventDefault()) } vibrate() { this.outerContainer.animate([{ transform: "translateX(-1rem)" }, { transform: "translateX(1rem)" }, { transform: "translateX(-0.5rem)" }, { transform: "translateX(0.5rem)" }, { transform: "translateX(0)" }], { duration: 300, easing: "ease" }) } handleOptionClick(t) { this.input.value = t.target.textContent, this.optionList.classList.add("hidden"), this.input.focus() } handleInputNavigation(t) { "ArrowDown" === t.key ? (t.preventDefault(), this.optionList.children.length && this.optionList.children[0].focus()) : "ArrowUp" === t.key && (t.preventDefault(), this.optionList.children.length && this.optionList.children[this.optionList.children.length - 1].focus()) } handleDatalistNavigation(t) { "ArrowUp" === t.key ? (t.preventDefault(), this.shadowRoot.activeElement.previousElementSibling ? this.shadowRoot.activeElement.previousElementSibling.focus() : this.input.focus()) : "ArrowDown" === t.key ? (t.preventDefault(), this.shadowRoot.activeElement.nextElementSibling ? this.shadowRoot.activeElement.nextElementSibling.focus() : this.input.focus()) : "Enter" !== t.key && " " !== t.key || (t.preventDefault(), this.input.value = t.target.textContent, this.optionList.classList.add("hidden"), this.input.focus()) } handleFocus(t) { this.datalist.length && this.searchDatalist(this.input.value.trim()) } handleBlur(t) { this.datalist.length && this.optionList.classList.add("hidden") } connectedCallback() { this.animate = this.hasAttribute("animate"), this.setAttribute("role", "textbox"), this.input.addEventListener("input", this.checkInput), this.clearBtn.addEventListener("click", this.clear), this.datalist.length && (this.optionList.addEventListener("click", this.handleOptionClick), this.input.addEventListener("keydown", this.handleInputNavigation), this.optionList.addEventListener("keydown", this.handleDatalistNavigation)), this.input.addEventListener("focusin", this.handleFocus), this.addEventListener("focusout", this.handleBlur) } attributeChangedCallback(t, e, n) { e !== n && (this.reflectedAttributes.includes(t) && (this.hasAttribute(t) ? this.input.setAttribute(t, this.getAttribute(t) ? this.getAttribute(t) : "") : this.input.removeAttribute(t)), "placeholder" === t ? (this.label.textContent = n, this.setAttribute("aria-label", n)) : this.hasAttribute("value") ? this.checkInput() : "type" === t ? this.hasAttribute("type") && "number" === this.getAttribute("type") ? (this.input.setAttribute("inputmode", "decimal"), this.input.addEventListener("keydown", this.allowOnlyNum)) : this.input.removeEventListener("keydown", this.allowOnlyNum) : "helper-text" === t ? this._helperText = this.getAttribute("helper-text") : "error-text" === t ? this._errorText = this.getAttribute("error-text") : "required" === t ? (this.isRequired = this.hasAttribute("required"), this.isRequired ? this.setAttribute("aria-required", "true") : this.setAttribute("aria-required", "false")) : "readonly" === t ? this.hasAttribute("readonly") ? this.inputParent.classList.add("readonly") : this.inputParent.classList.remove("readonly") : "disabled" === t ? this.hasAttribute("disabled") ? this.inputParent.classList.add("disabled") : this.inputParent.classList.remove("disabled") : "list" === t && this.hasAttribute("list") && "" !== this.getAttribute("list").trim() && (this.datalist = this.getAttribute("list").split(","))) } disconnectedCallback() { this.input.removeEventListener("input", this.checkInput), this.clearBtn.removeEventListener("click", this.clear), this.input.removeEventListener("keydown", this.allowOnlyNum), this.optionList.removeEventListener("click", this.handleOptionClick), this.input.removeEventListener("keydown", this.handleInputNavigation), this.optionList.removeEventListener("keydown", this.handleDatalistNavigation), this.input.removeEventListener("focusin", this.handleFocus), this.removeEventListener("focusout", this.handleBlur) } }); +const smNotifications = document.createElement("template"); smNotifications.innerHTML = '\n \n
\n ', customElements.define("sm-notifications", class extends HTMLElement { constructor() { super(), this.shadow = this.attachShadow({ mode: "open" }).append(smNotifications.content.cloneNode(!0)), this.notificationPanel = this.shadowRoot.querySelector(".notification-panel"), this.animationOptions = { duration: 300, fill: "forwards", easing: "cubic-bezier(0.175, 0.885, 0.32, 1.275)" }, this.push = this.push.bind(this), this.createNotification = this.createNotification.bind(this), this.removeNotification = this.removeNotification.bind(this), this.clearAll = this.clearAll.bind(this), this.remove = this.remove.bind(this), this.handlePointerMove = this.handlePointerMove.bind(this), this.startX = 0, this.currentX = 0, this.endX = 0, this.swipeDistance = 0, this.swipeDirection = "", this.swipeThreshold = 0, this.startTime = 0, this.swipeTime = 0, this.swipeTimeThreshold = 200, this.currentTarget = null, this.mediaQuery = window.matchMedia("(min-width: 640px)"), this.handleOrientationChange = this.handleOrientationChange.bind(this), this.isLandscape = !1 } randString(n) { let t = ""; const i = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; for (let e = 0; e < n; e++)t += i.charAt(Math.floor(Math.random() * i.length)); return t } createNotification(n, t = {}) { const { pinned: i = !1, icon: e = "", action: o } = t, r = document.createElement("div"); r.id = this.randString(8), r.classList.add("notification"); let a = ""; return a += `\n
${e}
\n ${n}\n `, o && (a += `\n \n `), i && (r.classList.add("pinned"), a += '\n \n '), r.innerHTML = a, r } push(n, t = {}) { const i = this.createNotification(n, t); return this.isLandscape ? this.notificationPanel.append(i) : this.notificationPanel.prepend(i), this.notificationPanel.animate([{ transform: `translateY(${this.isLandscape ? "" : "-"}${i.clientHeight}px)` }, { transform: "none" }], this.animationOptions), i.animate([{ transform: "translateY(-1rem)", opacity: "0" }, { transform: "none", opacity: "1" }], this.animationOptions).onfinish = (n => { n.target.commitStyles(), n.target.cancel() }), i.querySelector(".action") && i.querySelector(".action").addEventListener("click", t.action.callback), i.id } removeNotification(n, t = "left") { if (!n) return; const i = "left" === t ? "-" : "+"; n.animate([{ transform: this.currentX ? `translateX(${this.currentX}px)` : "none", opacity: "1" }, { transform: `translateX(calc(${i}${Math.abs(this.currentX)}px ${i} 1rem))`, opacity: "0" }], this.animationOptions).onfinish = (() => { n.remove() }) } remove(n) { const t = this.notificationPanel.querySelector(`#${n}`); t && this.removeNotification(t) } clearAll() { Array.from(this.notificationPanel.children).forEach(n => { this.removeNotification(n) }) } handlePointerMove(n) { this.currentX = n.clientX - this.startX, this.currentTarget.style.transform = `translateX(${this.currentX}px)` } handleOrientationChange(n) { this.isLandscape = n.matches, n.matches } connectedCallback() { this.handleOrientationChange(this.mediaQuery), this.mediaQuery.addEventListener("change", this.handleOrientationChange), this.notificationPanel.addEventListener("pointerdown", n => { n.target.closest(".close") ? this.removeNotification(n.target.closest(".notification")) : n.target.closest(".notification") && (this.swipeThreshold = n.target.closest(".notification").getBoundingClientRect().width / 2, this.currentTarget = n.target.closest(".notification"), this.currentTarget.setPointerCapture(n.pointerId), this.startTime = Date.now(), this.startX = n.clientX, this.startY = n.clientY, this.notificationPanel.addEventListener("pointermove", this.handlePointerMove)) }), this.notificationPanel.addEventListener("pointerup", n => { this.endX = n.clientX, this.endY = n.clientY, this.swipeDistance = Math.abs(this.endX - this.startX), this.swipeTime = Date.now() - this.startTime, this.endX > this.startX ? this.swipeDirection = "right" : this.swipeDirection = "left", this.swipeTime < this.swipeTimeThreshold ? this.swipeDistance > 50 && this.removeNotification(this.currentTarget, this.swipeDirection) : this.swipeDistance > this.swipeThreshold ? this.removeNotification(this.currentTarget, this.swipeDirection) : this.currentTarget.animate([{ transform: `translateX(${this.currentX}px)` }, { transform: "none" }], this.animationOptions).onfinish = (n => { n.target.commitStyles(), n.target.cancel() }), this.notificationPanel.removeEventListener("pointermove", this.handlePointerMove), this.notificationPanel.releasePointerCapture(n.pointerId), this.currentX = 0 }); const n = new MutationObserver(n => { n.forEach(n => { "childList" === n.type && n.addedNodes.length && !n.addedNodes[0].classList.contains("pinned") && setTimeout(() => { this.removeNotification(n.addedNodes[0]) }, 5e3) }) }); n.observe(this.notificationPanel, { childList: !0 }) } disconnectedCallback() { mediaQueryList.removeEventListener("change", handleOrientationChange) } }); +const smSwitch = document.createElement("template"); smSwitch.innerHTML = '\t\n\n', customElements.define("sm-switch", class extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(smSwitch.content.cloneNode(!0)), this.switch = this.shadowRoot.querySelector(".switch"), this.input = this.shadowRoot.querySelector("input"), this.isChecked = !1, this.isDisabled = !1, this.dispatch = this.dispatch.bind(this) } static get observedAttributes() { return ["disabled", "checked"] } get disabled() { return this.isDisabled } set disabled(e) { e ? this.setAttribute("disabled", "") : this.removeAttribute("disabled") } get checked() { return this.isChecked } set checked(e) { e ? this.setAttribute("checked", "") : this.removeAttribute("checked") } get value() { return this.isChecked } reset() { } dispatch() { this.dispatchEvent(new CustomEvent("change", { bubbles: !0, composed: !0, detail: { value: this.isChecked } })) } connectedCallback() { this.addEventListener("keydown", e => { " " !== e.key || this.isDisabled || (e.preventDefault(), this.input.click()) }), this.input.addEventListener("click", e => { this.input.checked ? this.checked = !0 : this.checked = !1, this.dispatch() }) } attributeChangedCallback(e, t, n) { t !== n && ("disabled" === e ? this.hasAttribute("disabled") ? this.disabled = !0 : this.disabled = !1 : "checked" === e && (this.hasAttribute("checked") ? (this.isChecked = !0, this.input.checked = !0) : (this.isChecked = !1, this.input.checked = !1))) } }); +const smSelect = document.createElement("template"); smSelect.innerHTML = '\n\n
\n
\n
\n \n \n
\n \n
', customElements.define("sm-select", class extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(smSelect.content.cloneNode(!0)), this.focusIn = this.focusIn.bind(this), this.reset = this.reset.bind(this), this.open = this.open.bind(this), this.collapse = this.collapse.bind(this), this.toggle = this.toggle.bind(this), this.handleOptionsNavigation = this.handleOptionsNavigation.bind(this), this.handleOptionSelection = this.handleOptionSelection.bind(this), this.handleKeydown = this.handleKeydown.bind(this), this.handleClickOutside = this.handleClickOutside.bind(this), this.selectOption = this.selectOption.bind(this), this.debounce = this.debounce.bind(this), this.availableOptions = [], this.previousOption, this.isOpen = !1, this.label = "", this.defaultSelected = "", this.isUnderViewport = !1, this.animationOptions = { duration: 300, fill: "forwards", easing: "ease" }, this.optionList = this.shadowRoot.querySelector(".options"), this.selection = this.shadowRoot.querySelector(".selection"), this.selectedOptionText = this.shadowRoot.querySelector(".selected-option-text") } static get observedAttributes() { return ["disabled", "label"] } get value() { return this.getAttribute("value") } set value(t) { const e = this.shadowRoot.querySelector("slot").assignedElements().find(e => e.getAttribute("value") === t); e ? (this.setAttribute("value", t), this.selectOption(e)) : console.warn(`There is no option with ${t} as value`) } debounce(t, e) { let n = null; return (...i) => { window.clearTimeout(n), n = window.setTimeout(() => { t.apply(null, i) }, e) } } reset(t = !0) { if (this.availableOptions[0] && this.previousOption !== this.availableOptions[0]) { const e = this.availableOptions.find(t => t.getAttribute("value") === this.defaultSelected) || this.availableOptions[0]; this.value = e.getAttribute("value"), t && this.fireEvent() } } selectOption(t) { this.previousOption !== t && (this.querySelectorAll("[selected]").forEach(t => t.removeAttribute("selected")), this.selectedOptionText.textContent = `${this.label}${t.textContent}`, t.setAttribute("selected", ""), this.previousOption = t) } focusIn() { this.selection.focus() } open() { this.availableOptions.forEach(t => t.setAttribute("tabindex", 0)), this.optionList.classList.remove("hidden"), this.isUnderViewport = this.getBoundingClientRect().bottom + this.optionList.getBoundingClientRect().height > window.innerHeight, this.isUnderViewport ? this.setAttribute("isUnder", "") : this.removeAttribute("isUnder"), this.optionList.animate([{ transform: `translateY(${this.isUnderViewport ? "" : "-"}0.5rem)`, opacity: 0 }, { transform: "translateY(0)", opacity: 1 }], this.animationOptions), this.setAttribute("open", ""), this.style.zIndex = 1e3, (this.availableOptions.find(t => t.hasAttribute("selected")) || this.availableOptions[0]).focus(), document.addEventListener("mousedown", this.handleClickOutside), this.isOpen = !0 } collapse() { this.removeAttribute("open"), this.optionList.animate([{ transform: "translateY(0)", opacity: 1 }, { transform: `translateY(${this.isUnderViewport ? "" : "-"}0.5rem)`, opacity: 0 }], this.animationOptions).onfinish = (() => { this.availableOptions.forEach(t => t.removeAttribute("tabindex")), document.removeEventListener("mousedown", this.handleClickOutside), this.optionList.classList.add("hidden"), this.isOpen = !1, this.style.zIndex = "auto" }) } toggle() { this.isOpen || this.hasAttribute("disabled") ? this.collapse() : this.open() } fireEvent() { this.dispatchEvent(new CustomEvent("change", { bubbles: !0, composed: !0, detail: { value: this.value } })) } handleOptionsNavigation(t) { "ArrowUp" === t.key ? (t.preventDefault(), document.activeElement.previousElementSibling ? document.activeElement.previousElementSibling.focus() : this.availableOptions[this.availableOptions.length - 1].focus()) : "ArrowDown" === t.key && (t.preventDefault(), document.activeElement.nextElementSibling ? document.activeElement.nextElementSibling.focus() : this.availableOptions[0].focus()) } handleOptionSelection(t) { this.previousOption !== document.activeElement && (this.value = document.activeElement.getAttribute("value"), this.fireEvent()) } handleClick(t) { t.target === this ? this.toggle() : (this.handleOptionSelection(), this.collapse()) } handleKeydown(t) { t.target === this ? this.isOpen && "ArrowDown" === t.key ? (t.preventDefault(), (this.availableOptions.find(t => t.hasAttribute("selected")) || this.availableOptions[0]).focus(), this.handleOptionSelection(t)) : " " === t.key && (t.preventDefault(), this.toggle()) : (this.handleOptionsNavigation(t), this.handleOptionSelection(t), ["Enter", " ", "Escape", "Tab"].includes(t.key) && (t.preventDefault(), this.collapse(), this.focusIn())) } handleClickOutside(t) { this.isOpen && !this.contains(t.target) && this.collapse() } connectedCallback() { this.setAttribute("role", "listbox"), this.hasAttribute("disabled") || this.selection.setAttribute("tabindex", "0"); let t = this.shadowRoot.querySelector("slot"); t.addEventListener("slotchange", this.debounce(e => { this.availableOptions = t.assignedElements(), this.reset(!1), this.defaultSelected = this.value }, 100)), new IntersectionObserver((t, e) => { t.forEach(t => { if (t.isIntersecting) { const t = this.selection.getBoundingClientRect().left; t < window.innerWidth / 2 ? this.setAttribute("align-select", "left") : this.setAttribute("align-select", "right") } }) }).observe(this), this.addEventListener("click", this.handleClick), this.addEventListener("keydown", this.handleKeydown) } disconnectedCallback() { this.removeEventListener("click", this.handleClick), this.removeEventListener("click", this.toggle), this.removeEventListener("keydown", this.handleKeydown) } attributeChangedCallback(t) { "disabled" === t ? this.hasAttribute("disabled") ? this.selection.removeAttribute("tabindex") : this.selection.setAttribute("tabindex", "0") : "label" === t && (this.label = this.hasAttribute("label") ? `${this.getAttribute("label")} ` : "") } }); const smOption = document.createElement("template"); smOption.innerHTML = "\n\n
\n \n
", customElements.define("sm-option", class extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(smOption.content.cloneNode(!0)) } connectedCallback() { this.setAttribute("role", "option") } }); +const themeToggle = document.createElement("template"); themeToggle.innerHTML = '\n \n \n'; class ThemeToggle extends HTMLElement { constructor() { super(), this.attachShadow({ mode: "open" }).append(themeToggle.content.cloneNode(!0)), this.isChecked = !1, this.hasTheme = "light", this.toggleState = this.toggleState.bind(this), this.fireEvent = this.fireEvent.bind(this), this.handleThemeChange = this.handleThemeChange.bind(this) } static get observedAttributes() { return ["checked"] } daylight() { this.hasTheme = "light", document.body.dataset.theme = "light", this.setAttribute("aria-checked", "false") } nightlight() { this.hasTheme = "dark", document.body.dataset.theme = "dark", this.setAttribute("aria-checked", "true") } toggleState() { this.toggleAttribute("checked"), this.fireEvent() } handleKeyDown(e) { " " === e.key && this.toggleState() } handleThemeChange(e) { e.detail.theme !== this.hasTheme && ("dark" === e.detail.theme ? this.setAttribute("checked", "") : this.removeAttribute("checked")) } fireEvent() { this.dispatchEvent(new CustomEvent("themechange", { bubbles: !0, composed: !0, detail: { theme: this.hasTheme } })) } connectedCallback() { this.setAttribute("role", "switch"), this.setAttribute("aria-label", "theme toggle"), "dark" === localStorage.getItem(`${window.location.hostname}-theme`) ? (this.nightlight(), this.setAttribute("checked", "")) : "light" === localStorage.getItem(`${window.location.hostname}-theme`) ? (this.daylight(), this.removeAttribute("checked")) : window.matchMedia("(prefers-color-scheme: dark)").matches ? (this.nightlight(), this.setAttribute("checked", "")) : (this.daylight(), this.removeAttribute("checked")), this.addEventListener("click", this.toggleState), this.addEventListener("keydown", this.handleKeyDown), document.addEventListener("themechange", this.handleThemeChange) } disconnectedCallback() { this.removeEventListener("click", this.toggleState), this.removeEventListener("keydown", this.handleKeyDown), document.removeEventListener("themechange", this.handleThemeChange) } attributeChangedCallback(e, t, n) { "checked" === e && (this.hasAttribute("checked") ? (this.nightlight(), localStorage.setItem(`${window.location.hostname}-theme`, "dark")) : (this.daylight(), localStorage.setItem(`${window.location.hostname}-theme`, "light"))) } } window.customElements.define("theme-toggle", ThemeToggle); \ No newline at end of file