├── public ├── card.png ├── cc-jcb.png ├── arrowUp.png ├── cc-amex.png ├── cc-diners.png ├── cc-discover.png ├── cc-invalid.png ├── cc-maestro.png ├── cc-unionpay.png ├── github-logo.png ├── cc-mastercard.png ├── discord-logo.png ├── linkedin-logo.png ├── telegram-logo.png ├── whatsapp-logo.png ├── instagram-logo.png ├── cc-default.svg ├── cc-chip.svg ├── cc-icon.svg └── cc-visa.svg ├── .github └── project.png ├── .gitignore ├── package.json ├── LICENSE ├── src ├── css │ ├── index.scss │ ├── _credit-card.scss │ ├── _swal.scss │ ├── index.css.map │ ├── _form.scss │ ├── _base.scss │ └── index.css └── main.js ├── readme-en.md ├── README.md └── index.html /public/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/card.png -------------------------------------------------------------------------------- /public/cc-jcb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/cc-jcb.png -------------------------------------------------------------------------------- /.github/project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/.github/project.png -------------------------------------------------------------------------------- /public/arrowUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/arrowUp.png -------------------------------------------------------------------------------- /public/cc-amex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/cc-amex.png -------------------------------------------------------------------------------- /public/cc-diners.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/cc-diners.png -------------------------------------------------------------------------------- /public/cc-discover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/cc-discover.png -------------------------------------------------------------------------------- /public/cc-invalid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/cc-invalid.png -------------------------------------------------------------------------------- /public/cc-maestro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/cc-maestro.png -------------------------------------------------------------------------------- /public/cc-unionpay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/cc-unionpay.png -------------------------------------------------------------------------------- /public/github-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/github-logo.png -------------------------------------------------------------------------------- /public/cc-mastercard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/cc-mastercard.png -------------------------------------------------------------------------------- /public/discord-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/discord-logo.png -------------------------------------------------------------------------------- /public/linkedin-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/linkedin-logo.png -------------------------------------------------------------------------------- /public/telegram-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/telegram-logo.png -------------------------------------------------------------------------------- /public/whatsapp-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/whatsapp-logo.png -------------------------------------------------------------------------------- /public/instagram-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Luk4x/gencard/HEAD/public/instagram-logo.png -------------------------------------------------------------------------------- /public/cc-default.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | !.vscode/settings.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GenCard", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "vite": "^3.1.0" 13 | }, 14 | "dependencies": { 15 | "dom-to-image": "^2.6.0", 16 | "imask": "^6.4.3", 17 | "sweetalert": "^2.1.2", 18 | "vanilla-tilt": "^1.7.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /public/cc-chip.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Lucas Maciel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/css/index.scss: -------------------------------------------------------------------------------- 1 | @import 'base'; 2 | @import 'credit-card'; 3 | @import 'form'; 4 | @import 'swal'; 5 | 6 | @media (max-width: 440px) { 7 | :root { 8 | font-size: 50%; 9 | } 10 | 11 | body { 12 | background: linear-gradient(5deg, $neutral-color2 50.5%, $neutral-color1 49.5%); 13 | 14 | #app { 15 | background: none; 16 | border: none; 17 | 18 | .cc-bg svg { 19 | width: 100%; 20 | height: auto; 21 | } 22 | } 23 | } 24 | } 25 | 26 | @media (min-width: 840px) { 27 | body { 28 | padding: 30px; 29 | background: linear-gradient(45deg, $neutral-color1 61.5%, $neutral-color2 39.5%); 30 | 31 | #app { 32 | grid-template-areas: 33 | 'A B' 34 | 'C B'; 35 | width: fit-content; 36 | max-width: fit-content; 37 | padding-inline: 4.8rem; 38 | grid-template-columns: 0.8fr 1fr; 39 | background: linear-gradient(-45deg, $neutral-color1 61.5%, $neutral-color2 39.5%); 40 | 41 | header { 42 | grid-area: A; 43 | } 44 | 45 | section.cc { 46 | grid-area: B; 47 | align-self: center; 48 | } 49 | 50 | form { 51 | grid-area: C; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/css/_credit-card.scss: -------------------------------------------------------------------------------- 1 | .cc { 2 | width: 36.5rem; 3 | height: 24rem; 4 | padding: 2rem; 5 | display: flex; 6 | flex-direction: column; 7 | justify-content: space-between; 8 | z-index: 1; 9 | background: $neutral-color1; 10 | border-radius: 20px; 11 | border: 1px solid #ffffff20; 12 | 13 | .cc-bg { 14 | position: absolute; 15 | inset: 0; 16 | z-index: 1; 17 | } 18 | 19 | .cc-logo { 20 | display: flex; 21 | justify-content: space-between; 22 | align-items: flex-start; 23 | 24 | span:nth-child(2) img { 25 | transition: all 0.8s ease-in-out; 26 | opacity: 0; 27 | max-height: 35px; 28 | transform: translateY(-5px); 29 | } 30 | } 31 | 32 | .cc-info { 33 | display: grid; 34 | gap: 1.4rem; 35 | 36 | .cc-number { 37 | font-size: 2.4rem; 38 | font-weight: bold; 39 | line-height: 2.9rem; 40 | letter-spacing: 0.04em; 41 | color: $text-color; 42 | text-shadow: 0 0.12rem 0.32rem rgb(23 23 23 / 40%); 43 | } 44 | 45 | .cc-holder, 46 | .cc-expiration, 47 | .cc-security { 48 | display: grid; 49 | gap: 0.4rem; 50 | } 51 | 52 | .cc-extra { 53 | display: flex; 54 | justify-content: space-between; 55 | align-items: center; 56 | } 57 | } 58 | 59 | .label { 60 | font-size: 1rem; 61 | line-height: 1.2rem; 62 | } 63 | 64 | .value { 65 | font-size: 1.4rem; 66 | font-weight: bold; 67 | color: $text-color; 68 | text-shadow: 0 0.25rem 0.25rem rgb(22 22 22 / 16%); 69 | text-transform: uppercase; 70 | } 71 | } 72 | 73 | .cc, 74 | .cc-logo, 75 | .cc-number { 76 | position: relative; 77 | z-index: 1; 78 | } 79 | -------------------------------------------------------------------------------- /public/cc-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/cc-visa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/css/_swal.scss: -------------------------------------------------------------------------------- 1 | .swal-overlay { 2 | background-color: #8257e670; 3 | 4 | .swal-modal { 5 | background-color: $neutral-color1; 6 | border: 2px solid $neutral-color2; 7 | 8 | .swal-icon::before, 9 | .swal-icon::after, 10 | .swal-icon--success__hide-corners { 11 | background: $neutral-color1; 12 | } 13 | 14 | .swal-icon--success { 15 | border-color: $secondary-color; 16 | } 17 | 18 | .swal-icon--success__line { 19 | background-color: $secondary-color; 20 | } 21 | 22 | .swal-text { 23 | color: $text-color; 24 | font-size: 17px; 25 | text-align: center; 26 | margin-top: 30px; 27 | display: block; 28 | } 29 | 30 | .swal-title { 31 | text-align: center; 32 | text-transform: capitalize; 33 | font-size: 33px; 34 | color: $dark-primary-color; 35 | border-bottom: 2px solid $secondary-color; 36 | border-radius: 2px; 37 | display: inline; 38 | } 39 | 40 | .swal-content__img { 41 | width: 100%; 42 | max-width: 288px; 43 | } 44 | 45 | .swal-button-container { 46 | border-radius: 6px; 47 | overflow: hidden; 48 | 49 | .swal-button.swal-button--confirm { 50 | display: flex; 51 | justify-content: center; 52 | align-items: center; 53 | flex-direction: column; 54 | color: $text-color; 55 | background: $primary-color; 56 | width: 110px; 57 | height: 45px; 58 | border: 2px solid $secondary-color; 59 | transition: 0.2s all ease-in-out; 60 | 61 | &:hover { 62 | background: $dark-primary-color; 63 | 64 | &::before { 65 | top: 10px; 66 | } 67 | 68 | &::after { 69 | bottom: -40px; 70 | } 71 | } 72 | 73 | &::before { 74 | content: url('https://user-images.githubusercontent.com/86276393/203387682-dee65164-c138-49c4-b39c-8547aafa0140.png'); 75 | position: absolute; 76 | top: -40px; 77 | transition: all 0.4s ease-in-out; 78 | } 79 | 80 | &::after { 81 | content: 'Download'; 82 | position: absolute; 83 | bottom: 14px; 84 | transition: all 0.4s ease-in-out; 85 | } 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/css/index.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["_base.scss","_credit-card.scss","_form.scss","_swal.scss","index.scss"],"names":[],"mappings":"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","file":"index.css"} -------------------------------------------------------------------------------- /readme-en.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 11 | 12 |
4 | 🇺🇸 English 5 |
9 | 🇧🇷 Português 10 |
13 | 14 | ![luk4x-repo-status](https://img.shields.io/badge/Status-Finished-lightgrey?style=for-the-badge&logo=headspace&logoColor=green&color=lightgrey) 15 | ![luk4x-repo-license](https://img.shields.io/github/license/Luk4x/gencard?style=for-the-badge&logo=unlicense&logoColor=lightgrey) 16 | # 💳 GenCard Project 17 | 18 |
19 |

20 | Video   |    21 | Technologies   |    22 | About   |    23 | Highlights   |    24 | Cloning   |    25 | Contact 26 |

27 |
28 | 29 | ## 📹 Project Video Presentation 30 |
31 |
33 | 34 | > **If the video has any errors, reload the page!**
35 | > Access the project online **[HERE](https://luk4x-gencard.netlify.app/)** 36 | 37 | ## 🚀 Technologies Used 38 | 39 | - [SweetAlert](https://sweetalert.js.org/guides/) 40 | - [Vanilla-Tilt](https://micku7zu.github.io/vanilla-tilt.js/) 41 | - [Dom-To-Image](https://github.com/tsayen/dom-to-image) 42 | - [Sass](https://sass-lang.com/) 43 | - [iMask](https://imask.js.org) 44 | - [UI Ball Loaders](https://uiball.com/) 45 | - [CSS Buttons](https://uiverse.io/) 46 | - [Regex](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) 47 | - [ViteJS](https://vitejs.dev/) 48 | - [NodeJS](https://nodejs.org) 49 | - [npm](https://www.npmjs.com/) 50 | - [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) 51 | - [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS) 52 | - [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) 53 | 54 | ## 📝 About 55 | 56 | > Watching the video above and/or accessing the project online will help you understand the explanation! 57 | 58 | Inspired by [RocketPay](https://www.figma.com/file/gpqavL469k0pPUGOmAQEM9/Explorer-Lab-%2301/duplicate), GenCard simulates a credit card filling form, where the focus was to practice handling HTML elements via DOM and use the `IMask` to validate the information.
59 | Since I already had this knowledge, I took the opportunity to give room to my ideas and explore more about Regex and Sass, thus developing several modifications and improvements, such as the creation of extra validations, the development of a more elaborate and performative CSS, among others. mentioned in the highlights section. 60 | 61 | ### 📌 Some Highlights 62 | 63 | - Extra validations; 64 | - More card possibilities; 65 | - Improved layout, user experience and animations with the use of `Sass`, the `Vanilla-Tilt` lib, and Loaders and Buttons components.; 66 | - Option to generate and download the card image using the `Dom-To-Image` - functionality that may not make much sense in this context, but even so I wanted to put into practice this idea that came to mind; 67 | - User feedback modal with user information using `SweetAlert`; 68 | - Fully responsive design; 69 | 70 | ## 📖 Cloning the Project 71 | 72 | To clone and run this project on your computer you will need [Git](https://git-scm.com/) and [Node.js v16.13.2](https://nodejs.org/en/) or higher and previously installed.
73 | After that, in the terminal: 74 | 75 | ```bash 76 | # Clone this repository with: 77 | > git clone https://github.com/Luk4x/gencard.git 78 | 79 | # Enter the repository with: 80 | > cd gencard 81 | 82 | # Install dependencies with: 83 | > npm install 84 | 85 | # Run the project with: 86 | > npm run dev 87 | 88 | # Once this is done, you will be able to access the project through the link that will appear in the terminal! (something like http://localhost:3000/ or http://127.0.0.1:5173/) 89 | ``` 90 | 91 | ## 🤝 Contributor Contact 92 | 93 | 94 | 95 | 124 | 142 | 143 |
96 |
97 | 98 | Vitrine.Dev 🪟 99 | 100 | 101 | 112 | 113 |
102 | 103 | Luk4x Github Photo 104 | 105 |
106 | 107 | 108 | Lucas Maciel 109 | 110 | 111 |
114 |
115 | 116 | | :placard: Vitrine.Dev | Lucas Maciel | 117 | | ------------- | --- | 118 | | :sparkles: Nome | **💳 GenCard** 119 | | :label: Tecnologias | sass, regex, imask, sweetalert, nodejs, npm, css-buttons, dom-to-image, vitejs, vanilla-tilt, ui-ball-loaders, javascript, css, html 120 | | :camera: Img | vitrine.dev thumb 121 | 122 |
123 |
125 | MaykBrito.Dev 🪟 126 | 127 | 128 | 139 | 140 |
129 | 130 | Luk4x Github Photo 131 | 132 |
133 | 134 | 135 | Mayk Brito 136 | 137 | 138 |
141 |
144 | 145 |

146 | Back to Top 147 |

148 | -------------------------------------------------------------------------------- /src/css/_form.scss: -------------------------------------------------------------------------------- 1 | form { 2 | max-width: 36rem; 3 | display: grid; 4 | gap: 1.6rem; 5 | 6 | .input-wrapper { 7 | display: grid; 8 | gap: 0.6rem; 9 | } 10 | 11 | label { 12 | font-weight: 600; 13 | font-size: 1.2rem; 14 | line-height: 1.5rem; 15 | letter-spacing: 0.01px; 16 | text-transform: uppercase; 17 | color: $text-color; 18 | } 19 | 20 | input { 21 | background: $neutral-color3; 22 | border: 2px solid $neutral-color2; 23 | border-radius: 6px; 24 | height: 41px; 25 | padding-inline: 1.2rem; 26 | width: 100%; 27 | color: $text-color; 28 | text-transform: uppercase; 29 | transition: all 0.5s ease-in-out; 30 | } 31 | 32 | .flex { 33 | gap: 1.4rem; 34 | 35 | .input-wrapper { 36 | flex: 1; 37 | } 38 | } 39 | 40 | /* From uiverse.io by @menezes11. Converted to Sass and edited by @Luk4x (Github) */ 41 | button { 42 | position: relative; 43 | padding: 1.6rem 1.8rem; 44 | color: $primary-color; 45 | text-transform: uppercase; 46 | letter-spacing: 2px; 47 | overflow: hidden; 48 | transition: 0.2s; 49 | border-radius: 0.5em; 50 | margin-top: 1.6rem; 51 | display: flex; 52 | justify-content: center; 53 | align-items: center; 54 | font-weight: 700; 55 | font-size: 1.4rem; 56 | line-height: 1.7rem; 57 | cursor: not-allowed; 58 | opacity: 0.65; 59 | background: #201214; 60 | height: 49px; 61 | 62 | span { 63 | position: absolute; 64 | 65 | @for $i from 1 through 4 { 66 | &:nth-child(#{$i}) { 67 | @if ($i == 1) { 68 | top: 0; 69 | left: -100%; 70 | width: 100%; 71 | height: 2px; 72 | background: linear-gradient(90deg, transparent, $primary-color); 73 | } @else if ($i == 2) { 74 | top: -100%; 75 | right: 0; 76 | width: 2px; 77 | height: 100%; 78 | background: linear-gradient(180deg, transparent, $primary-color); 79 | } @else if ($i == 3) { 80 | bottom: 0; 81 | right: -100%; 82 | width: 100%; 83 | height: 2px; 84 | background: linear-gradient(90deg, transparent, $secondary-color); 85 | } @else { 86 | bottom: -100%; 87 | left: 0; 88 | width: 2px; 89 | height: 100%; 90 | background: linear-gradient(360deg, transparent, $secondary-color); 91 | } 92 | } 93 | } 94 | } 95 | 96 | &:active { 97 | @for $i from 1 through 4 { 98 | span:nth-child(#{$i}) { 99 | transition: none; 100 | transition-delay: none; 101 | } 102 | } 103 | } 104 | } 105 | 106 | .activeButton { 107 | cursor: pointer; 108 | opacity: 1; 109 | background: $neutral-color3; 110 | 111 | &:hover { 112 | @for $i from 1 through 4 { 113 | span:nth-child(#{$i}) { 114 | @if ($i == 1) { 115 | left: 100%; 116 | transition: 0.7s; 117 | } @else if ($i == 2) { 118 | top: 100%; 119 | transition: 0.7s; 120 | transition-delay: 0.17s; 121 | } @else if ($i == 3) { 122 | right: 100%; 123 | transition: 0.7s; 124 | transition-delay: 0.35s; 125 | } @else { 126 | bottom: 100%; 127 | transition: 0.7s; 128 | transition-delay: 0.52s; 129 | } 130 | } 131 | } 132 | } 133 | 134 | &:active { 135 | background: $dark-primary-color; 136 | background: linear-gradient(to top right, $dark-primary-color 28%, $secondary-color); 137 | color: $text-color; 138 | box-shadow: 0 0 8px $primary-color, 0 0 8px $secondary-color, 0 0 8px $primary-color; 139 | transition: 0.1s; 140 | transition-delay: none; 141 | } 142 | } 143 | 144 | .hideButtonElement { 145 | display: none !important; 146 | } 147 | } 148 | 149 | .waveform { 150 | $uib-size: 25px; 151 | $uib-speed: 1s; 152 | $uib-color: $primary-color; 153 | $uib-line-weight: 3.5px; 154 | 155 | display: flex; 156 | flex-flow: row nowrap; 157 | align-items: center; 158 | justify-content: space-between; 159 | width: $uib-size; 160 | height: calc($uib-size * 0.9); 161 | 162 | .waveform__bar { 163 | width: $uib-line-weight; 164 | height: 100%; 165 | background-color: $uib-color; 166 | 167 | @for $i from 1 through 4 { 168 | &:nth-child(#{$i}) { 169 | @if ($i == 1) { 170 | animation: grow $uib-speed ease-in-out calc($uib-speed * -0.45) infinite; 171 | } @else if ($i == 2) { 172 | animation: grow $uib-speed ease-in-out calc($uib-speed * -0.3) infinite; 173 | } @else if ($i == 3) { 174 | animation: grow $uib-speed ease-in-out calc($uib-speed * -0.15) infinite; 175 | } @else { 176 | animation: grow $uib-speed ease-in-out infinite; 177 | } 178 | } 179 | } 180 | 181 | @keyframes grow { 182 | 0%, 183 | 100% { 184 | transform: scaleY(0.3); 185 | } 186 | 187 | 50% { 188 | transform: scaleY(1); 189 | } 190 | } 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 11 | 12 |
4 | 🇺🇸 English 5 |
9 | 🇧🇷 Português 10 |
13 | 14 | ![luk4x-repo-status](https://img.shields.io/badge/Status-Finished-lightgrey?style=for-the-badge&logo=headspace&logoColor=green&color=lightgrey) 15 | ![luk4x-repo-license](https://img.shields.io/github/license/Luk4x/gencard?style=for-the-badge&logo=unlicense&logoColor=lightgrey) 16 | # 💳 GenCard Project 17 | 18 |
19 |

20 | Vídeo   |    21 | Tecnologias   |    22 | Sobre   |    23 | Destaques   |    24 | Clone   |    25 | Contato 26 |

27 |
28 | 29 | ## 📹 Apresentação em Vídeo do Projeto 30 |
31 |
33 | 34 | > **Caso o vídeo apresente algum erro, recarregue a página!**
35 | > Acesse o projeto online **[AQUI](https://luk4x-gencard.netlify.app/)** 36 | 37 | ## 🚀 Tecnologias Utilizadas 38 | 39 | - [SweetAlert](https://sweetalert.js.org/guides/) 40 | - [Vanilla-Tilt](https://micku7zu.github.io/vanilla-tilt.js/) 41 | - [Dom-To-Image](https://github.com/tsayen/dom-to-image) 42 | - [Sass](https://sass-lang.com/) 43 | - [iMask](https://imask.js.org) 44 | - [UI Ball Loaders](https://uiball.com/) 45 | - [CSS Buttons](https://uiverse.io/) 46 | - [Regex](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions) 47 | - [ViteJS](https://vitejs.dev/) 48 | - [NodeJS](https://nodejs.org) 49 | - [npm](https://www.npmjs.com/) 50 | - [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) 51 | - [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS) 52 | - [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML) 53 | 54 | ## 📝 Sobre 55 | 56 | > Assistir o vídeo acima e/ou acessar o projeto online ajudará na compreensão da explicação! 57 | 58 | Inspirado no [RocketPay](https://www.figma.com/file/gpqavL469k0pPUGOmAQEM9/Explorer-Lab-%2301/duplicate), o GenCard simula um formulário de preenchimento de cartão de crédito, onde o foco foi praticar a manipulação de elementos HTML via DOM e utilizar o `IMask` para a validação das informações.
59 | Visto que já tinha esses conhecimentos, aproveitei a oportunidade para dar margem às minhas ideias e explorar mais sobre Regex e Sass, assim desenvolvendo diversas modificações e melhorias, como a criação de validações extras, o desenvolvimento de um CSS mais rebuscado e performático, entre outras citadas na sessão de destaques.
60 | 61 | ### 📌 Alguns Destaques 62 | 63 | - Validações extras; 64 | - Mais possibilidades de cartões; 65 | - Layout, experiência do usuário e animações melhoradas com o uso de `Sass`, da lib `Vanilla-Tilt`, e componentes de Loaders e Buttons.; 66 | - Opção de gerar e baixar a imagem do cartão utilizando o `Dom-To-Image` - funcionalidade essa que pode não ter muito sentido nesse contexto, mas mesmo assim quis pôr em prática essa ideia que me veio a mente; 67 | - Modal de feedback para o usuário com informações do mesmo utilizando o `SweetAlert`; 68 | - Projeto totalmente responsivo; 69 | 70 | ## 📖 Clonando o Projeto 71 | 72 | Para clonar e executar este projeto em seu computador, você precisará do [Git](https://git-scm.com/) e [Node.js v16.13.2](https://nodejs.org/en/) ou superior previamente instalados.
73 | Feito isso, no terminal: 74 | 75 | ```bash 76 | # Clone esse repositório com: 77 | > git clone https://github.com/Luk4x/gencard.git 78 | 79 | # Entre no repositório com: 80 | > cd gencard 81 | 82 | # Instale as dependências com: 83 | > npm install 84 | 85 | # Execute o projeto com: 86 | > npm run dev 87 | 88 | # Feito isso, você já poderá acessar o projeto pelo link que aparecerá no terminal! (algo como http://localhost:3000/ ou http://127.0.0.1:5173/) 89 | ``` 90 | 91 | ## 🤝 Contato dos Contribuintes 92 | 93 | 94 | 95 | 124 | 142 | 143 |
96 |
97 | 98 | Vitrine.Dev 🪟 99 | 100 | 101 | 112 | 113 |
102 | 103 | Luk4x Github Photo 104 | 105 |
106 | 107 | 108 | Lucas Maciel 109 | 110 | 111 |
114 |
115 | 116 | | :placard: Vitrine.Dev | Lucas Maciel | 117 | | ------------- | --- | 118 | | :sparkles: Nome | **💳 GenCard** 119 | | :label: Tecnologias | sass, regex, imask, sweetalert, nodejs, npm, css-buttons, dom-to-image, vitejs, vanilla-tilt, ui-ball-loaders, javascript, css, html 120 | | :camera: Img | vitrine.dev thumb 121 | 122 |
123 |
125 | MaykBrito.Dev 🪟 126 | 127 | 128 | 139 | 140 |
129 | 130 | Luk4x Github Photo 131 | 132 |
133 | 134 | 135 | Mayk Brito 136 | 137 | 138 |
141 |
144 | 145 |

146 | Voltar ao Topo 147 |

148 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import './css/index.css'; 2 | import IMask from 'imask'; 3 | import swal from 'sweetalert'; 4 | import domtoimage from 'dom-to-image'; 5 | import VanillaTilt from 'vanilla-tilt'; 6 | 7 | // card hover effect 8 | const card = document.querySelector('.cc'); 9 | VanillaTilt.init(card, { 10 | max: 20, 11 | speed: 350, 12 | glare: true 13 | }); 14 | 15 | // Personalizing card 16 | const cardBgColor1 = document.querySelector('.cc-bg svg > g g:nth-child(1) path'); 17 | const cardBgColor2 = document.querySelector('.cc-bg svg > g g:nth-child(2) path'); 18 | const cardLogo = document.querySelector('.cc-logo span:nth-child(2) img'); 19 | 20 | const setCardType = (type, ext) => { 21 | const colors = { 22 | visa: ['#436d99', '#2d57f2'], 23 | mastercard: ['#FC3551', '#c69347'], 24 | maestro: ['#1248FF', '#FC3551'], 25 | discover: ['#F73A67', '#FFC632'], 26 | jcb: ['#2BB01F', '#FE304A'], 27 | unionpay: ['#3BC3EE', '#292D98'], 28 | amex: ['#1238FF', '#E1E1E1'], 29 | diners: ['#8EB5FF', '#0025CE'], 30 | invalid: ['#633bbc', '#601111'], 31 | default: ['#323238', '#323238'] 32 | }; 33 | 34 | cardBgColor1.setAttribute('fill', colors[type][0]); 35 | cardBgColor2.setAttribute('fill', colors[type][1]); 36 | 37 | cardLogo.setAttribute('src', `cc-${type}.${ext ?? 'svg'}`); 38 | const typeCheck = type && type !== 'default'; 39 | cardLogo.style.opacity = typeCheck ? '1' : '0'; 40 | cardLogo.style.transform = typeCheck ? 'translateY(0)' : 'translateY(-5px)'; 41 | }; 42 | globalThis.setCardType = setCardType; 43 | 44 | // Creating masks 45 | const cardNumber = document.getElementById('card-number'); 46 | const cardNumberPattern = { 47 | mask: [ 48 | { 49 | mask: '0000 0000 0000 0000', 50 | regex: /^4\d{0,15}/, 51 | cardType: 'visa' 52 | }, 53 | { 54 | mask: '0000 0000 0000 0000', 55 | regex: /^(5[1-5]\d{0,2}|22[2-9]\d{0,1}|2[3-7]\d{0,2})\d{0,12}/, 56 | cardType: 'mastercard', 57 | ext: 'png' 58 | }, 59 | { 60 | mask: '0000 0000 0000 0000', 61 | regex: /^(?:6011|65\d{0,2}|64[4-9]\d?)\d{0,12}/, 62 | cardType: 'discover', 63 | ext: 'png' 64 | }, 65 | { 66 | mask: '0000 0000 0000 0000', 67 | regex: /^(?:35\d{0,2})\d{0,12}/, 68 | cardType: 'jcb', 69 | ext: 'png' 70 | }, 71 | { 72 | mask: '0000 0000 0000 0000', 73 | regex: /^(?:5[0678]\d{0,2}|6304|67\d{0,2})\d{0,12}/, 74 | cardType: 'maestro', 75 | ext: 'png' 76 | }, 77 | { 78 | mask: '0000 0000 0000 0000', 79 | regex: /^62\d{0,14}/, 80 | cardType: 'unionpay', 81 | ext: 'png' 82 | }, 83 | { 84 | mask: '0000 000000 00000', 85 | regex: /^3[47]\d{0,13}/, 86 | cardType: 'amex', 87 | ext: 'png' 88 | }, 89 | { 90 | mask: '0000 000000 0000', 91 | regex: /^3(?:0([0-5]|9)|[689]\d?)\d{0,11}/, 92 | cardType: 'diners', 93 | ext: 'png' 94 | }, 95 | { 96 | mask: '0000 0000 0000 0000', 97 | cardType: 'default' 98 | } 99 | ], 100 | dispatch: (appended, dynamicMasked) => { 101 | const number = (dynamicMasked.value + appended).replace(/\D/g, ''); 102 | 103 | return dynamicMasked.compiledMasks.find(({ regex }) => number.match(regex)); 104 | } 105 | }; 106 | const cardNumberMasked = IMask(cardNumber, cardNumberPattern); 107 | 108 | const expirationDate = document.getElementById('expiration-date'); 109 | const expirationDatePattern = { 110 | mask: 'MM{/}YY', 111 | blocks: { 112 | MM: { 113 | mask: IMask.MaskedRange, 114 | from: 1, 115 | to: 12 116 | }, 117 | YY: { 118 | mask: IMask.MaskedRange, 119 | from: parseInt(String(new Date().getFullYear()).slice(2)), 120 | to: parseInt(String(new Date().getFullYear()).slice(2)) + 10 121 | } 122 | } 123 | }; 124 | const expirationDateMasked = IMask(expirationDate, expirationDatePattern); 125 | 126 | const securityCode = document.getElementById('security-code'); 127 | const securityCodeMasked = IMask(securityCode, { 128 | mask: '000' 129 | }); 130 | 131 | // Changing card 132 | const cardShowNumber = document.querySelector('.cc-number'); 133 | cardNumberMasked.on('accept', () => { 134 | cardShowNumber.innerText = 135 | cardNumberMasked.value.length > 0 ? cardNumberMasked.value : '#### #### #### ####'; 136 | setCardType( 137 | cardNumberMasked.masked.currentMask.cardType, 138 | cardNumberMasked.masked.currentMask.ext 139 | ); 140 | 141 | if (cardNumberMasked.masked.currentMask.cardType === 'amex') { 142 | cardNumber.style.borderColor = cardNumberMasked.value.length === 17 ? '#633bbc' : '#323238'; 143 | } else if (cardNumberMasked.masked.currentMask.cardType === 'diners') { 144 | cardNumber.style.borderColor = cardNumberMasked.value.length === 16 ? '#633bbc' : '#323238'; 145 | } else { 146 | if (cardNumberMasked.value.length === 19) { 147 | if ( 148 | cardNumberMasked.masked.currentMask.cardType && 149 | cardNumberMasked.masked.currentMask.cardType !== 'default' 150 | ) { 151 | cardNumber.style.borderColor = '#633bbc'; 152 | } else { 153 | cardNumber.style.borderColor = '#601111'; 154 | setCardType('invalid', 'png'); 155 | cardShowNumber.innerText = 'Número Inválido'; 156 | } 157 | } else { 158 | cardNumber.style.borderColor = '#323238'; 159 | } 160 | } 161 | }); 162 | 163 | const cardName = document.getElementById('card-holder'); 164 | const cardShowName = document.querySelector('.cc-holder .value'); 165 | cardName.addEventListener('input', () => { 166 | cardName.value = cardName.value.replace(/[0-9]/g, ''); 167 | cardShowName.innerText = cardName.value.length > 0 ? cardName.value : 'Nome Completo'; 168 | cardName.style.borderColor = cardName.value.match(/[a-zA-Z] [a-zA-Z]/) ? '#633bbc' : '#323238'; 169 | }); 170 | 171 | const cardShowExpirationDate = document.querySelector('.cc-extra .value'); 172 | expirationDateMasked.on('accept', () => { 173 | cardShowExpirationDate.innerText = 174 | expirationDateMasked.value.length > 0 ? expirationDateMasked.value : '##/##'; 175 | expirationDate.style.borderColor = 176 | expirationDateMasked.value.length === 5 ? '#633bbc' : '#323238'; 177 | }); 178 | 179 | const cardShowSecurityCode = document.querySelector('.cc-security .value'); 180 | securityCodeMasked.on('accept', () => { 181 | cardShowSecurityCode.innerText = 182 | securityCodeMasked.value.length > 0 ? securityCodeMasked.value : '###'; 183 | securityCode.style.borderColor = securityCodeMasked.value.length === 3 ? '#633bbc' : '#323238'; 184 | }); 185 | 186 | // form functionality 187 | const inputs = [securityCode, cardName, expirationDate, cardNumber]; 188 | const button = document.getElementById('submitButton'); 189 | const buttonText = document.querySelector('#submitButton p'); 190 | const buttonLoader = document.querySelector('.waveform'); 191 | const buttonImg = document.querySelector('#submitButton img'); 192 | 193 | inputs.forEach(input => { 194 | // on a input in each input, verify if the color of the actual input and others if green (that is, if it is duly filled) and if all inputs are duly filled, unlock button submit 195 | input.addEventListener('input', () => { 196 | const enableButton = inputs.reduce((enable, input) => { 197 | return enable && input.style.borderColor === 'rgb(99, 59, 188)'; 198 | }, true); 199 | 200 | const isInputEmpty = inputs.reduce((isEmpty, input) => { 201 | return isEmpty && input.value.length === 0; 202 | }, true); 203 | 204 | if (enableButton) { 205 | button.classList.add('activeButton'); 206 | button.disabled = false; 207 | 208 | buttonText.classList.remove('hideButtonElement'); 209 | buttonLoader.classList.add('hideButtonElement'); 210 | } else { 211 | if (isInputEmpty) { 212 | buttonLoader.classList.add('hideButtonElement'); 213 | buttonImg.classList.remove('hideButtonElement'); 214 | } else { 215 | buttonLoader.classList.remove('hideButtonElement'); 216 | buttonImg.classList.add('hideButtonElement'); 217 | } 218 | 219 | button.classList.remove('activeButton'); 220 | button.disabled = true; 221 | buttonText.classList.add('hideButtonElement'); 222 | } 223 | }); 224 | }); 225 | 226 | const form = document.querySelector('form'); 227 | form.addEventListener('submit', e => { 228 | e.preventDefault(); 229 | 230 | const formLoader = document.querySelector('.orbit'); 231 | const app = document.getElementById('app'); 232 | 233 | formLoader.classList.add('showOrbit'); 234 | app.classList.add('appLoadingState'); 235 | 236 | setTimeout(async () => { 237 | let userFirstName = ''; 238 | for (let letter of cardName.value) { 239 | if (letter === ' ') break; 240 | else userFirstName += letter; 241 | } 242 | 243 | // generating card image url 244 | const cardUrl = await domtoimage.toPng(card); 245 | 246 | // resetting fields 247 | inputs.forEach(input => { 248 | input.value = ''; 249 | input.style.borderColor = '#323238'; 250 | }); 251 | 252 | cardShowName.innerText = 'NOME COMPLETO'; 253 | cardShowSecurityCode.innerText = '###'; 254 | cardShowNumber.innerText = '#### #### #### ####'; 255 | cardShowExpirationDate.innerText = '##/##'; 256 | setCardType('default'); 257 | 258 | buttonText.classList.add('hideButtonElement'); 259 | buttonImg.classList.remove('hideButtonElement'); 260 | button.classList.remove('activeButton'); 261 | button.disabled = true; 262 | 263 | formLoader.classList.remove('showOrbit'); 264 | app.classList.remove('appLoadingState'); 265 | 266 | swal({ 267 | title: `Hey ${userFirstName.toLowerCase()}!`, 268 | text: 'Seu cartão foi gerado com sucesso!', 269 | icon: 'success', 270 | content: { 271 | element: 'img', 272 | attributes: { 273 | src: cardUrl, 274 | alt: `${userFirstName.toUpperCase()} GC Card image` 275 | } 276 | }, 277 | button: '' 278 | }) 279 | .then(download => { 280 | // generating card download link 281 | if (download) { 282 | const cardImgLink = document.createElement('a'); 283 | cardImgLink.download = `${userFirstName.toUpperCase()}-GC-Card.png`; 284 | cardImgLink.href = cardUrl; 285 | cardImgLink.click(); 286 | } 287 | }) 288 | .catch(error => console.error(error)); 289 | }, 1400); 290 | }); 291 | 292 | // cleaning inputs on load 293 | window.onload = () => { 294 | cardName.value = ''; 295 | securityCode.value = ''; 296 | cardNumber.value = ''; 297 | expirationDate.value = ''; 298 | }; 299 | -------------------------------------------------------------------------------- /src/css/_base.scss: -------------------------------------------------------------------------------- 1 | $primary-color: #8257e6; 2 | $dark-primary-color: #633bbc; 3 | $secondary-color: #42d3ff; 4 | $neutral-color1: #202024; 5 | $neutral-color2: #323238; 6 | $neutral-color3: #121214; 7 | $text-color: #e1e1e6; 8 | 9 | * { 10 | margin: 0; 11 | padding: 0; 12 | box-sizing: border-box; 13 | border: none; 14 | outline: none; 15 | text-decoration: none; 16 | list-style-type: none; 17 | font-family: Inter, sans-serif; 18 | } 19 | 20 | :root { 21 | font-size: 62.5%; 22 | color: #ffffffde; 23 | font-synthesis: none; 24 | text-rendering: optimizeLegibility; 25 | -webkit-font-smoothing: antialiased; 26 | -moz-osx-font-smoothing: grayscale; 27 | -webkit-text-size-adjust: 100%; 28 | } 29 | 30 | body { 31 | font-size: 1.6rem; 32 | background: linear-gradient(-5deg, $neutral-color1 51%, $neutral-color2 49%); 33 | display: flex; 34 | place-items: center; 35 | min-height: 100vh; 36 | 37 | .flex { 38 | display: flex; 39 | } 40 | 41 | #app { 42 | display: grid; 43 | justify-content: center; 44 | gap: 3.2rem; 45 | width: 100%; 46 | max-width: 42rem; 47 | margin: 0 auto; 48 | padding: 2.8rem 6rem 4rem; 49 | background: $neutral-color1; 50 | border: 2px solid $neutral-color2; 51 | border-radius: 0.6rem; 52 | position: relative; 53 | z-index: 1; 54 | background: linear-gradient(5deg, $neutral-color2 51%, $neutral-color1 49%); 55 | transition: all 0.35s ease-in-out; 56 | 57 | header { 58 | display: flex; 59 | align-items: center; 60 | border-bottom: 2px solid $dark-primary-color; 61 | width: 148px; 62 | 63 | h1 { 64 | font-size: 24.5px; 65 | margin-left: 8px; 66 | color: $text-color; 67 | font-weight: 300; 68 | } 69 | 70 | span { 71 | font-weight: 400; 72 | color: #6a6a6c; 73 | } 74 | } 75 | } 76 | 77 | .appLoadingState { 78 | filter: brightness(65%) blur(3px) opacity(0.95); 79 | } 80 | 81 | .links { 82 | position: absolute; 83 | bottom: 40px; 84 | left: 50%; 85 | transform: translateX(-50%); 86 | border-bottom: 8px solid $dark-primary-color; 87 | border-radius: 20px; 88 | padding: 0 5px; 89 | 90 | .links-list { 91 | display: flex; 92 | list-style-type: none; 93 | gap: 8px; 94 | 95 | li a img, 96 | button { 97 | background: none; 98 | cursor: pointer; 99 | opacity: 0.7; 100 | transition: all 0.2s ease-in-out; 101 | 102 | &:hover { 103 | opacity: 1; 104 | transform: scale(0.9); 105 | } 106 | } 107 | 108 | button:hover::after { 109 | content: attr(data-tooltip); 110 | position: absolute; 111 | width: 80px; 112 | height: 40px; 113 | background: $secondary-color; 114 | color: $neutral-color3; 115 | font-size: 14.5px; 116 | border-radius: 5px; 117 | border-bottom-left-radius: 50%; 118 | border-bottom-right-radius: 50%; 119 | bottom: 45px; 120 | left: calc(50% - 80px / 2); 121 | line-height: 32px; 122 | transition: all 1s ease-in-out; 123 | } 124 | } 125 | } 126 | 127 | .orbit { 128 | $uib-size: 80px; 129 | $uib-speed: 1.5s; 130 | position: absolute; 131 | display: flex; 132 | align-items: center; 133 | justify-content: center; 134 | height: $uib-size; 135 | width: $uib-size; 136 | top: 45%; 137 | right: 45%; 138 | transform: translate(-50%); 139 | opacity: 0; 140 | 141 | &::before, 142 | &::after { 143 | content: ''; 144 | position: absolute; 145 | height: 60%; 146 | width: 60%; 147 | border-radius: 50%; 148 | will-change: transform; 149 | flex-shrink: 0; 150 | } 151 | 152 | &::before { 153 | background-color: $primary-color; 154 | animation: orbit $uib-speed linear infinite; 155 | } 156 | 157 | &::after { 158 | background-color: $secondary-color; 159 | animation: orbit $uib-speed linear calc($uib-speed / -2) infinite; 160 | } 161 | 162 | @keyframes orbit { 163 | 0% { 164 | transform: translate(calc($uib-size * 0.5)) scale(0.73684); 165 | opacity: 0.65; 166 | } 167 | 5% { 168 | transform: translate(calc($uib-size * 0.4)) scale(0.684208); 169 | opacity: 0.58; 170 | } 171 | 10% { 172 | transform: translate(calc($uib-size * 0.3)) scale(0.631576); 173 | opacity: 0.51; 174 | } 175 | 15% { 176 | transform: translate(calc($uib-size * 0.2)) scale(0.578944); 177 | opacity: 0.44; 178 | } 179 | 20% { 180 | transform: translate(calc($uib-size * 0.1)) scale(0.526312); 181 | opacity: 0.37; 182 | } 183 | 25% { 184 | transform: translate(0%) scale(0.47368); 185 | opacity: 0.3; 186 | } 187 | 30% { 188 | transform: translate(calc($uib-size * -0.1)) scale(0.526312); 189 | opacity: 0.37; 190 | } 191 | 35% { 192 | transform: translate(calc($uib-size * -0.2)) scale(0.578944); 193 | opacity: 0.44; 194 | } 195 | 40% { 196 | transform: translate(calc($uib-size * -0.3)) scale(0.631576); 197 | opacity: 0.51; 198 | } 199 | 45% { 200 | transform: translate(calc($uib-size * -0.4)) scale(0.684208); 201 | opacity: 0.58; 202 | } 203 | 50% { 204 | transform: translate(calc($uib-size * -0.5)) scale(0.73684); 205 | opacity: 0.65; 206 | } 207 | 55% { 208 | transform: translate(calc($uib-size * -0.4)) scale(0.789472); 209 | opacity: 0.72; 210 | } 211 | 60% { 212 | transform: translate(calc($uib-size * -0.3)) scale(0.842104); 213 | opacity: 0.79; 214 | } 215 | 65% { 216 | transform: translate(calc($uib-size * -0.2)) scale(0.894736); 217 | opacity: 0.86; 218 | } 219 | 70% { 220 | transform: translate(calc($uib-size * -0.1)) scale(0.947368); 221 | opacity: 0.93; 222 | } 223 | 75% { 224 | transform: translate(0%) scale(1); 225 | opacity: 1; 226 | } 227 | 80% { 228 | transform: translate(calc($uib-size * 0.1)) scale(0.947368); 229 | opacity: 0.93; 230 | } 231 | 85% { 232 | transform: translate(calc($uib-size * 0.2)) scale(0.894736); 233 | opacity: 0.86; 234 | } 235 | 90% { 236 | transform: translate(calc($uib-size * 0.3)) scale(0.842104); 237 | opacity: 0.79; 238 | } 239 | 95% { 240 | transform: translate(calc($uib-size * 0.4)) scale(0.789472); 241 | opacity: 0.72; 242 | } 243 | 100% { 244 | transform: translate(calc($uib-size * 0.5)) scale(0.73684); 245 | opacity: 0.65; 246 | } 247 | } 248 | } 249 | 250 | .showOrbit { 251 | transition: all 0.8s ease-in-out; 252 | opacity: 1; 253 | z-index: 1; 254 | } 255 | 256 | .squares { 257 | position: absolute; 258 | top: 0; 259 | left: 0; 260 | width: 100vw; 261 | height: 100vh; 262 | overflow: hidden; 263 | 264 | li { 265 | position: absolute; 266 | display: block; 267 | list-style: none; 268 | width: 20px; 269 | height: 20px; 270 | background: #42d3ff60; 271 | animation: animate 25s linear infinite; 272 | bottom: -150px; 273 | border-radius: 6%; 274 | 275 | @for $i from 1 through 10 { 276 | &:nth-child(#{$i}) { 277 | @if ($i == 1) { 278 | left: 25%; 279 | width: 80px; 280 | height: 80px; 281 | animation-delay: 0s; 282 | } @else if ($i == 2) { 283 | left: 10%; 284 | width: 20px; 285 | height: 20px; 286 | animation-delay: 2s; 287 | animation-duration: 12s; 288 | } @else if ($i == 3) { 289 | left: 70%; 290 | width: 20px; 291 | height: 20px; 292 | animation-delay: 4s; 293 | } @else if ($i == 4) { 294 | left: 40%; 295 | width: 60px; 296 | height: 60px; 297 | animation-delay: 0s; 298 | animation-duration: 18s; 299 | } @else if ($i == 5) { 300 | left: 65%; 301 | width: 20px; 302 | height: 20px; 303 | animation-delay: 0s; 304 | } @else if ($i == 6) { 305 | left: 75%; 306 | width: 110px; 307 | height: 110px; 308 | animation-delay: 3s; 309 | } @else if ($i == 7) { 310 | left: 35%; 311 | width: 150px; 312 | height: 150px; 313 | animation-delay: 7s; 314 | } @else if ($i == 8) { 315 | left: 50%; 316 | width: 25px; 317 | height: 25px; 318 | animation-delay: 15s; 319 | animation-duration: 45s; 320 | } @else if ($i == 9) { 321 | left: 20%; 322 | width: 15px; 323 | height: 15px; 324 | animation-delay: 2s; 325 | animation-duration: 35s; 326 | } @else { 327 | left: 85%; 328 | width: 150px; 329 | height: 150px; 330 | animation-delay: 0s; 331 | animation-duration: 11s; 332 | } 333 | } 334 | } 335 | 336 | @keyframes animate { 337 | 0% { 338 | transform: translateY(0) rotate(0deg); 339 | opacity: 1; 340 | } 341 | 342 | 100% { 343 | transform: translateY(-120vh) rotate(720deg); 344 | opacity: 0; 345 | } 346 | } 347 | } 348 | } 349 | } 350 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 16 | 20 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 39 | GenCard 40 | 41 | 42 |
43 |
44 | contactless icon 45 |

GenCard

46 |
47 |
48 |
49 | 56 | 65 | 66 | 67 | 68 | 69 | 74 | 75 | 76 | 81 | 82 | 83 | 84 | 93 | 94 | 100 | 104 | 105 | 114 | 115 | 121 | 125 | 126 | 127 | 128 |
129 | 135 |
136 |
#### #### #### ####
137 |
138 |
Nome do titular
139 |
Nome Completo
140 |
141 |
142 |
143 |
Expiração
144 |
##/##
145 |
146 |
147 |
CVC
148 |
###
149 |
150 | ícone de chip de cartão de crédito 151 |
152 |
153 |
154 |
155 |
156 | 157 | 158 |
159 |
160 | 161 | 162 |
163 |
164 |
165 | 166 | 167 |
168 | 169 |
170 | 171 | 172 |
173 |
174 | 188 |
189 |
190 |
191 | 203 | 260 | 261 | 262 | 263 | -------------------------------------------------------------------------------- /src/css/index.css: -------------------------------------------------------------------------------- 1 | *{margin:0;padding:0;box-sizing:border-box;border:none;outline:none;text-decoration:none;list-style-type:none;font-family:Inter,sans-serif}:root{font-size:62.5%;color:rgba(255,255,255,.8705882353);font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%}body{font-size:1.6rem;background:linear-gradient(-5deg, #202024 51%, #323238 49%);display:flex;place-items:center;min-height:100vh}body .flex{display:flex}body #app{display:grid;justify-content:center;gap:3.2rem;width:100%;max-width:42rem;margin:0 auto;padding:2.8rem 6rem 4rem;background:#202024;border:2px solid #323238;border-radius:.6rem;position:relative;z-index:1;background:linear-gradient(5deg, #323238 51%, #202024 49%);transition:all .35s ease-in-out}body #app header{display:flex;align-items:center;border-bottom:2px solid #633bbc;width:148px}body #app header h1{font-size:24.5px;margin-left:8px;color:#e1e1e6;font-weight:300}body #app header span{font-weight:400;color:#6a6a6c}body .appLoadingState{filter:brightness(65%) blur(3px) opacity(0.95)}body .links{position:absolute;bottom:40px;left:50%;transform:translateX(-50%);border-bottom:8px solid #633bbc;border-radius:20px;padding:0 5px}body .links .links-list{display:flex;list-style-type:none;gap:8px}body .links .links-list li a img,body .links .links-list button{background:none;cursor:pointer;opacity:.7;transition:all .2s ease-in-out}body .links .links-list li a img:hover,body .links .links-list button:hover{opacity:1;transform:scale(0.9)}body .links .links-list button:hover::after{content:attr(data-tooltip);position:absolute;width:80px;height:40px;background:#42d3ff;color:#121214;font-size:14.5px;border-radius:5px;border-bottom-left-radius:50%;border-bottom-right-radius:50%;bottom:45px;left:calc(50% - 40px);line-height:32px;transition:all 1s ease-in-out}body .orbit{position:absolute;display:flex;align-items:center;justify-content:center;height:80px;width:80px;top:45%;right:45%;transform:translate(-50%);opacity:0}body .orbit::before,body .orbit::after{content:"";position:absolute;height:60%;width:60%;border-radius:50%;will-change:transform;flex-shrink:0}body .orbit::before{background-color:#8257e6;-webkit-animation:orbit 1.5s linear infinite;animation:orbit 1.5s linear infinite}body .orbit::after{background-color:#42d3ff;-webkit-animation:orbit 1.5s linear -0.75s infinite;animation:orbit 1.5s linear -0.75s infinite}@-webkit-keyframes orbit{0%{transform:translate(40px) scale(0.73684);opacity:.65}5%{transform:translate(32px) scale(0.684208);opacity:.58}10%{transform:translate(24px) scale(0.631576);opacity:.51}15%{transform:translate(16px) scale(0.578944);opacity:.44}20%{transform:translate(8px) scale(0.526312);opacity:.37}25%{transform:translate(0%) scale(0.47368);opacity:.3}30%{transform:translate(-8px) scale(0.526312);opacity:.37}35%{transform:translate(-16px) scale(0.578944);opacity:.44}40%{transform:translate(-24px) scale(0.631576);opacity:.51}45%{transform:translate(-32px) scale(0.684208);opacity:.58}50%{transform:translate(-40px) scale(0.73684);opacity:.65}55%{transform:translate(-32px) scale(0.789472);opacity:.72}60%{transform:translate(-24px) scale(0.842104);opacity:.79}65%{transform:translate(-16px) scale(0.894736);opacity:.86}70%{transform:translate(-8px) scale(0.947368);opacity:.93}75%{transform:translate(0%) scale(1);opacity:1}80%{transform:translate(8px) scale(0.947368);opacity:.93}85%{transform:translate(16px) scale(0.894736);opacity:.86}90%{transform:translate(24px) scale(0.842104);opacity:.79}95%{transform:translate(32px) scale(0.789472);opacity:.72}100%{transform:translate(40px) scale(0.73684);opacity:.65}}@keyframes orbit{0%{transform:translate(40px) scale(0.73684);opacity:.65}5%{transform:translate(32px) scale(0.684208);opacity:.58}10%{transform:translate(24px) scale(0.631576);opacity:.51}15%{transform:translate(16px) scale(0.578944);opacity:.44}20%{transform:translate(8px) scale(0.526312);opacity:.37}25%{transform:translate(0%) scale(0.47368);opacity:.3}30%{transform:translate(-8px) scale(0.526312);opacity:.37}35%{transform:translate(-16px) scale(0.578944);opacity:.44}40%{transform:translate(-24px) scale(0.631576);opacity:.51}45%{transform:translate(-32px) scale(0.684208);opacity:.58}50%{transform:translate(-40px) scale(0.73684);opacity:.65}55%{transform:translate(-32px) scale(0.789472);opacity:.72}60%{transform:translate(-24px) scale(0.842104);opacity:.79}65%{transform:translate(-16px) scale(0.894736);opacity:.86}70%{transform:translate(-8px) scale(0.947368);opacity:.93}75%{transform:translate(0%) scale(1);opacity:1}80%{transform:translate(8px) scale(0.947368);opacity:.93}85%{transform:translate(16px) scale(0.894736);opacity:.86}90%{transform:translate(24px) scale(0.842104);opacity:.79}95%{transform:translate(32px) scale(0.789472);opacity:.72}100%{transform:translate(40px) scale(0.73684);opacity:.65}}body .showOrbit{transition:all .8s ease-in-out;opacity:1;z-index:1}body .squares{position:absolute;top:0;left:0;width:100vw;height:100vh;overflow:hidden}body .squares li{position:absolute;display:block;list-style:none;width:20px;height:20px;background:rgba(66,211,255,.3764705882);-webkit-animation:animate 25s linear infinite;animation:animate 25s linear infinite;bottom:-150px;border-radius:6%}body .squares li:nth-child(1){left:25%;width:80px;height:80px;-webkit-animation-delay:0s;animation-delay:0s}body .squares li:nth-child(2){left:10%;width:20px;height:20px;-webkit-animation-delay:2s;animation-delay:2s;-webkit-animation-duration:12s;animation-duration:12s}body .squares li:nth-child(3){left:70%;width:20px;height:20px;-webkit-animation-delay:4s;animation-delay:4s}body .squares li:nth-child(4){left:40%;width:60px;height:60px;-webkit-animation-delay:0s;animation-delay:0s;-webkit-animation-duration:18s;animation-duration:18s}body .squares li:nth-child(5){left:65%;width:20px;height:20px;-webkit-animation-delay:0s;animation-delay:0s}body .squares li:nth-child(6){left:75%;width:110px;height:110px;-webkit-animation-delay:3s;animation-delay:3s}body .squares li:nth-child(7){left:35%;width:150px;height:150px;-webkit-animation-delay:7s;animation-delay:7s}body .squares li:nth-child(8){left:50%;width:25px;height:25px;-webkit-animation-delay:15s;animation-delay:15s;-webkit-animation-duration:45s;animation-duration:45s}body .squares li:nth-child(9){left:20%;width:15px;height:15px;-webkit-animation-delay:2s;animation-delay:2s;-webkit-animation-duration:35s;animation-duration:35s}body .squares li:nth-child(10){left:85%;width:150px;height:150px;-webkit-animation-delay:0s;animation-delay:0s;-webkit-animation-duration:11s;animation-duration:11s}@-webkit-keyframes animate{0%{transform:translateY(0) rotate(0deg);opacity:1}100%{transform:translateY(-120vh) rotate(720deg);opacity:0}}@keyframes animate{0%{transform:translateY(0) rotate(0deg);opacity:1}100%{transform:translateY(-120vh) rotate(720deg);opacity:0}}.cc{width:36.5rem;height:24rem;padding:2rem;display:flex;flex-direction:column;justify-content:space-between;z-index:1;background:#202024;border-radius:20px;border:1px solid rgba(255,255,255,.1254901961)}.cc .cc-bg{position:absolute;inset:0;z-index:1}.cc .cc-logo{display:flex;justify-content:space-between;align-items:flex-start}.cc .cc-logo span:nth-child(2) img{transition:all .8s ease-in-out;opacity:0;max-height:35px;transform:translateY(-5px)}.cc .cc-info{display:grid;gap:1.4rem}.cc .cc-info .cc-number{font-size:2.4rem;font-weight:bold;line-height:2.9rem;letter-spacing:.04em;color:#e1e1e6;text-shadow:0 .12rem .32rem rgba(23,23,23,.4)}.cc .cc-info .cc-holder,.cc .cc-info .cc-expiration,.cc .cc-info .cc-security{display:grid;gap:.4rem}.cc .cc-info .cc-extra{display:flex;justify-content:space-between;align-items:center}.cc .label{font-size:1rem;line-height:1.2rem}.cc .value{font-size:1.4rem;font-weight:bold;color:#e1e1e6;text-shadow:0 .25rem .25rem rgba(22,22,22,.16);text-transform:uppercase}.cc,.cc-logo,.cc-number{position:relative;z-index:1}form{max-width:36rem;display:grid;gap:1.6rem}form .input-wrapper{display:grid;gap:.6rem}form label{font-weight:600;font-size:1.2rem;line-height:1.5rem;letter-spacing:.01px;text-transform:uppercase;color:#e1e1e6}form input{background:#121214;border:2px solid #323238;border-radius:6px;height:41px;padding-inline:1.2rem;width:100%;color:#e1e1e6;text-transform:uppercase;transition:all .5s ease-in-out}form .flex{gap:1.4rem}form .flex .input-wrapper{flex:1}form button{position:relative;padding:1.6rem 1.8rem;color:#8257e6;text-transform:uppercase;letter-spacing:2px;overflow:hidden;transition:.2s;border-radius:.5em;margin-top:1.6rem;display:flex;justify-content:center;align-items:center;font-weight:700;font-size:1.4rem;line-height:1.7rem;cursor:not-allowed;opacity:.65;background:#201214;height:49px}form button span{position:absolute}form button span:nth-child(1){top:0;left:-100%;width:100%;height:2px;background:linear-gradient(90deg, transparent, #8257e6)}form button span:nth-child(2){top:-100%;right:0;width:2px;height:100%;background:linear-gradient(180deg, transparent, #8257e6)}form button span:nth-child(3){bottom:0;right:-100%;width:100%;height:2px;background:linear-gradient(90deg, transparent, #42d3ff)}form button span:nth-child(4){bottom:-100%;left:0;width:2px;height:100%;background:linear-gradient(360deg, transparent, #42d3ff)}form button:active span:nth-child(1){transition:none;transition-delay:none}form button:active span:nth-child(2){transition:none;transition-delay:none}form button:active span:nth-child(3){transition:none;transition-delay:none}form button:active span:nth-child(4){transition:none;transition-delay:none}form .activeButton{cursor:pointer;opacity:1;background:#121214}form .activeButton:hover span:nth-child(1){left:100%;transition:.7s}form .activeButton:hover span:nth-child(2){top:100%;transition:.7s;transition-delay:.17s}form .activeButton:hover span:nth-child(3){right:100%;transition:.7s;transition-delay:.35s}form .activeButton:hover span:nth-child(4){bottom:100%;transition:.7s;transition-delay:.52s}form .activeButton:active{background:#633bbc;background:linear-gradient(to top right, #633bbc 28%, #42d3ff);color:#e1e1e6;box-shadow:0 0 8px #8257e6,0 0 8px #42d3ff,0 0 8px #8257e6;transition:.1s;transition-delay:none}form .hideButtonElement{display:none !important}.waveform{display:flex;flex-flow:row nowrap;align-items:center;justify-content:space-between;width:25px;height:22.5px}.waveform .waveform__bar{width:3.5px;height:100%;background-color:#8257e6}.waveform .waveform__bar:nth-child(1){-webkit-animation:grow 1s ease-in-out -0.45s infinite;animation:grow 1s ease-in-out -0.45s infinite}.waveform .waveform__bar:nth-child(2){-webkit-animation:grow 1s ease-in-out -0.3s infinite;animation:grow 1s ease-in-out -0.3s infinite}.waveform .waveform__bar:nth-child(3){-webkit-animation:grow 1s ease-in-out -0.15s infinite;animation:grow 1s ease-in-out -0.15s infinite}.waveform .waveform__bar:nth-child(4){-webkit-animation:grow 1s ease-in-out infinite;animation:grow 1s ease-in-out infinite}@-webkit-keyframes grow{0%,100%{transform:scaleY(0.3)}50%{transform:scaleY(1)}}@keyframes grow{0%,100%{transform:scaleY(0.3)}50%{transform:scaleY(1)}}.swal-overlay{background-color:rgba(130,87,230,.4392156863)}.swal-overlay .swal-modal{background-color:#202024;border:2px solid #323238}.swal-overlay .swal-modal .swal-icon::before,.swal-overlay .swal-modal .swal-icon::after,.swal-overlay .swal-modal .swal-icon--success__hide-corners{background:#202024}.swal-overlay .swal-modal .swal-icon--success{border-color:#42d3ff}.swal-overlay .swal-modal .swal-icon--success__line{background-color:#42d3ff}.swal-overlay .swal-modal .swal-text{color:#e1e1e6;font-size:17px;text-align:center;margin-top:30px;display:block}.swal-overlay .swal-modal .swal-title{text-align:center;text-transform:capitalize;font-size:33px;color:#633bbc;border-bottom:2px solid #42d3ff;border-radius:2px;display:inline}.swal-overlay .swal-modal .swal-content__img{width:100%;max-width:288px}.swal-overlay .swal-modal .swal-button-container{border-radius:6px;overflow:hidden}.swal-overlay .swal-modal .swal-button-container .swal-button.swal-button--confirm{display:flex;justify-content:center;align-items:center;flex-direction:column;color:#e1e1e6;background:#8257e6;width:110px;height:45px;border:2px solid #42d3ff;transition:.2s all ease-in-out}.swal-overlay .swal-modal .swal-button-container .swal-button.swal-button--confirm:hover{background:#633bbc}.swal-overlay .swal-modal .swal-button-container .swal-button.swal-button--confirm:hover::before{top:10px}.swal-overlay .swal-modal .swal-button-container .swal-button.swal-button--confirm:hover::after{bottom:-40px}.swal-overlay .swal-modal .swal-button-container .swal-button.swal-button--confirm::before{content:url("https://user-images.githubusercontent.com/86276393/203387682-dee65164-c138-49c4-b39c-8547aafa0140.png");position:absolute;top:-40px;transition:all .4s ease-in-out}.swal-overlay .swal-modal .swal-button-container .swal-button.swal-button--confirm::after{content:"Download";position:absolute;bottom:14px;transition:all .4s ease-in-out}@media(max-width: 440px){:root{font-size:50%}body{background:linear-gradient(5deg, #323238 50.5%, #202024 49.5%)}body #app{background:none;border:none}body #app .cc-bg svg{width:100%;height:auto}}@media(min-width: 840px){body{padding:30px;background:linear-gradient(45deg, #202024 61.5%, #323238 39.5%)}body #app{grid-template-areas:"A B" "C B";width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;max-width:-webkit-fit-content;max-width:-moz-fit-content;max-width:fit-content;padding-inline:4.8rem;grid-template-columns:.8fr 1fr;background:linear-gradient(-45deg, #202024 61.5%, #323238 39.5%)}body #app header{grid-area:A}body #app section.cc{grid-area:B;align-self:center}body #app form{grid-area:C}}/*# sourceMappingURL=index.css.map */ --------------------------------------------------------------------------------