diff --git a/src/common/header/header.css b/src/common/header/header.css index 8324afb537..19c8f4cc20 100644 --- a/src/common/header/header.css +++ b/src/common/header/header.css @@ -283,8 +283,8 @@ .header-links > li > .app-header-btn.app-header-btn--secondary:hover, .header-links > li > .app-header-btn.app-header-btn--secondary:focus { -border-color: var(--color-brand-primary); -background-color: var(--color-neutral-10); + border-color: var(--color-brand-primary); + background-color: var(--color-neutral-10); } .header-links > li > .app-header-btn.app-header-btn--secondary { diff --git a/src/common/playleaderboard/leaderBoard.css b/src/common/playleaderboard/leaderBoard.css index bab6f4799f..9fed5cd318 100644 --- a/src/common/playleaderboard/leaderBoard.css +++ b/src/common/playleaderboard/leaderBoard.css @@ -37,158 +37,157 @@ justify-content: center; height: 100vh; } */ - + .leaderboard-wrapper { - background-color: #ffffff; - border-radius: 16px; - padding: 24px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); - font-family: 'Inter', sans-serif; - max-width: 800px; - margin: 20px auto; - } - - .leaderboard-title { - font-size: 24px; - font-weight: 600; - color: #1a202c; - margin-bottom: 24px; - } - - .podium-container { - display: flex; - justify-content: center; - align-items: flex-end; - gap: 8px; - margin-bottom: 16px; - } - - .podium-card { - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - padding: 16px; - border-radius: 12px; - width: 120px; - color: #4a5568; - border: 1px solid #e2e8f0; - transition: transform 0.2s ease-in-out; - } - - .podium-card:hover { - transform: translateY(-5px); - } - - .podium-avatar { - width: 60px; - height: 60px; - border-radius: 50%; - border: 3px solid #fff; - box-shadow: 0 2px 4px rgba(0,0,0,0.1); - margin-bottom: 8px; - } - - .podium-name { - font-weight: 600; - font-size: 14px; - color: #2d3748; - } - - .podium-rank { - font-size: 12px; - font-weight: 500; - margin-bottom: 4px; - } - - .podium-points { - font-weight: 700; - font-size: 14px; - color: #1a202c; - } - - .podium-second { - background-color: #f7fafc; - height: 170px; - order: 1; - } - - .podium-first { - background-color: #fffbef; - height: 200px; - border-color: #f6e05e; - order: 2; - } - - .podium-third { - background-color: #fdf5f2; - height: 150px; - order: 3; - } - - .winner-announcement { - text-align: center; - color: #4a5568; - font-size: 14px; - margin-bottom: 32px; - line-height: 1.5; - } - + background-color: #ffffff; + border-radius: 16px; + padding: 24px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); + font-family: 'Inter', sans-serif; + max-width: 800px; + margin: 20px auto; +} - .leaderboard-table-container { - box-shadow: none !important; - border: 1px solid #e2e8f0; - border-radius: 12px !important; - } - - .leaderboard-table-header { - font-weight: 600 !important; - font-size: 12px !important; - color: #718096 !important; - text-transform: uppercase; - background-color: #f7fafc !important; - border-bottom: 1px solid #e2e8f0 !important; - } - - .leaderboard-table-cell { - font-size: 14px !important; - color: #2d3748 !important; - border-bottom: 1px solid #e2e8f0 !important; - } - - .user-profile { - display: flex; - align-items: center; - gap: 12px; - font-weight: 500; - } - - .table-avatar { - width: 32px; - height: 32px; - border-radius: 50%; - } - - .rank-cell { - display: flex; - align-items: center; - gap: 8px; - font-weight: 600 !important; - } - - .points-cell { - font-weight: 600 !important; - } - - .rank-icon { - font-size: 16px !important; - } - .rank-up { - color: #38a169; - } - .rank-down { - color: #e53e3e; - } - .rank-same { - color: #a0aec0; - } \ No newline at end of file +.leaderboard-title { + font-size: 24px; + font-weight: 600; + color: #1a202c; + margin-bottom: 24px; +} + +.podium-container { + display: flex; + justify-content: center; + align-items: flex-end; + gap: 8px; + margin-bottom: 16px; +} + +.podium-card { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: 16px; + border-radius: 12px; + width: 120px; + color: #4a5568; + border: 1px solid #e2e8f0; + transition: transform 0.2s ease-in-out; +} + +.podium-card:hover { + transform: translateY(-5px); +} + +.podium-avatar { + width: 60px; + height: 60px; + border-radius: 50%; + border: 3px solid #fff; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + margin-bottom: 8px; +} + +.podium-name { + font-weight: 600; + font-size: 14px; + color: #2d3748; +} + +.podium-rank { + font-size: 12px; + font-weight: 500; + margin-bottom: 4px; +} + +.podium-points { + font-weight: 700; + font-size: 14px; + color: #1a202c; +} + +.podium-second { + background-color: #f7fafc; + height: 170px; + order: 1; +} + +.podium-first { + background-color: #fffbef; + height: 200px; + border-color: #f6e05e; + order: 2; +} + +.podium-third { + background-color: #fdf5f2; + height: 150px; + order: 3; +} + +.winner-announcement { + text-align: center; + color: #4a5568; + font-size: 14px; + margin-bottom: 32px; + line-height: 1.5; +} + +.leaderboard-table-container { + box-shadow: none !important; + border: 1px solid #e2e8f0; + border-radius: 12px !important; +} + +.leaderboard-table-header { + font-weight: 600 !important; + font-size: 12px !important; + color: #718096 !important; + text-transform: uppercase; + background-color: #f7fafc !important; + border-bottom: 1px solid #e2e8f0 !important; +} + +.leaderboard-table-cell { + font-size: 14px !important; + color: #2d3748 !important; + border-bottom: 1px solid #e2e8f0 !important; +} + +.user-profile { + display: flex; + align-items: center; + gap: 12px; + font-weight: 500; +} + +.table-avatar { + width: 32px; + height: 32px; + border-radius: 50%; +} + +.rank-cell { + display: flex; + align-items: center; + gap: 8px; + font-weight: 600 !important; +} + +.points-cell { + font-weight: 600 !important; +} + +.rank-icon { + font-size: 16px !important; +} +.rank-up { + color: #38a169; +} +.rank-down { + color: #e53e3e; +} +.rank-same { + color: #a0aec0; +} diff --git a/src/common/playlists/playlist.css b/src/common/playlists/playlist.css index 4b90f9f7fc..fccc439833 100644 --- a/src/common/playlists/playlist.css +++ b/src/common/playlists/playlist.css @@ -351,7 +351,7 @@ margin-top: 0.4rem; padding-top: 0.4rem; } - .header-rightcol{ + .header-rightcol { max-width: 95%; } diff --git a/src/common/techstack/TechStacks.css b/src/common/techstack/TechStacks.css index f0cd91ce9b..3fcd7cbfbd 100644 --- a/src/common/techstack/TechStacks.css +++ b/src/common/techstack/TechStacks.css @@ -180,4 +180,4 @@ .tech-brand-name { font-size: 1.5rem; } -} \ No newline at end of file +} diff --git a/src/plays/Selection-Sort-Visualizer/select.css b/src/plays/Selection-Sort-Visualizer/select.css index a1ad33ff24..b54eb0a5a5 100644 --- a/src/plays/Selection-Sort-Visualizer/select.css +++ b/src/plays/Selection-Sort-Visualizer/select.css @@ -1,96 +1,97 @@ /* Scoped styles for the Selection Sort Visualizer */ .visualizer-body { - background-color: papayawhip; - } - - .visualizer-container * { - font-size: 16px; - font-weight: bold; - font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; - } - - .visualizer-head { - margin-top: 20px; - margin-right: 20vw; - margin-left: 20vw; - text-align: center; - font-size: 30px; - background-color: greenyellow; - color: white; - border-radius: 19px; - font-weight: bolder; - } - - .visualizer-input-container { - display: flex; - flex-direction: row; - margin: 2rem 5rem; - } - - .input-field { - width: 180px; - height: 40px; - border: 1px solid black; - border-radius: 5px; - outline: none; - text-align: center; - } - - .button-blue, - .button-green { - width: 100px; - text-align: center; - margin-left: 10px; - border: 1px solid black; - border-radius: 5px; - height: 40px; - color: white; - } - - .button-green { - background-color: #4cd430; - } - - .button-blue { - background-color: #3478d5; - } - - #input-visualizer { - margin: 0 5rem; - margin-top: 2rem; - display: flex; - text-align: center; - } - - #input-visualizer div { - margin-right: 10px; - background-color: #e6852c; - border: 1px solid black; - border-radius: 5px; - padding: 10px; - width: 50px; - color: white; - } - - #output-visualizer { - display: flex; - flex-direction: column; - } - - #output-visualizer div { - margin: 0 5rem; - margin-top: 2rem; - display: flex; - text-align: center; - } - - #output-visualizer div span { - margin-right: 10px; - background-color: #3478d5; - border: 1px solid black; - border-radius: 5px; - padding: 10px; - width: 50px; - color: white; - } - + background-color: papayawhip; +} + +.visualizer-container * { + font-size: 16px; + font-weight: bold; + font-family: + 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, + sans-serif; +} + +.visualizer-head { + margin-top: 20px; + margin-right: 20vw; + margin-left: 20vw; + text-align: center; + font-size: 30px; + background-color: greenyellow; + color: white; + border-radius: 19px; + font-weight: bolder; +} + +.visualizer-input-container { + display: flex; + flex-direction: row; + margin: 2rem 5rem; +} + +.input-field { + width: 180px; + height: 40px; + border: 1px solid black; + border-radius: 5px; + outline: none; + text-align: center; +} + +.button-blue, +.button-green { + width: 100px; + text-align: center; + margin-left: 10px; + border: 1px solid black; + border-radius: 5px; + height: 40px; + color: white; +} + +.button-green { + background-color: #4cd430; +} + +.button-blue { + background-color: #3478d5; +} + +#input-visualizer { + margin: 0 5rem; + margin-top: 2rem; + display: flex; + text-align: center; +} + +#input-visualizer div { + margin-right: 10px; + background-color: #e6852c; + border: 1px solid black; + border-radius: 5px; + padding: 10px; + width: 50px; + color: white; +} + +#output-visualizer { + display: flex; + flex-direction: column; +} + +#output-visualizer div { + margin: 0 5rem; + margin-top: 2rem; + display: flex; + text-align: center; +} + +#output-visualizer div span { + margin-right: 10px; + background-color: #3478d5; + border: 1px solid black; + border-radius: 5px; + padding: 10px; + width: 50px; + color: white; +} diff --git a/src/plays/codenchill/Readme.md b/src/plays/codenchill/Readme.md index 459a56951d..b211cad3ec 100644 --- a/src/plays/codenchill/Readme.md +++ b/src/plays/codenchill/Readme.md @@ -9,7 +9,6 @@ - It comes with a bunch of features with a seamless User Experience and an elegant design for both mobile and desktop. - The following are the features of the tool: - - You can easily play, pause , and shuffle your lo-fi tracks, and adjust the volume or mute the audio with just one click. - You can set the timer in three fixed tabs - Rest, Work and Focus , or even set a custom timer to fit your specific needs. Once you turn on the timer, you can see it in the title of your browser tab. @@ -48,5 +47,4 @@ ## Resources - Have installed one node module for implementing the download feature: - - `redux-toolkit` module diff --git a/src/plays/daily-journa/Readme.md b/src/plays/daily-journa/Readme.md index a1bfca02bc..4f59404709 100644 --- a/src/plays/daily-journa/Readme.md +++ b/src/plays/daily-journa/Readme.md @@ -11,8 +11,8 @@ This play is about writing daily entries, categorising them by mood or topic, an - User: GhadaRV - Gihub Link: https://github.com/GhadaRV -- Blog: -- Video: +- Blog: +- Video: ## Implementation Details diff --git a/src/plays/dictionary/Readme.md b/src/plays/dictionary/Readme.md index ad215b77fc..54c581fdff 100644 --- a/src/plays/dictionary/Readme.md +++ b/src/plays/dictionary/Readme.md @@ -14,7 +14,7 @@ Display the definition, pronunciation, antonyms and synonyms of the word ## Implementation Details -This implenmetation uses axios to call a remote API. The remote API returns the meaning as well as synonyms and antonyms of the word entered by the user, which is rendered. +This implenmetation uses axios to call a remote API. The remote API returns the meaning as well as synonyms and antonyms of the word entered by the user, which is rendered. ## Consideration diff --git a/src/plays/emojipedia/readme.md b/src/plays/emojipedia/readme.md index a406e7803a..20e4bb86a2 100644 --- a/src/plays/emojipedia/readme.md +++ b/src/plays/emojipedia/readme.md @@ -26,7 +26,6 @@ Emojipedia is a fun project play where users can search for any emojis and can c - The implementation is quite simple. In this project, I've used [Open Emoji API](https://emoji-api.com/). - There are basically three main components: - - `Emojipedia`: As the name suggests it is an entry point of the project. - `EmojiCard`: It is responsible for rendering Emoji characters and their Unicode name in the card format. - `SkeletonCard`: This component is an animated placeholder that simulates the layout of a page while data is being loaded. diff --git a/src/plays/random-quote-card-generator/Readme.md b/src/plays/random-quote-card-generator/Readme.md index d2e0dbe2fa..6a7fd116ca 100644 --- a/src/plays/random-quote-card-generator/Readme.md +++ b/src/plays/random-quote-card-generator/Readme.md @@ -7,7 +7,6 @@ - This tool can be used in real life for social media posts/stories. - Customizations available: - - Editing the background color of container from the available gradients - Editing the Quote Card color (Dark/Light) - Changing the aspect ratio ( 2 options available): diff --git a/src/plays/random-quotes/RandomQuotes.js b/src/plays/random-quotes/RandomQuotes.js new file mode 100644 index 0000000000..501b429ed0 --- /dev/null +++ b/src/plays/random-quotes/RandomQuotes.js @@ -0,0 +1,285 @@ +import React, { useState, useEffect } from 'react'; +import PlayHeader from 'common/playlists/PlayHeader'; +import './styles.css'; + +// WARNING: Do not change the entry component name +function RandomQuotes(props) { + const [quote, setQuote] = useState(''); + const [author, setAuthor] = useState(''); + const [category, setCategory] = useState('motivational'); + const [loading, setLoading] = useState(false); + + // Reliable category tags (quotable.io) + const categories = { + motivational: 'motivational', + life: 'life', + programming: 'technology' + }; + + // Local fallback quotes — EXPANDED LIST + const localFallback = { + motivational: [ + { content: 'The only way to do great work is to love what you do.', author: 'Steve Jobs' }, + { content: "Believe you can and you're halfway there.", author: 'Theodore Roosevelt' }, + { content: 'Don’t watch the clock; do what it does. Keep going.', author: 'Sam Levenson' }, + { + content: + 'Success is not final; failure is not fatal: It is the courage to continue that counts.', + author: 'Winston Churchill' + }, + { + content: 'Push yourself because no one else is going to do it for you.', + author: 'Unknown' + }, + { content: 'Dream bigger. Do bigger.', author: 'Unknown' }, + { + content: 'You don’t have to be great to start, but you have to start to be great.', + author: 'Zig Ziglar' + }, + { content: 'Hard work beats talent when talent doesn’t work hard.', author: 'Tim Notke' }, + { content: 'If opportunity doesn’t knock, build a door.', author: 'Milton Berle' }, + { + content: 'Discipline is choosing between what you want now and what you want most.', + author: 'Abraham Lincoln' + }, + { content: 'Don’t limit your challenges—challenge your limits.', author: 'Jerry Dunn' }, + { content: 'It always seems impossible until it’s done.', author: 'Nelson Mandela' }, + { content: 'Make each day your masterpiece.', author: 'John Wooden' }, + { content: 'A little progress each day adds up to big results.', author: 'Satya Nani' }, + { + content: 'Do something today that your future self will thank you for.', + author: 'Sean Patrick Flanery' + } + ], + + life: [ + { + content: "Life is what happens when you're busy making other plans.", + author: 'John Lennon' + }, + { content: 'Keep smiling, because life is a beautiful thing.', author: 'Marilyn Monroe' }, + { content: 'The purpose of our lives is to be happy.', author: 'Dalai Lama' }, + { + content: + "In the end, it's not the years in your life that count. It's the life in your years.", + author: 'Abraham Lincoln' + }, + { + content: 'Life is really simple, but we insist on making it complicated.', + author: 'Confucius' + }, + { + content: 'Good friends, good books, and a sleepy conscience: this is the ideal life.', + author: 'Mark Twain' + }, + { + content: 'To live is the rarest thing in the world. Most people exist, that is all.', + author: 'Oscar Wilde' + }, + { + content: 'Life isn’t about finding yourself. It’s about creating yourself.', + author: 'George Bernard Shaw' + }, + { + content: 'Happiness is not something ready-made. It comes from your own actions.', + author: 'Dalai Lama' + }, + { + content: 'You only live once, but if you do it right, once is enough.', + author: 'Mae West' + }, + { + content: 'Difficulties in life are intended to make us better, not bitter.', + author: 'Dan Reeves' + }, + { + content: 'The biggest adventure you can take is to live the life of your dreams.', + author: 'Oprah Winfrey' + }, + { + content: + 'Enjoy the little things, for one day you may look back and realize they were the big things.', + author: 'Robert Brault' + }, + { + content: 'Life itself is the most wonderful fairy tale.', + author: 'Hans Christian Andersen' + }, + { content: 'In the book of life, the answers aren’t in the back.', author: 'Charlie Brown' } + ], + + programming: [ + { content: 'Talk is cheap. Show me the code.', author: 'Linus Torvalds' }, + { + content: + 'Programs must be written for people to read, and only incidentally for machines to execute.', + author: 'Harold Abelson' + }, + { content: 'First, solve the problem. Then, write the code.', author: 'John Johnson' }, + { + content: 'Experience is the name everyone gives to their mistakes.', + author: 'Oscar Wilde' + }, + { + content: 'Code is like humor. When you have to explain it, it’s bad.', + author: 'Cory House' + }, + { content: 'Fix the cause, not the symptom.', author: 'Steve Maguire' }, + { + content: 'Optimism is an occupational hazard of programming: feedback is the treatment.', + author: 'Kent Beck' + }, + { content: 'Simplicity is the soul of efficiency.', author: 'Austin Freeman' }, + { + content: 'Before software can be reusable it first has to be usable.', + author: 'Ralph Johnson' + }, + { + content: 'Programming isn’t about what you know; it’s about what you can figure out.', + author: 'Chris Pine' + }, + { content: 'The best error message is the one that never shows up.', author: 'Thomas Fuchs' }, + { content: 'You can’t have great software without a great team.', author: 'Martin Fowler' }, + { content: 'Make it work, make it right, make it fast.', author: 'Kent Beck' }, + { + content: + 'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.', + author: 'Martin Fowler' + }, + { + content: 'The function of good software is to make the complex appear simple.', + author: 'Grady Booch' + } + ], + + general: [ + { content: 'Don’t watch the clock; do what it does. Keep going.', author: 'Sam Levenson' }, + { content: 'Simplicity is the soul of efficiency.', author: 'Austin Freeman' }, + { content: 'Everything you can imagine is real.', author: 'Pablo Picasso' }, + { + content: 'Whether you think you can or you think you can’t, you’re right.', + author: 'Henry Ford' + } + ] + }; + + const fetchWithTimeout = async (url, timeout = 7000) => { + const controller = new AbortController(); + const id = setTimeout(() => controller.abort(), timeout); + try { + const res = await fetch(url, { signal: controller.signal }); + clearTimeout(id); + + return res; + } catch (err) { + clearTimeout(id); + + throw err; + } + }; + + const fetchQuote = async () => { + setLoading(true); + const tag = categories[category] || ''; + const taggedUrl = tag ? `https://api.quotable.io/random?tags=${encodeURIComponent(tag)}` : null; + const generalUrl = 'https://api.quotable.io/random'; + + try { + let data; + + if (taggedUrl) { + try { + const res = await fetchWithTimeout(taggedUrl); + if (!res.ok) throw new Error(); + data = await res.json(); + } catch { + console.warn('Tagged fetch failed, trying general endpoint'); + } + } + + if (!data) { + try { + const res = await fetchWithTimeout(generalUrl); + if (!res.ok) throw new Error(); + data = await res.json(); + } catch { + console.warn('General fetch failed'); + } + } + + if (data && data.content) { + setQuote(data.content); + setAuthor(data.author || 'Unknown'); + } else { + const pool = localFallback[category] || localFallback.general; + const random = pool[Math.floor(Math.random() * pool.length)]; + setQuote(random.content); + setAuthor(random.author); + } + } catch (err) { + console.error('Unexpected fetch error:', err); + const pool = localFallback[category] || localFallback.general; + const random = pool[Math.floor(Math.random() * pool.length)]; + setQuote(random.content); + setAuthor(random.author); + } finally { + setLoading(false); + } + }; + + const speakQuote = () => { + if (!quote || !window.speechSynthesis) return; + const utter = new SpeechSynthesisUtterance(`${quote} — ${author}`); + window.speechSynthesis.cancel(); + window.speechSynthesis.speak(utter); + }; + + useEffect(() => { + fetchQuote(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [category]); + + return ( +
+ +
+
+

✨ Enhanced Random Quote Generator ✨

+ +
+ + + + + +
+ +
+ {loading ? ( +

Loading...

+ ) : ( + <> +

“{quote}”

+

— {author}

+ + )} +
+
+
+
+ ); +} + +export default RandomQuotes; diff --git a/src/plays/random-quotes/Readme.md b/src/plays/random-quotes/Readme.md new file mode 100644 index 0000000000..80d3ca81cd --- /dev/null +++ b/src/plays/random-quotes/Readme.md @@ -0,0 +1,64 @@ +# Random Quotes + +An enhanced Random Quote Generator built using React. It allows users to generate motivational, life, and programming quotes with category selection and text-to-speech support for accessibility. + +## Play Demographic + +- Language: js +- Level: Intermediate + +## Creator Information + +- User: rajnishpatell +- Gihub Link: https://github.com/rajnishpatell +- Blog: +- Video: + +## Implementation Details + +The Enhanced Random Quote Generator is a React-based interactive project that displays motivational, life, and programming quotes dynamically. Users can switch categories, generate new quotes, and even listen to them using text-to-speech functionality. + +⚙️ Core Features + +Dynamic Quote Fetching: Fetches quotes from the Quotable API + based on the selected category (motivational, life, or programming). + +Offline Fallback: Includes a local quote dataset to ensure the app works even if the API request fails. + +Category Selection: Users can easily switch between categories using a dropdown menu. + +Text-to-Speech: Integrated browser speech synthesis to read quotes aloud for accessibility. + +Modern UI/UX Design: Styled using custom CSS with a gradient background, glassmorphism effect, and responsive layout. + +Error Handling & Retry: Automatically falls back to a general quote or local list when the API fails, ensuring smooth user experience. + +Loading State: Displays a loading message while fetching new quotes. + +🛠️ Tech Stack + +Frontend: React.js (Functional Components + Hooks) + +Styling: Custom CSS (responsive + animations) + +APIs: Quotable.io API + +Speech: Web Speech API (Text-to-Speech) + +Tools: npm, Vite (via ReactPlay environment) + +## Consideration + +The app uses the Quotable API, but also includes a local fallback quote list to ensure it works offline or if the API request fails. + +Text-to-Speech (TTS) relies on the browser’s built-in SpeechSynthesis API, which may behave slightly differently across browsers. + +Quotes are categorized into Motivational, Life, and Programming to give users a more focused experience. + +The design follows ReactPlay contribution guidelines and uses component-based structure for easy maintenance. + +Accessibility and simplicity were prioritized, ensuring the UI works well on both desktop and mobile devices. + +## Resources + +Update external resources(if any) diff --git a/src/plays/random-quotes/cover.jpg.jpeg b/src/plays/random-quotes/cover.jpg.jpeg new file mode 100644 index 0000000000..541396acd9 Binary files /dev/null and b/src/plays/random-quotes/cover.jpg.jpeg differ diff --git a/src/plays/random-quotes/styles.css b/src/plays/random-quotes/styles.css new file mode 100644 index 0000000000..6abfc805b0 --- /dev/null +++ b/src/plays/random-quotes/styles.css @@ -0,0 +1,152 @@ +/* General layout */ +.rq-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: 80vh; + background: linear-gradient(135deg, #667eea, #764ba2); + color: #fff; + font-family: "Poppins", sans-serif; + padding: 2rem; + border-radius: 20px; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.25); + transition: all 0.3s ease; +} + +.rq-title { + font-size: 2.2rem; + font-weight: 700; + text-align: center; + margin-bottom: 1.5rem; + letter-spacing: 1px; + color: #f9fafb; +} + +/* Control section */ +.rq-controls { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 0.8rem; + margin-bottom: 2rem; +} + +.rq-select { + padding: 0.7rem 1rem; + border: none; + border-radius: 8px; + background: rgba(255, 255, 255, 0.9); + color: #333; + font-size: 1rem; + font-weight: 500; + outline: none; + cursor: pointer; + transition: 0.3s; +} + +.rq-select:hover { + background: #f8fafc; +} + +.rq-btn { + background: #ffffff; + color: #333; + padding: 0.7rem 1.3rem; + font-size: 1rem; + font-weight: 600; + border-radius: 8px; + border: none; + cursor: pointer; + transition: all 0.3s ease-in-out; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); +} + +.rq-btn:hover { + background: #4f46e5; + color: #fff; + transform: translateY(-2px); +} + +.rq-speak { + background: #22c55e; + color: #fff; +} + +.rq-speak:hover { + background: #16a34a; +} + +/* Quote display */ +.rq-quote-box { + background: rgba(255, 255, 255, 0.15); + padding: 2rem; + border-radius: 15px; + backdrop-filter: blur(10px); + width: 90%; + max-width: 700px; + text-align: center; + transition: all 0.3s ease-in-out; + animation: fadeIn 0.6s ease; +} + +.rq-text { + font-size: 1.4rem; + line-height: 1.6; + margin-bottom: 1rem; + font-weight: 500; + color: #fefefe; + transition: 0.3s; +} + +.rq-author { + font-size: 1.1rem; + color: #d1d5db; + font-style: italic; + margin-top: 0.5rem; +} + +/* Loading text */ +.rq-loading { + font-size: 1.2rem; + color: #f9fafb; + font-style: italic; +} + +/* Subtle fade animation */ +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(15px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Responsive tweaks */ +@media (max-width: 600px) { + .rq-container { + padding: 1.5rem; + border-radius: 10px; + } + + .rq-title { + font-size: 1.6rem; + } + + .rq-text { + font-size: 1.1rem; + } + + .rq-controls { + flex-direction: column; + } + + .rq-btn, + .rq-select { + width: 100%; + text-align: center; + } +} diff --git a/src/plays/simple-todo-app/Readme.md b/src/plays/simple-todo-app/Readme.md index 6d8b5faf78..42d12fe404 100644 --- a/src/plays/simple-todo-app/Readme.md +++ b/src/plays/simple-todo-app/Readme.md @@ -11,8 +11,8 @@ A productivity-focused Todo app built with React + TypeScript. Capture tasks, ke - User: efebaslilar - Gihub Link: https://github.com/efebaslilar -- Blog: -- Video: +- Blog: +- Video: ## Implementation Details diff --git a/src/plays/simple-todo-app/styles.css b/src/plays/simple-todo-app/styles.css index 91b86dbdfc..7fb22ceb3f 100644 --- a/src/plays/simple-todo-app/styles.css +++ b/src/plays/simple-todo-app/styles.css @@ -13,8 +13,8 @@ gap: 0.75rem; margin-bottom: 1.25rem; } -.play-description{ - text-align: center; +.play-description { + text-align: center; } .todo-form input { @@ -24,7 +24,9 @@ border: 1px solid #cbd5f5; border-radius: 12px; background: #ffffff; - transition: border 0.2s ease, box-shadow 0.2s ease; + transition: + border 0.2s ease, + box-shadow 0.2s ease; } .todo-form input:focus { @@ -41,7 +43,9 @@ background: #6366f1; color: #f8fafc; cursor: pointer; - transition: background 0.2s ease, transform 0.1s ease; + transition: + background 0.2s ease, + transform 0.1s ease; } .todo-form button:hover { @@ -99,7 +103,10 @@ font-size: 0.85rem; font-weight: 500; cursor: pointer; - transition: background 0.2s ease, color 0.2s ease, border 0.2s ease; + transition: + background 0.2s ease, + color 0.2s ease, + border 0.2s ease; } .todo-filters button.active { @@ -144,7 +151,9 @@ border-radius: 12px; background: #fff; box-shadow: 0 4px 15px -12px rgba(15, 23, 42, 0.5); - transition: transform 0.2s ease, box-shadow 0.2s ease; + transition: + transform 0.2s ease, + box-shadow 0.2s ease; } .todo-item:hover { @@ -192,7 +201,10 @@ cursor: pointer; padding: 0.35rem 0.65rem; border-radius: 8px; - transition: background 0.2s ease, color 0.2s ease, transform 0.1s ease; + transition: + background 0.2s ease, + color 0.2s ease, + transform 0.1s ease; } .todo-item-actions button:hover { @@ -211,7 +223,9 @@ border: 1px solid #cbd5f5; background: #ffffff; font-size: 0.95rem; - transition: border 0.2s ease, box-shadow 0.2s ease; + transition: + border 0.2s ease, + box-shadow 0.2s ease; } .todo-edit-input:focus { @@ -221,7 +235,8 @@ } .todo-item.editing { - box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.18), + box-shadow: + 0 0 0 2px rgba(99, 102, 241, 0.18), 0 18px 30px -22px rgba(15, 23, 42, 0.55); } diff --git a/src/plays/steps/Readme.md b/src/plays/steps/Readme.md index 2b14a4dddc..e69d0ef886 100644 --- a/src/plays/steps/Readme.md +++ b/src/plays/steps/Readme.md @@ -12,7 +12,7 @@ A web app with “next” and “previous” navigation buttons, where the “ne - User: aaqib605 - Gihub Link: https://github.com/aaqib605 - Blog: https://hashnode.com/@aaqib605 -- Video: +- Video: ## Implementation Details diff --git a/src/plays/tenzies-game/Readme.md b/src/plays/tenzies-game/Readme.md index 9125a621b1..b09071e18e 100644 --- a/src/plays/tenzies-game/Readme.md +++ b/src/plays/tenzies-game/Readme.md @@ -23,7 +23,6 @@ Tenzies is a dice roll game where you have to roll the dice until all dice are t - The implementation is quite simple. In this project, I use simple react concepts like `useState`, `useEffect`, `onClick` etc... - There are basically two main components: - - `Dice`: As the name suggests it is 10 dice box components that shows the number Between `1` to `6`. - `Main`: It is responsible for rendering dice components and handle all function Which is use to run the Game. diff --git a/src/plays/text-to-speech/styles.css b/src/plays/text-to-speech/styles.css index a11dff07f3..adc01c6b9a 100644 --- a/src/plays/text-to-speech/styles.css +++ b/src/plays/text-to-speech/styles.css @@ -29,7 +29,9 @@ font-size: 18px; resize: vertical; outline: none; - transition: border 0.2s, box-shadow 0.2s; + transition: + border 0.2s, + box-shadow 0.2s; } .tts-textarea:focus { @@ -46,7 +48,9 @@ font-weight: 600; font-size: 18px; cursor: pointer; - transition: background 0.3s ease, transform 0.1s; + transition: + background 0.3s ease, + transform 0.1s; } .tts-convert-btn:hover { @@ -90,7 +94,9 @@ background: #3b82f6; color: white; cursor: pointer; - transition: background 0.2s, transform 0.1s; + transition: + background 0.2s, + transform 0.1s; display: flex; align-items: center; justify-content: center; @@ -163,7 +169,7 @@ gap: 4px; } -.tts-sliders input[type="range"] { +.tts-sliders input[type='range'] { width: 100%; cursor: pointer; } diff --git a/src/plays/typing-speed-test/readme.md b/src/plays/typing-speed-test/readme.md index cb102d7e66..52adceadf7 100644 --- a/src/plays/typing-speed-test/readme.md +++ b/src/plays/typing-speed-test/readme.md @@ -52,7 +52,6 @@ The implementation of the Typing Speed Test project is quite simple. - Additionally, there is a `ResultModal` component that opens when the time is up or the user finishes typing all the words. This modal renders the statistics of the typing session, providing a summary of the user’s performance. - ## Contributing First of all thanks for wanting to contribute! To start contributing to this play, please go through the [Contribution guidelines of ReactPlay](https://github.com/reactplay/react-play/blob/main/CONTRIBUTING.md).