Add files via upload
This commit is contained in:
		
						commit
						1c99d6fbb9
					
				
							
								
								
									
										21
									
								
								LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| The MIT License (MIT) | ||||
| 
 | ||||
| Copyright (c) 2022 by Jessica Guarato  (https://codepen.io/jguarato/pen/PoRQPqG) | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
							
								
								
									
										4
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| # Solitaire (desktop browsers only) | ||||
| 
 | ||||
| A Pen created on CodePen.io. Original URL: [https://codepen.io/jguarato/pen/PoRQPqG](https://codepen.io/jguarato/pen/PoRQPqG). | ||||
| 
 | ||||
							
								
								
									
										49
									
								
								dist/index.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								dist/index.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en" > | ||||
| <head> | ||||
|   <meta charset="UTF-8"> | ||||
|   <title>CodePen - Solitaire (desktop browsers only)</title> | ||||
|   <link rel="stylesheet" href="./style.css"> | ||||
| 
 | ||||
| </head> | ||||
| <body> | ||||
| <!-- partial:index.partial.html --> | ||||
| <div class="top-area"> | ||||
|   <div class="container"> | ||||
|     <div class="left-area"> | ||||
|       <div id="deck" class="deck"></div> | ||||
|       <div id="top-cards" class="top-cards"></div> | ||||
|     </div> | ||||
|     <div class="right-area"> | ||||
|       <div class="pile"><span id="spade-cards">♠</span></div> | ||||
|       <div class="pile"><span id="heart-cards">♥</span></div> | ||||
|       <div class="pile"><span id="diamond-cards">♦</span></div> | ||||
|       <div class="pile"><span id="club-cards">♣</span></div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| 
 | ||||
| <div class="container"> | ||||
|   <div class="bottom-area"> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|   </div> | ||||
| </div> | ||||
| 
 | ||||
| <footer> | ||||
|   <p> | ||||
|     Created by <a class="name-dark">jguarato</a> •  | ||||
|     <a href="https://codepen.io/jguarato" target="_blank">Check out my other Pens</a> • | ||||
|     <a href="https://github.com/jguarato" target="_blank">Follow me on GitHub</a> | ||||
|   </p> | ||||
| </footer> | ||||
| <!-- partial --> | ||||
|   <script  src="./script.js"></script> | ||||
| 
 | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										414
									
								
								dist/script.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										414
									
								
								dist/script.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,414 @@ | ||||
| function createCard(rank, suit, higher) { | ||||
| 
 | ||||
|     let suitSymbol, cardColor; | ||||
|     switch (suit) { | ||||
|         case 'spade': | ||||
|             suitSymbol = '♠'; | ||||
|             cardColor = 'black'; | ||||
|             break; | ||||
|         case 'heart': | ||||
|             suitSymbol = '♥'; | ||||
|             cardColor = 'red'; | ||||
|             break; | ||||
|         case 'diamond': | ||||
|             suitSymbol = '♦'; | ||||
|             cardColor = 'red'; | ||||
|             break; | ||||
|         case 'club': | ||||
|             suitSymbol = '♣'; | ||||
|             cardColor = 'black'; | ||||
|             break; | ||||
|         default: | ||||
|             suitSymbol = '🃏'; | ||||
|             cardColor = 'black'; | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     let frontInnerHTML = `<div class="inner-info card-rank">${rank}</div>`; | ||||
|     frontInnerHTML += `<div class="inner-info card-suit-small">${suitSymbol}</div>`; | ||||
|     frontInnerHTML += `<div class="inner-info card-suit-big">${suitSymbol}</div>`; | ||||
| 
 | ||||
|     return { | ||||
|         rank, | ||||
|         higher, | ||||
|         inner: frontInnerHTML, | ||||
|         suit, | ||||
|         color: cardColor, | ||||
|         below: null | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function createDeck() { | ||||
| 
 | ||||
|     const cardRanking = ['A', '2', '3', '4', '5', | ||||
|         '6', '7', '8', '9', '10', 'J', 'Q', 'K']; | ||||
| 
 | ||||
|     const cardSuits = ['spade', 'heart', 'diamond', 'club']; | ||||
| 
 | ||||
|     const deck = []; | ||||
| 
 | ||||
|     for (let i = 0; i < cardSuits.length; i++) { | ||||
|         for (let j = 0; j < cardRanking.length; j++) { | ||||
| 
 | ||||
|             const higherRank = cardRanking[j + 1] ? cardRanking[j + 1] : null; | ||||
|             const newCard = createCard(cardRanking[j], cardSuits[i], higherRank); | ||||
|             deck.push(newCard); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     return deck; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function shuffleCards(deck) { | ||||
|     return deck.sort(() => Math.random() - 0.5); | ||||
| } | ||||
| 
 | ||||
| function putCardsInDeck(cards) { | ||||
| 
 | ||||
|     const deck = document.getElementById('deck'); | ||||
| 
 | ||||
|     cards.forEach(() => { | ||||
|         deck.innerHTML += `<div class="card back"></div>`; | ||||
|     }); | ||||
| 
 | ||||
|     const cardsInDeck = deck.querySelectorAll('.card'); | ||||
| 
 | ||||
|     cards.forEach((card, index) => { | ||||
|         cardsInDeck[index].cardInfo = card; | ||||
|     }); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function turnCard() { | ||||
| 
 | ||||
|     const isLastCard = this === this.parentNode.lastElementChild; | ||||
|     const isCardVisible = this.style.visibility !== 'hidden'; | ||||
|     const isCardFacingDown = this.classList.contains('back'); | ||||
| 
 | ||||
|     if (isLastCard && isCardVisible) { | ||||
| 
 | ||||
|         if (isCardFacingDown) { | ||||
|          | ||||
|             this.classList.remove('back'); | ||||
|             this.classList.add(`${this.cardInfo.suit}`); | ||||
|             this.innerHTML = this.cardInfo.inner; | ||||
|         } | ||||
| 
 | ||||
|         this.setAttribute('draggable', true); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function turnCardBack(card) { | ||||
|      | ||||
|     card.classList.remove(`${card.cardInfo.suit}`); | ||||
|     card.classList.add('back'); | ||||
|     card.innerHTML = ''; | ||||
|     card.setAttribute('draggable', false); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function distributeCards() { | ||||
| 
 | ||||
|     const piles = document.querySelectorAll('.row'); | ||||
| 
 | ||||
|     piles.forEach((pile, index) => { | ||||
|          | ||||
|         for (let i = 0; i < index + 1; i++) { | ||||
| 
 | ||||
|             const deck = document.getElementById('deck'); | ||||
|             const topCard = deck.lastElementChild; | ||||
| 
 | ||||
|             if (i === index) { | ||||
|                 turnCard.apply(topCard); | ||||
|             } | ||||
| 
 | ||||
|             deck.removeChild(topCard); | ||||
|             pile.append(topCard); | ||||
|         } | ||||
| 
 | ||||
|     }); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function showTopCard(topCards, deck, deckTopCard) { | ||||
| 
 | ||||
|     if (deckTopCard.cardInfo) { | ||||
| 
 | ||||
|         deck.removeChild(deckTopCard); | ||||
|         topCards.append(deckTopCard); | ||||
|          | ||||
|         if (topCards.childElementCount > 1) { | ||||
|             topCards.childNodes[0].setAttribute('draggable', false); | ||||
|         } | ||||
| 
 | ||||
|         if (topCards.childElementCount > 2) { | ||||
|             topCards.childNodes[1].setAttribute('draggable', false); | ||||
|         } | ||||
| 
 | ||||
|         if (topCards.childElementCount > 3) { | ||||
| 
 | ||||
|             topCards.childNodes[2].setAttribute('draggable', false); | ||||
| 
 | ||||
|             const firstCard = topCards.firstElementChild; | ||||
| 
 | ||||
|             turnCardBack(firstCard); | ||||
|             firstCard.style.visibility = 'hidden'; | ||||
| 
 | ||||
|             topCards.removeChild(firstCard); | ||||
|             deck.prepend(firstCard); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function returnCardsToDeck(topCards, deck) { | ||||
| 
 | ||||
|     const cardsToDeck = []; | ||||
| 
 | ||||
|     topCards.childNodes.forEach(card => { | ||||
|         turnCardBack(card); | ||||
|         card.style.visibility = 'hidden'; | ||||
|         cardsToDeck.push(card); | ||||
|     }); | ||||
| 
 | ||||
|     cardsToDeck.forEach(card => { | ||||
|         deck.prepend(card); | ||||
|     }); | ||||
| 
 | ||||
|     topCards.innerHTML = ''; | ||||
| 
 | ||||
|     const cardsInDeck = deck.querySelectorAll('.card'); | ||||
| 
 | ||||
|     cardsInDeck.forEach(card => { | ||||
|         card.style.visibility = 'visible'; | ||||
|     }); | ||||
| 
 | ||||
|      | ||||
| } | ||||
| 
 | ||||
| function checkDeckCards() { | ||||
| 
 | ||||
|     const topCards = document.getElementById('top-cards'); | ||||
|     const deck = document.getElementById('deck'); | ||||
|     const deckTopCard = deck.lastElementChild; | ||||
| 
 | ||||
|     if (!deckTopCard) { | ||||
|         returnCardsToDeck(topCards, deck); | ||||
|     } else if (deckTopCard.style.visibility === 'hidden') { | ||||
|         returnCardsToDeck(topCards, deck); | ||||
|     } else { | ||||
|         showTopCard(topCards, deck, deckTopCard); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function changeCardPosition(cardToDrop, dropSpot, checkCondition) { | ||||
| 
 | ||||
|     if (checkCondition) { | ||||
| 
 | ||||
|         const cardAbove = cardToDrop.previousSibling; | ||||
| 
 | ||||
|         cardToDrop.parentNode.removeChild(cardToDrop); | ||||
|         dropSpot.append(cardToDrop); | ||||
| 
 | ||||
|         if (cardToDrop.cardInfo.below) { | ||||
|             cardToDrop.cardInfo.below.forEach(card => dropSpot.append(card)); | ||||
|         } | ||||
| 
 | ||||
|         return cardAbove; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function dropInRow(cardToDrop, dropSpot) { | ||||
|      | ||||
|     const cardToDropInfo = cardToDrop.cardInfo; | ||||
|     const lastCardInRow = dropSpot.lastElementChild; | ||||
|      | ||||
|     if (lastCardInRow) { | ||||
| 
 | ||||
|         const lastCardInfo = lastCardInRow.cardInfo; | ||||
| 
 | ||||
|         if (lastCardInfo && lastCardInRow.draggable) { | ||||
| 
 | ||||
|             const checkRank = lastCardInfo.rank === cardToDropInfo.higher; | ||||
|             const checkColor = lastCardInfo.color !== cardToDropInfo.color; | ||||
| 
 | ||||
|             return changeCardPosition(cardToDrop, dropSpot, (checkRank && checkColor)); | ||||
|         } | ||||
| 
 | ||||
|     } else { | ||||
| 
 | ||||
|         const checkRank = cardToDrop.cardInfo.rank === 'K'; | ||||
| 
 | ||||
|         return changeCardPosition(cardToDrop, dropSpot, checkRank); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function dropInPile(cardToDrop, dropSpot) { | ||||
| 
 | ||||
|     const cardToDropInfo = cardToDrop.cardInfo; | ||||
|     const lastCardInPile = dropSpot.lastElementChild; | ||||
| 
 | ||||
|     if (!cardToDropInfo.below) { | ||||
| 
 | ||||
|         if (lastCardInPile) { | ||||
| 
 | ||||
|             const lastCardInfo = lastCardInPile.cardInfo; | ||||
| 
 | ||||
|             if (lastCardInfo) { | ||||
| 
 | ||||
|                 const checkRank = lastCardInfo.higher === cardToDropInfo.rank; | ||||
|                 const checkSuit = lastCardInfo.suit === cardToDropInfo.suit; | ||||
| 
 | ||||
|                 if (checkRank && checkSuit) { | ||||
|                     lastCardInPile.setAttribute('draggable', false); | ||||
|                 } | ||||
| 
 | ||||
|                 return changeCardPosition(cardToDrop, dropSpot, (checkRank && checkSuit)); | ||||
| 
 | ||||
|             } else { | ||||
| 
 | ||||
|                 const checkRank = cardToDropInfo.rank === 'A'; | ||||
|                 const checkSuit = lastCardInPile.id.split('-')[0] === cardToDropInfo.suit; | ||||
| 
 | ||||
|                 return changeCardPosition(cardToDrop, dropSpot, (checkRank && checkSuit)); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function dropCard(event, cardToDrop) { | ||||
| 
 | ||||
|     const tgt = event.target; | ||||
| 
 | ||||
|     const findSpot = function (element, htmlClass) { | ||||
| 
 | ||||
|         const classList = element.classList; | ||||
| 
 | ||||
|         if (classList) { | ||||
| 
 | ||||
|             if (classList.contains(htmlClass)) { | ||||
|                 return element; | ||||
| 
 | ||||
|             } else { | ||||
|                 return findSpot(element.parentNode, htmlClass); | ||||
| 
 | ||||
|             }  | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         return; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     const dropSpot = findSpot(tgt, 'row') || findSpot(tgt, 'pile'); | ||||
| 
 | ||||
|     let cardAbove; | ||||
| 
 | ||||
|     if (dropSpot) { | ||||
| 
 | ||||
|         if (dropSpot.classList.contains('row')) { | ||||
| 
 | ||||
|             cardAbove = dropInRow(cardToDrop, dropSpot); | ||||
| 
 | ||||
|         } else if (dropSpot.classList.contains('pile')) { | ||||
| 
 | ||||
|             cardAbove = dropInPile(cardToDrop, dropSpot); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     if (cardAbove) { | ||||
|         turnCard.apply(cardAbove); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function checkGameOver() { | ||||
| 
 | ||||
|     const piles = document.querySelectorAll('.pile'); | ||||
| 
 | ||||
|     let allPilesComplete =  true; | ||||
| 
 | ||||
|     piles.forEach(pile => { | ||||
|         allPilesComplete = allPilesComplete && (pile.childElementCount - 1) === 13; | ||||
|     }); | ||||
| 
 | ||||
|     if (allPilesComplete) { | ||||
|         alert('YOU WIN!'); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function resetSelections(card) { | ||||
| 
 | ||||
|     card.cardInfo.below = null; | ||||
|     card = null; | ||||
| 
 | ||||
|     return card; | ||||
| } | ||||
| 
 | ||||
| function dragRowCards(card) { | ||||
| 
 | ||||
|     const cardParent = card.parentNode; | ||||
|     const isLastCard = card === cardParent.lastElementChild; | ||||
| 
 | ||||
|     if (!isLastCard) { | ||||
| 
 | ||||
|         card.cardInfo.below = []; | ||||
| 
 | ||||
|         for (let i = cardParent.childElementCount - 1; i >= 0; i--) { | ||||
| 
 | ||||
|             if (cardParent.childNodes[i] === card) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             card.cardInfo.below.unshift(cardParent.childNodes[i]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| const globalDeck = createDeck(); | ||||
| const shuffledDeck = shuffleCards(globalDeck); | ||||
| putCardsInDeck(shuffledDeck); | ||||
| distributeCards(); | ||||
| 
 | ||||
| const deck = document.getElementById('deck'); | ||||
| deck.addEventListener('click', checkDeckCards); | ||||
| 
 | ||||
| const cards = document.getElementsByClassName('card'); | ||||
| for (let i = 0; i < cards.length; i++) { | ||||
|     cards[i].addEventListener('click', turnCard); | ||||
| } | ||||
| 
 | ||||
| let selectedCard = null; | ||||
| 
 | ||||
| document.addEventListener("dragstart", event => { | ||||
|     if (event.target.draggable) { | ||||
|         selectedCard = event.target; | ||||
|         dragRowCards(selectedCard); | ||||
|     } | ||||
| }); | ||||
|    | ||||
| document.addEventListener("dragover", event => { | ||||
|     event.preventDefault(); | ||||
| }, false); | ||||
| 
 | ||||
| document.addEventListener("drop", event => { | ||||
|     event.preventDefault(); | ||||
|     dropCard(event, selectedCard); | ||||
|     selectedCard = resetSelections(selectedCard); | ||||
|     checkGameOver(); | ||||
| }); | ||||
							
								
								
									
										256
									
								
								dist/style.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								dist/style.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,256 @@ | ||||
| @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&family=Poppins:wght@300;400;500;600&display=swap'); | ||||
| 
 | ||||
| html, | ||||
| body { | ||||
|   width: 100%; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
|   background-color: #f7f7f7; | ||||
|   background-color: #147246; | ||||
|   font: 400 1.2em sans-serif; | ||||
|   line-height: 1.2; | ||||
|   user-select: none; | ||||
| } | ||||
| 
 | ||||
| .container { | ||||
|   width: fit-content; | ||||
|   height: 100%; | ||||
|   margin: 0 auto; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .card { | ||||
|   padding: 0; | ||||
|   margin: 2vmin; | ||||
|   width: 7.6vmin; | ||||
|   height: 11vmin; | ||||
|   box-shadow: inset 0px 0px 1vmin 0.2vmin #c3c6c6; | ||||
|   border-radius: 0.8vmin;  | ||||
|   background-color: #f5f9fa; | ||||
|   font-family: Roboto; | ||||
| } | ||||
| 
 | ||||
| .card-rank { | ||||
|   width: 48%; | ||||
|   float: left; | ||||
|   margin-left: 0.4vmin; | ||||
|   margin-right: 0.3vmin; | ||||
|   letter-spacing: -0.8vmin; | ||||
|   font-size: 4vmin; | ||||
|   font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| .card-suit-small { | ||||
|   width: 40%; | ||||
|   float: left; | ||||
|   font-size: 4vmin; | ||||
| } | ||||
| 
 | ||||
| .card-suit-big { | ||||
|   width: 100%; | ||||
|   height: inherit; | ||||
|   line-height: 0.6; | ||||
|   font-size: 8vmin; | ||||
|   text-align: center; | ||||
| } | ||||
| 
 | ||||
| @-moz-document url-prefix() { | ||||
|   .card-rank { | ||||
|     margin-right: 0.3vmin; | ||||
|     font-size: 4vmin; | ||||
|   } | ||||
|    | ||||
|   .card-suit-small { | ||||
|     line-height: 1.6; | ||||
|     font-size: 3vmin; | ||||
|   } | ||||
|    | ||||
|   .card-suit-big { | ||||
|     line-height: 0.8; | ||||
|     font-size: 7vmin; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .card.diamond .inner-info, | ||||
| .card.heart .inner-info { | ||||
|   background: linear-gradient(to right, #c21f02, #ff2802, #c21f02, #ff2802, #c21f02); | ||||
|   -webkit-background-clip: text; | ||||
|   color: transparent; | ||||
| } | ||||
| 
 | ||||
| .card.club .inner-info, | ||||
| .card.spade .inner-info { | ||||
|   background: linear-gradient(to right, #242222, #534f51, #242222, #534f51, #242222); | ||||
|   -webkit-background-clip: text; | ||||
|   color: transparent; | ||||
| } | ||||
| 
 | ||||
| .back { | ||||
|   box-shadow: inset 0px 0px 0.2vmin 0.2vmin #0a2f41; | ||||
|   background: linear-gradient(315deg, #242222, #534f51, #242222, #534f51, #242222); | ||||
|   background: linear-gradient(315deg, #0a3142, #104c66, #12506b, #1b7ca5, #2195ca); | ||||
| } | ||||
| 
 | ||||
| .top-area { | ||||
|   padding-top: 2vmin; | ||||
|   width: 100vw; | ||||
|   height: 16vmin; | ||||
|   background-color: #1b4934; | ||||
| } | ||||
| 
 | ||||
| .left-area, | ||||
| .right-area { | ||||
|   display: flex; | ||||
|   place-content: center; | ||||
|   float: left; | ||||
| } | ||||
| 
 | ||||
| .left-area { | ||||
|   width: 41vmin; | ||||
| } | ||||
| 
 | ||||
| .right-area { | ||||
|   width: 57vmin; | ||||
| } | ||||
| 
 | ||||
| .deck { | ||||
|   margin: 2vmin; | ||||
|   width: 7.6vmin; | ||||
|   height: 11vmin; | ||||
|   box-shadow: inset 0px 0px 0vmin 0.5vmin #c3c6c644; | ||||
|   border-radius: 0.8vmin; | ||||
|   background-color: #c3c6c60c; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .deck::before { | ||||
|   content: "⟲"; | ||||
|   width: 100%; | ||||
|   height: inherit; | ||||
|   line-height: 1.6; | ||||
|   font-size: 7vmin; | ||||
|   text-align: center; | ||||
|   color: #c3c6c644; | ||||
|   position: absolute; | ||||
|   cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| .deck .card { | ||||
|   position: absolute; | ||||
|   transform: translateX(-2vmin) translateY(-2vmin); | ||||
|   cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| .top-cards { | ||||
|   width: 55%; | ||||
|   display: flex; | ||||
| } | ||||
| 
 | ||||
| .top-cards .card { | ||||
|   margin-right: -5vmin; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .pile { | ||||
|   padding: 0; | ||||
|   margin: 2vmin; | ||||
|   width: 7.6vmin; | ||||
|   height: 11vmin; | ||||
|   box-shadow: inset 0px 0px 0vmin 0.5vmin #c3c6c644; | ||||
|   border-radius: 0.8vmin; | ||||
|   background-color: #c3c6c60c; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .pile span { | ||||
|   width: 100%; | ||||
|   height: inherit; | ||||
|   line-height: 1.4; | ||||
|   font-size: 8vmin; | ||||
|   text-align: center; | ||||
|   color: #c3c6c644; | ||||
|   position: absolute; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .pile .card { | ||||
|   position: absolute; | ||||
|   transform: translateX(-2vmin) translateY(-2vmin); | ||||
| } | ||||
| 
 | ||||
| .bottom-area { | ||||
|   display: flex; | ||||
|   place-content: center; | ||||
|   width: 100vmin; | ||||
|   min-height: 100%; | ||||
|   height: fit-content; | ||||
|   padding-top: 4vmin; | ||||
|   padding-bottom: 10vmin; | ||||
| } | ||||
| 
 | ||||
| .row { | ||||
|   display: grid; | ||||
|   margin-right: 1%; | ||||
|   width: 12%; | ||||
|   height: 100%; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .row::before { | ||||
|   content: ""; | ||||
|   width: 7.6vmin; | ||||
|   height: 11vmin; | ||||
|   box-shadow: inset 0px 0px 0vmin 0.5vmin #c3c6c644; | ||||
|   border-radius: 0.8vmin; | ||||
|   background-color: #c3c6c60c; | ||||
|   transform: translateX(2vmin) translateY(2vmin); | ||||
|   position: absolute; | ||||
| } | ||||
| 
 | ||||
| .row .card { | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .row .card:not(:first-child) { | ||||
|   margin-top: -8vmin; | ||||
| } | ||||
| 
 | ||||
| footer { | ||||
|   position: fixed; | ||||
|   bottom: 0; | ||||
|   width: 100%; | ||||
|   height: fit-content; | ||||
|   margin-top: 25vmin; | ||||
|   padding: 1vmin 0; | ||||
|   background-color: #1e1f26; | ||||
|   font-size: 1.6vmin; | ||||
| } | ||||
| 
 | ||||
| footer p { | ||||
|   margin: 1vmin; | ||||
|   text-align: center; | ||||
|   color: #F5F5F5; | ||||
|   font-family: Poppins; | ||||
| } | ||||
| 
 | ||||
| footer a:link { | ||||
|   color: #b3a290; | ||||
| } | ||||
| footer a:visited { | ||||
|   color: #91d4d0; | ||||
| } | ||||
| footer a:hover { | ||||
|   color: #ff3300; | ||||
| } | ||||
| footer a:active { | ||||
|   color: #ff3300; | ||||
| } | ||||
| 
 | ||||
| .name-dark { | ||||
|   color: #91d4d0; | ||||
|   text-decoration: none; | ||||
|   background: linear-gradient(to right, #91d4d0 50%, #ff3300 100%); | ||||
|   -webkit-background-clip: text; | ||||
|   -webkit-text-fill-color: transparent; | ||||
| } | ||||
							
								
								
									
										34
									
								
								src/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| <div class="top-area"> | ||||
|   <div class="container"> | ||||
|     <div class="left-area"> | ||||
|       <div id="deck" class="deck"></div> | ||||
|       <div id="top-cards" class="top-cards"></div> | ||||
|     </div> | ||||
|     <div class="right-area"> | ||||
|       <div class="pile"><span id="spade-cards">♠</span></div> | ||||
|       <div class="pile"><span id="heart-cards">♥</span></div> | ||||
|       <div class="pile"><span id="diamond-cards">♦</span></div> | ||||
|       <div class="pile"><span id="club-cards">♣</span></div> | ||||
|     </div> | ||||
|   </div> | ||||
| </div> | ||||
| 
 | ||||
| <div class="container"> | ||||
|   <div class="bottom-area"> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|     <div class="row"></div> | ||||
|   </div> | ||||
| </div> | ||||
| 
 | ||||
| <footer> | ||||
|   <p> | ||||
|     Created by <a class="name-dark">jguarato</a> •  | ||||
|     <a href="https://codepen.io/jguarato" target="_blank">Check out my other Pens</a> • | ||||
|     <a href="https://github.com/jguarato" target="_blank">Follow me on GitHub</a> | ||||
|   </p> | ||||
| </footer> | ||||
							
								
								
									
										414
									
								
								src/script.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										414
									
								
								src/script.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,414 @@ | ||||
| function createCard(rank, suit, higher) { | ||||
| 
 | ||||
|     let suitSymbol, cardColor; | ||||
|     switch (suit) { | ||||
|         case 'spade': | ||||
|             suitSymbol = '♠'; | ||||
|             cardColor = 'black'; | ||||
|             break; | ||||
|         case 'heart': | ||||
|             suitSymbol = '♥'; | ||||
|             cardColor = 'red'; | ||||
|             break; | ||||
|         case 'diamond': | ||||
|             suitSymbol = '♦'; | ||||
|             cardColor = 'red'; | ||||
|             break; | ||||
|         case 'club': | ||||
|             suitSymbol = '♣'; | ||||
|             cardColor = 'black'; | ||||
|             break; | ||||
|         default: | ||||
|             suitSymbol = '🃏'; | ||||
|             cardColor = 'black'; | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     let frontInnerHTML = `<div class="inner-info card-rank">${rank}</div>`; | ||||
|     frontInnerHTML += `<div class="inner-info card-suit-small">${suitSymbol}</div>`; | ||||
|     frontInnerHTML += `<div class="inner-info card-suit-big">${suitSymbol}</div>`; | ||||
| 
 | ||||
|     return { | ||||
|         rank, | ||||
|         higher, | ||||
|         inner: frontInnerHTML, | ||||
|         suit, | ||||
|         color: cardColor, | ||||
|         below: null | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function createDeck() { | ||||
| 
 | ||||
|     const cardRanking = ['A', '2', '3', '4', '5', | ||||
|         '6', '7', '8', '9', '10', 'J', 'Q', 'K']; | ||||
| 
 | ||||
|     const cardSuits = ['spade', 'heart', 'diamond', 'club']; | ||||
| 
 | ||||
|     const deck = []; | ||||
| 
 | ||||
|     for (let i = 0; i < cardSuits.length; i++) { | ||||
|         for (let j = 0; j < cardRanking.length; j++) { | ||||
| 
 | ||||
|             const higherRank = cardRanking[j + 1] ? cardRanking[j + 1] : null; | ||||
|             const newCard = createCard(cardRanking[j], cardSuits[i], higherRank); | ||||
|             deck.push(newCard); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     return deck; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function shuffleCards(deck) { | ||||
|     return deck.sort(() => Math.random() - 0.5); | ||||
| } | ||||
| 
 | ||||
| function putCardsInDeck(cards) { | ||||
| 
 | ||||
|     const deck = document.getElementById('deck'); | ||||
| 
 | ||||
|     cards.forEach(() => { | ||||
|         deck.innerHTML += `<div class="card back"></div>`; | ||||
|     }); | ||||
| 
 | ||||
|     const cardsInDeck = deck.querySelectorAll('.card'); | ||||
| 
 | ||||
|     cards.forEach((card, index) => { | ||||
|         cardsInDeck[index].cardInfo = card; | ||||
|     }); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function turnCard() { | ||||
| 
 | ||||
|     const isLastCard = this === this.parentNode.lastElementChild; | ||||
|     const isCardVisible = this.style.visibility !== 'hidden'; | ||||
|     const isCardFacingDown = this.classList.contains('back'); | ||||
| 
 | ||||
|     if (isLastCard && isCardVisible) { | ||||
| 
 | ||||
|         if (isCardFacingDown) { | ||||
|          | ||||
|             this.classList.remove('back'); | ||||
|             this.classList.add(`${this.cardInfo.suit}`); | ||||
|             this.innerHTML = this.cardInfo.inner; | ||||
|         } | ||||
| 
 | ||||
|         this.setAttribute('draggable', true); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function turnCardBack(card) { | ||||
|      | ||||
|     card.classList.remove(`${card.cardInfo.suit}`); | ||||
|     card.classList.add('back'); | ||||
|     card.innerHTML = ''; | ||||
|     card.setAttribute('draggable', false); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function distributeCards() { | ||||
| 
 | ||||
|     const piles = document.querySelectorAll('.row'); | ||||
| 
 | ||||
|     piles.forEach((pile, index) => { | ||||
|          | ||||
|         for (let i = 0; i < index + 1; i++) { | ||||
| 
 | ||||
|             const deck = document.getElementById('deck'); | ||||
|             const topCard = deck.lastElementChild; | ||||
| 
 | ||||
|             if (i === index) { | ||||
|                 turnCard.apply(topCard); | ||||
|             } | ||||
| 
 | ||||
|             deck.removeChild(topCard); | ||||
|             pile.append(topCard); | ||||
|         } | ||||
| 
 | ||||
|     }); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function showTopCard(topCards, deck, deckTopCard) { | ||||
| 
 | ||||
|     if (deckTopCard.cardInfo) { | ||||
| 
 | ||||
|         deck.removeChild(deckTopCard); | ||||
|         topCards.append(deckTopCard); | ||||
|          | ||||
|         if (topCards.childElementCount > 1) { | ||||
|             topCards.childNodes[0].setAttribute('draggable', false); | ||||
|         } | ||||
| 
 | ||||
|         if (topCards.childElementCount > 2) { | ||||
|             topCards.childNodes[1].setAttribute('draggable', false); | ||||
|         } | ||||
| 
 | ||||
|         if (topCards.childElementCount > 3) { | ||||
| 
 | ||||
|             topCards.childNodes[2].setAttribute('draggable', false); | ||||
| 
 | ||||
|             const firstCard = topCards.firstElementChild; | ||||
| 
 | ||||
|             turnCardBack(firstCard); | ||||
|             firstCard.style.visibility = 'hidden'; | ||||
| 
 | ||||
|             topCards.removeChild(firstCard); | ||||
|             deck.prepend(firstCard); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function returnCardsToDeck(topCards, deck) { | ||||
| 
 | ||||
|     const cardsToDeck = []; | ||||
| 
 | ||||
|     topCards.childNodes.forEach(card => { | ||||
|         turnCardBack(card); | ||||
|         card.style.visibility = 'hidden'; | ||||
|         cardsToDeck.push(card); | ||||
|     }); | ||||
| 
 | ||||
|     cardsToDeck.forEach(card => { | ||||
|         deck.prepend(card); | ||||
|     }); | ||||
| 
 | ||||
|     topCards.innerHTML = ''; | ||||
| 
 | ||||
|     const cardsInDeck = deck.querySelectorAll('.card'); | ||||
| 
 | ||||
|     cardsInDeck.forEach(card => { | ||||
|         card.style.visibility = 'visible'; | ||||
|     }); | ||||
| 
 | ||||
|      | ||||
| } | ||||
| 
 | ||||
| function checkDeckCards() { | ||||
| 
 | ||||
|     const topCards = document.getElementById('top-cards'); | ||||
|     const deck = document.getElementById('deck'); | ||||
|     const deckTopCard = deck.lastElementChild; | ||||
| 
 | ||||
|     if (!deckTopCard) { | ||||
|         returnCardsToDeck(topCards, deck); | ||||
|     } else if (deckTopCard.style.visibility === 'hidden') { | ||||
|         returnCardsToDeck(topCards, deck); | ||||
|     } else { | ||||
|         showTopCard(topCards, deck, deckTopCard); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function changeCardPosition(cardToDrop, dropSpot, checkCondition) { | ||||
| 
 | ||||
|     if (checkCondition) { | ||||
| 
 | ||||
|         const cardAbove = cardToDrop.previousSibling; | ||||
| 
 | ||||
|         cardToDrop.parentNode.removeChild(cardToDrop); | ||||
|         dropSpot.append(cardToDrop); | ||||
| 
 | ||||
|         if (cardToDrop.cardInfo.below) { | ||||
|             cardToDrop.cardInfo.below.forEach(card => dropSpot.append(card)); | ||||
|         } | ||||
| 
 | ||||
|         return cardAbove; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function dropInRow(cardToDrop, dropSpot) { | ||||
|      | ||||
|     const cardToDropInfo = cardToDrop.cardInfo; | ||||
|     const lastCardInRow = dropSpot.lastElementChild; | ||||
|      | ||||
|     if (lastCardInRow) { | ||||
| 
 | ||||
|         const lastCardInfo = lastCardInRow.cardInfo; | ||||
| 
 | ||||
|         if (lastCardInfo && lastCardInRow.draggable) { | ||||
| 
 | ||||
|             const checkRank = lastCardInfo.rank === cardToDropInfo.higher; | ||||
|             const checkColor = lastCardInfo.color !== cardToDropInfo.color; | ||||
| 
 | ||||
|             return changeCardPosition(cardToDrop, dropSpot, (checkRank && checkColor)); | ||||
|         } | ||||
| 
 | ||||
|     } else { | ||||
| 
 | ||||
|         const checkRank = cardToDrop.cardInfo.rank === 'K'; | ||||
| 
 | ||||
|         return changeCardPosition(cardToDrop, dropSpot, checkRank); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function dropInPile(cardToDrop, dropSpot) { | ||||
| 
 | ||||
|     const cardToDropInfo = cardToDrop.cardInfo; | ||||
|     const lastCardInPile = dropSpot.lastElementChild; | ||||
| 
 | ||||
|     if (!cardToDropInfo.below) { | ||||
| 
 | ||||
|         if (lastCardInPile) { | ||||
| 
 | ||||
|             const lastCardInfo = lastCardInPile.cardInfo; | ||||
| 
 | ||||
|             if (lastCardInfo) { | ||||
| 
 | ||||
|                 const checkRank = lastCardInfo.higher === cardToDropInfo.rank; | ||||
|                 const checkSuit = lastCardInfo.suit === cardToDropInfo.suit; | ||||
| 
 | ||||
|                 if (checkRank && checkSuit) { | ||||
|                     lastCardInPile.setAttribute('draggable', false); | ||||
|                 } | ||||
| 
 | ||||
|                 return changeCardPosition(cardToDrop, dropSpot, (checkRank && checkSuit)); | ||||
| 
 | ||||
|             } else { | ||||
| 
 | ||||
|                 const checkRank = cardToDropInfo.rank === 'A'; | ||||
|                 const checkSuit = lastCardInPile.id.split('-')[0] === cardToDropInfo.suit; | ||||
| 
 | ||||
|                 return changeCardPosition(cardToDrop, dropSpot, (checkRank && checkSuit)); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function dropCard(event, cardToDrop) { | ||||
| 
 | ||||
|     const tgt = event.target; | ||||
| 
 | ||||
|     const findSpot = function (element, htmlClass) { | ||||
| 
 | ||||
|         const classList = element.classList; | ||||
| 
 | ||||
|         if (classList) { | ||||
| 
 | ||||
|             if (classList.contains(htmlClass)) { | ||||
|                 return element; | ||||
| 
 | ||||
|             } else { | ||||
|                 return findSpot(element.parentNode, htmlClass); | ||||
| 
 | ||||
|             }  | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         return; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     const dropSpot = findSpot(tgt, 'row') || findSpot(tgt, 'pile'); | ||||
| 
 | ||||
|     let cardAbove; | ||||
| 
 | ||||
|     if (dropSpot) { | ||||
| 
 | ||||
|         if (dropSpot.classList.contains('row')) { | ||||
| 
 | ||||
|             cardAbove = dropInRow(cardToDrop, dropSpot); | ||||
| 
 | ||||
|         } else if (dropSpot.classList.contains('pile')) { | ||||
| 
 | ||||
|             cardAbove = dropInPile(cardToDrop, dropSpot); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     if (cardAbove) { | ||||
|         turnCard.apply(cardAbove); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| function checkGameOver() { | ||||
| 
 | ||||
|     const piles = document.querySelectorAll('.pile'); | ||||
| 
 | ||||
|     let allPilesComplete =  true; | ||||
| 
 | ||||
|     piles.forEach(pile => { | ||||
|         allPilesComplete = allPilesComplete && (pile.childElementCount - 1) === 13; | ||||
|     }); | ||||
| 
 | ||||
|     if (allPilesComplete) { | ||||
|         alert('YOU WIN!'); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function resetSelections(card) { | ||||
| 
 | ||||
|     card.cardInfo.below = null; | ||||
|     card = null; | ||||
| 
 | ||||
|     return card; | ||||
| } | ||||
| 
 | ||||
| function dragRowCards(card) { | ||||
| 
 | ||||
|     const cardParent = card.parentNode; | ||||
|     const isLastCard = card === cardParent.lastElementChild; | ||||
| 
 | ||||
|     if (!isLastCard) { | ||||
| 
 | ||||
|         card.cardInfo.below = []; | ||||
| 
 | ||||
|         for (let i = cardParent.childElementCount - 1; i >= 0; i--) { | ||||
| 
 | ||||
|             if (cardParent.childNodes[i] === card) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             card.cardInfo.below.unshift(cardParent.childNodes[i]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| const globalDeck = createDeck(); | ||||
| const shuffledDeck = shuffleCards(globalDeck); | ||||
| putCardsInDeck(shuffledDeck); | ||||
| distributeCards(); | ||||
| 
 | ||||
| const deck = document.getElementById('deck'); | ||||
| deck.addEventListener('click', checkDeckCards); | ||||
| 
 | ||||
| const cards = document.getElementsByClassName('card'); | ||||
| for (let i = 0; i < cards.length; i++) { | ||||
|     cards[i].addEventListener('click', turnCard); | ||||
| } | ||||
| 
 | ||||
| let selectedCard = null; | ||||
| 
 | ||||
| document.addEventListener("dragstart", event => { | ||||
|     if (event.target.draggable) { | ||||
|         selectedCard = event.target; | ||||
|         dragRowCards(selectedCard); | ||||
|     } | ||||
| }); | ||||
|    | ||||
| document.addEventListener("dragover", event => { | ||||
|     event.preventDefault(); | ||||
| }, false); | ||||
| 
 | ||||
| document.addEventListener("drop", event => { | ||||
|     event.preventDefault(); | ||||
|     dropCard(event, selectedCard); | ||||
|     selectedCard = resetSelections(selectedCard); | ||||
|     checkGameOver(); | ||||
| }); | ||||
							
								
								
									
										256
									
								
								src/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								src/style.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,256 @@ | ||||
| @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&family=Poppins:wght@300;400;500;600&display=swap'); | ||||
| 
 | ||||
| html, | ||||
| body { | ||||
|   width: 100%; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
|   background-color: #f7f7f7; | ||||
|   background-color: #147246; | ||||
|   font: 400 1.2em sans-serif; | ||||
|   line-height: 1.2; | ||||
|   user-select: none; | ||||
| } | ||||
| 
 | ||||
| .container { | ||||
|   width: fit-content; | ||||
|   height: 100%; | ||||
|   margin: 0 auto; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .card { | ||||
|   padding: 0; | ||||
|   margin: 2vmin; | ||||
|   width: 7.6vmin; | ||||
|   height: 11vmin; | ||||
|   box-shadow: inset 0px 0px 1vmin 0.2vmin #c3c6c6; | ||||
|   border-radius: 0.8vmin;  | ||||
|   background-color: #f5f9fa; | ||||
|   font-family: Roboto; | ||||
| } | ||||
| 
 | ||||
| .card-rank { | ||||
|   width: 48%; | ||||
|   float: left; | ||||
|   margin-left: 0.4vmin; | ||||
|   margin-right: 0.3vmin; | ||||
|   letter-spacing: -0.8vmin; | ||||
|   font-size: 4vmin; | ||||
|   font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| .card-suit-small { | ||||
|   width: 40%; | ||||
|   float: left; | ||||
|   font-size: 4vmin; | ||||
| } | ||||
| 
 | ||||
| .card-suit-big { | ||||
|   width: 100%; | ||||
|   height: inherit; | ||||
|   line-height: 0.6; | ||||
|   font-size: 8vmin; | ||||
|   text-align: center; | ||||
| } | ||||
| 
 | ||||
| @-moz-document url-prefix() { | ||||
|   .card-rank { | ||||
|     margin-right: 0.3vmin; | ||||
|     font-size: 4vmin; | ||||
|   } | ||||
|    | ||||
|   .card-suit-small { | ||||
|     line-height: 1.6; | ||||
|     font-size: 3vmin; | ||||
|   } | ||||
|    | ||||
|   .card-suit-big { | ||||
|     line-height: 0.8; | ||||
|     font-size: 7vmin; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .card.diamond .inner-info, | ||||
| .card.heart .inner-info { | ||||
|   background: linear-gradient(to right, #c21f02, #ff2802, #c21f02, #ff2802, #c21f02); | ||||
|   -webkit-background-clip: text; | ||||
|   color: transparent; | ||||
| } | ||||
| 
 | ||||
| .card.club .inner-info, | ||||
| .card.spade .inner-info { | ||||
|   background: linear-gradient(to right, #242222, #534f51, #242222, #534f51, #242222); | ||||
|   -webkit-background-clip: text; | ||||
|   color: transparent; | ||||
| } | ||||
| 
 | ||||
| .back { | ||||
|   box-shadow: inset 0px 0px 0.2vmin 0.2vmin #0a2f41; | ||||
|   background: linear-gradient(315deg, #242222, #534f51, #242222, #534f51, #242222); | ||||
|   background: linear-gradient(315deg, #0a3142, #104c66, #12506b, #1b7ca5, #2195ca); | ||||
| } | ||||
| 
 | ||||
| .top-area { | ||||
|   padding-top: 2vmin; | ||||
|   width: 100vw; | ||||
|   height: 16vmin; | ||||
|   background-color: #1b4934; | ||||
| } | ||||
| 
 | ||||
| .left-area, | ||||
| .right-area { | ||||
|   display: flex; | ||||
|   place-content: center; | ||||
|   float: left; | ||||
| } | ||||
| 
 | ||||
| .left-area { | ||||
|   width: 41vmin; | ||||
| } | ||||
| 
 | ||||
| .right-area { | ||||
|   width: 57vmin; | ||||
| } | ||||
| 
 | ||||
| .deck { | ||||
|   margin: 2vmin; | ||||
|   width: 7.6vmin; | ||||
|   height: 11vmin; | ||||
|   box-shadow: inset 0px 0px 0vmin 0.5vmin #c3c6c644; | ||||
|   border-radius: 0.8vmin; | ||||
|   background-color: #c3c6c60c; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .deck::before { | ||||
|   content: "⟲"; | ||||
|   width: 100%; | ||||
|   height: inherit; | ||||
|   line-height: 1.6; | ||||
|   font-size: 7vmin; | ||||
|   text-align: center; | ||||
|   color: #c3c6c644; | ||||
|   position: absolute; | ||||
|   cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| .deck .card { | ||||
|   position: absolute; | ||||
|   transform: translateX(-2vmin) translateY(-2vmin); | ||||
|   cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| .top-cards { | ||||
|   width: 55%; | ||||
|   display: flex; | ||||
| } | ||||
| 
 | ||||
| .top-cards .card { | ||||
|   margin-right: -5vmin; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .pile { | ||||
|   padding: 0; | ||||
|   margin: 2vmin; | ||||
|   width: 7.6vmin; | ||||
|   height: 11vmin; | ||||
|   box-shadow: inset 0px 0px 0vmin 0.5vmin #c3c6c644; | ||||
|   border-radius: 0.8vmin; | ||||
|   background-color: #c3c6c60c; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .pile span { | ||||
|   width: 100%; | ||||
|   height: inherit; | ||||
|   line-height: 1.4; | ||||
|   font-size: 8vmin; | ||||
|   text-align: center; | ||||
|   color: #c3c6c644; | ||||
|   position: absolute; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .pile .card { | ||||
|   position: absolute; | ||||
|   transform: translateX(-2vmin) translateY(-2vmin); | ||||
| } | ||||
| 
 | ||||
| .bottom-area { | ||||
|   display: flex; | ||||
|   place-content: center; | ||||
|   width: 100vmin; | ||||
|   min-height: 100%; | ||||
|   height: fit-content; | ||||
|   padding-top: 4vmin; | ||||
|   padding-bottom: 10vmin; | ||||
| } | ||||
| 
 | ||||
| .row { | ||||
|   display: grid; | ||||
|   margin-right: 1%; | ||||
|   width: 12%; | ||||
|   height: 100%; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .row::before { | ||||
|   content: ""; | ||||
|   width: 7.6vmin; | ||||
|   height: 11vmin; | ||||
|   box-shadow: inset 0px 0px 0vmin 0.5vmin #c3c6c644; | ||||
|   border-radius: 0.8vmin; | ||||
|   background-color: #c3c6c60c; | ||||
|   transform: translateX(2vmin) translateY(2vmin); | ||||
|   position: absolute; | ||||
| } | ||||
| 
 | ||||
| .row .card { | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .row .card:not(:first-child) { | ||||
|   margin-top: -8vmin; | ||||
| } | ||||
| 
 | ||||
| footer { | ||||
|   position: fixed; | ||||
|   bottom: 0; | ||||
|   width: 100%; | ||||
|   height: fit-content; | ||||
|   margin-top: 25vmin; | ||||
|   padding: 1vmin 0; | ||||
|   background-color: #1e1f26; | ||||
|   font-size: 1.6vmin; | ||||
| } | ||||
| 
 | ||||
| footer p { | ||||
|   margin: 1vmin; | ||||
|   text-align: center; | ||||
|   color: #F5F5F5; | ||||
|   font-family: Poppins; | ||||
| } | ||||
| 
 | ||||
| footer a:link { | ||||
|   color: #b3a290; | ||||
| } | ||||
| footer a:visited { | ||||
|   color: #91d4d0; | ||||
| } | ||||
| footer a:hover { | ||||
|   color: #ff3300; | ||||
| } | ||||
| footer a:active { | ||||
|   color: #ff3300; | ||||
| } | ||||
| 
 | ||||
| .name-dark { | ||||
|   color: #91d4d0; | ||||
|   text-decoration: none; | ||||
|   background: linear-gradient(to right, #91d4d0 50%, #ff3300 100%); | ||||
|   -webkit-background-clip: text; | ||||
|   -webkit-text-fill-color: transparent; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jessica Guarato
						Jessica Guarato