From 48bd06681984e99065d43e9b0a894a8e6051ec48 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Tue, 21 Jul 2026 21:38:45 +0100 Subject: [PATCH 1/8] update html --- Sprint-3/quote-generator/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..e227ef2d9 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -3,13 +3,13 @@ - Title here + Quote generator app + -

hello there

-

-

+

quote text

+

author

From b3e29b9861a60b858d4c5a2ccdb1ef8b27679a7a Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Tue, 21 Jul 2026 21:44:18 +0100 Subject: [PATCH 2/8] add function, dom elements and event listener for quotes --- Sprint-3/quote-generator/quotes.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 4a4d04b72..b903ee416 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -490,4 +490,20 @@ const quotes = [ }, ]; -// call pickFromArray with the quotes array to check you get a random quote +// define variables to store elements +const quoteText = document.querySelector(".quote-text"); +const author = document.querySelector(".author"); +const newQuoteBtn = document.querySelector("button"); + +// function to display quote +function displayQuote() { + const quote = pickFromArray(quotes); + quoteText.textContent = quote.quote; + author.textContent = quote.author; +} + +// display quote when page loads +displayQuote(); + +// display quote when button is clicked +newQuoteBtn.addEventListener("click", displayQuote); From 12932cdba53301abfd44fb444a7b5e8433002bfb Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Tue, 21 Jul 2026 21:47:40 +0100 Subject: [PATCH 3/8] refactor: update DOM selectors to use IDs instead of classes for quote and author elements --- Sprint-3/quote-generator/index.html | 4 ++-- Sprint-3/quote-generator/quotes.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index e227ef2d9..1f67f2c6a 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -8,8 +8,8 @@ -

quote text

-

author

+

quote text

+

author

diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index b903ee416..983171580 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -491,9 +491,9 @@ const quotes = [ ]; // define variables to store elements -const quoteText = document.querySelector(".quote-text"); -const author = document.querySelector(".author"); -const newQuoteBtn = document.querySelector("button"); +const quoteText = document.querySelector("#quote"); +const author = document.querySelector("#author"); +const newQuoteBtn = document.querySelector("#new-quote"); // function to display quote function displayQuote() { From 36729c1117c0495f99dce2177a20cb1f7c9b5f7a Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Thu, 23 Jul 2026 15:47:25 +0100 Subject: [PATCH 4/8] add fonts and new elements on the page --- Sprint-3/quote-generator/index.html | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 1f67f2c6a..87d76e4ee 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -4,12 +4,24 @@ Quote generator app + + + -

quote text

-

author

- +
+
+
+
+

quote text

+

author

+
+
+ +
+
+
From 19a0791792ca768bc4d21aaf5ff0f593acf14143 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Thu, 23 Jul 2026 15:47:51 +0100 Subject: [PATCH 5/8] add styling cartoonish flashcard design and polka dot background --- Sprint-3/quote-generator/style.css | 203 ++++++++++++++++++++++++++++- 1 file changed, 202 insertions(+), 1 deletion(-) diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 63cedf2d2..164d9ec4a 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1 +1,202 @@ -/** Write your CSS in here **/ +:root { + /* Fonts */ + --font-sans: + "Outfit", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + --font-serif: "Lora", Georgia, serif; + /* Colours */ + --bg-yellow: oklch(0.93 0.16 90); + --bg-pink-dots: oklch(0.68 0.23 330); + --card-bg: oklch(0.96 0.06 200); + --text-dark: oklch(0.12 0.04 240); + --accent-yellow: oklch(0.88 0.21 95); + --btn-pink: oklch(0.65 0.25 330); + --btn-orange: oklch(0.75 0.22 50); +} + +/* Reset */ +* { + box-sizing: border-box; +} + +body { + margin: 0; + padding: 0; + min-height: 100dvh; + display: flex; + justify-content: center; + align-items: center; + font-family: var(--font-sans); + + /* Cartoonish Polka Dot Wallpaper Background */ + background-color: var(--bg-yellow); + background-image: + radial-gradient(var(--bg-pink-dots) 20%, transparent 20%), + radial-gradient(var(--bg-pink-dots) 20%, transparent 20%); + background-size: 40px 40px; + background-position: + 0 0, + 20px 20px; + + overflow-x: hidden; +} + +/* App container */ +.app-container { + display: grid; + place-items: center; + width: 100%; + padding: 2rem 1.5rem; +} + +/* Funky Cartoon Flashcard */ +.flashcard { + position: relative; + background-color: var(--card-bg); + width: 100%; + max-width: 580px; + min-height: 340px; + border-radius: 28px; + padding: 3.5rem 3rem 3rem 3.5rem; + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 2.5rem; + + border: 4px solid var(--text-dark); + box-shadow: 12px 12px 0px var(--text-dark); + + transform: rotate(-1deg); + transition: + transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275), + box-shadow 0.2s ease; +} + +/* Wiggle on hover */ +.flashcard:hover { + transform: rotate(1deg) scale(1.02); + box-shadow: 16px 16px 0px var(--text-dark); +} + +/* Double quote */ +.quote-symbol { + font-family: var(--font-serif); + font-size: 14rem; + line-height: 1; + color: var(--text-dark) + opacity: 0.18; + position: absolute; + top: -2.5rem; + left: 1rem; + user-select: none; + pointer-events: none; +} + +/* Card Content Area */ +.flashcard-content { + display: flex; + flex-direction: column; + gap: 2rem; + position: relative; + z-index: 1; +} + +/* Quote Text Style */ +#quote { + font-family: var(--font-sans); + font-size: clamp(1.2rem, 1rem + 1.2vw, 2.3rem); + font-weight: 850; + line-height: 1.3; + color: var(--text-dark); + margin: 0; + text-wrap: pretty; +} + +/* Author badge */ +#author { + font-family: var(--font-sans); + font-size: 0.95rem; + font-weight: 800; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--text-dark); + margin: 0; + align-self: flex-end; + + /* Badge styling */ + background-color: var(--accent-yellow); + padding: 0.6rem 1.2rem; + border: 3px solid var(--text-dark); + border-radius: 12px; + box-shadow: 4px 4px 0px var(--text-dark); + transform: rotate(2deg); + transition: transform 0.2s ease; +} + +#author:hover { + transform: rotate(-2deg) scale(1.05); +} + +/* Action button area */ +.flashcard-actions { + display: flex; + justify-content: center; + position: relative; + z-index: 1; +} + +/* Pop Button */ +#new-quote { + font-family: var(--font-sans); + font-size: 1.1rem; + font-weight: 900; + color: oklch(1 0 0); + background-color: var(--btn-pink); + border: 3px solid var(--text-dark); + border-radius: 16px; + padding: 0.9rem 2.5rem; + cursor: pointer; + box-shadow: 5px 5px 0px var(--text-dark); + transition: + transform 0.1s ease, + box-shadow 0.1s ease, + background-color 0.2s ease; + + text-transform: uppercase; + letter-spacing: 0.03em; + min-block-size: 48px; +} + +#new-quote:hover { + background-color: var(--btn-orange); + transform: translate(-2px, -2px); + box-shadow: 7px 7px 0px var(--text-dark); +} + +#new-quote:active { + transform: translate(3px, 3px); + box-shadow: 2px 2px 0px var(--text-dark); +} + +/* Focus style */ +#new-quote:focus-visible { + outline: 3px solid var(--text-dark); + outline-offset: 4px; +} + +/* Preferences for motion */ +@media (prefers-reduced-motion: reduce) { + .flashcard, + #author, + #new-quote { + transition: none; + transform: none !important; + } + .flashcard:hover { + transform: none !important; + } + #new-quote:hover, + #new-quote:active { + transform: none !important; + box-shadow: 5px 5px 0px var(--text-dark) !important; + } +} From cc2b5d2c89340b8425faeef069fe3e5453fb8a79 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Thu, 23 Jul 2026 15:59:22 +0100 Subject: [PATCH 6/8] add autoplay functionality to the quote generator with toggle control --- Sprint-3/quote-generator/index.html | 7 +++++ Sprint-3/quote-generator/quotes.js | 43 +++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 87d76e4ee..324f38b5d 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -20,6 +20,13 @@

quote text

+
+ + auto-play:OFF +
diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 983171580..fd9e18707 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -494,6 +494,8 @@ const quotes = [ const quoteText = document.querySelector("#quote"); const author = document.querySelector("#author"); const newQuoteBtn = document.querySelector("#new-quote"); +const autoplayToggle = document.querySelector("#autoplay-toggle"); +const autoplayStatus = document.querySelector("#autoplay-status"); // function to display quote function displayQuote() { @@ -505,5 +507,42 @@ function displayQuote() { // display quote when page loads displayQuote(); -// display quote when button is clicked -newQuoteBtn.addEventListener("click", displayQuote); +// Autoplay interval management +let autoplayInterval = null; +const AUTOPLAY_DELAY_MS = 5000; // 5 seconds + +function startAutoplay() { + if (!autoplayInterval) { + autoplayInterval = setInterval(displayQuote, AUTOPLAY_DELAY_MS); + } + autoplayStatus.textContent = "auto-play:ON"; + autoplayStatus.classList.add("active"); +} + +function stopAutoplay() { + if (autoplayInterval) { + clearInterval(autoplayInterval); + autoplayInterval = null; + } + autoplayStatus.textContent = "auto-play:OFF"; + autoplayStatus.classList.remove("active"); +} + +// Handler for new quote button click (resets autoplay timer if active) +function handleNewQuoteClick() { + displayQuote(); + if (autoplayToggle.checked) { + stopAutoplay(); + startAutoplay(); + } +} + +newQuoteBtn.addEventListener("click", handleNewQuoteClick); + +autoplayToggle.addEventListener("change", (event) => { + if (event.target.checked) { + startAutoplay(); + } else { + stopAutoplay(); + } +}); From 8f4225d267284708ba9d9202169cddd9c309ad84 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Thu, 23 Jul 2026 16:00:05 +0100 Subject: [PATCH 7/8] add styled autoplay toggle switch with effect --- Sprint-3/quote-generator/style.css | 94 +++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 164d9ec4a..cd14db471 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -139,11 +139,96 @@ body { /* Action button area */ .flashcard-actions { display: flex; - justify-content: center; + flex-flow: row wrap; + justify-content: space-between; + align-items: center; + gap: 1.5rem; position: relative; z-index: 1; } +/* Autoplay control layout and badge */ +.autoplay-control { + display: flex; + align-items: center; + gap: 0.75rem; + background-color: var(--accent-yellow); + border: 3px solid var(--text-dark); + border-radius: 16px; + padding: 0.5rem 1rem; + box-shadow: 4px 4px 0px var(--text-dark); + transform: rotate(-1deg); + transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +.autoplay-control:hover { + transform: rotate(1deg) scale(1.03); +} + +/* Toggle Switch */ +.toggle-switch { + position: relative; + display: inline-block; + width: 54px; + height: 30px; +} + +.toggle-switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: oklch(0.9 0.02 240); + border: 3px solid var(--text-dark); + border-radius: 34px; + transition: background-color 0.2s ease; +} + +.slider::before { + position: absolute; + content: ""; + height: 16px; + width: 16px; + left: 4px; + bottom: 4px; + background-color: var(--text-dark); + border-radius: 50%; + transition: transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); +} + +input:checked + .slider { + background-color: var(--btn-pink); +} + +input:checked + .slider::before { + transform: translateX(24px); + background-color: oklch(1 0 0); +} + +input:focus-visible + .slider { + outline: 2px solid var(--text-dark); + outline-offset: 2px; +} + +.autoplay-status { + font-family: var(--font-sans); + font-size: 0.85rem; + font-weight: 850; + text-transform: uppercase; + color: var(--text-dark); + letter-spacing: 0.05em; + user-select: none; +} + + /* Pop Button */ #new-quote { font-family: var(--font-sans); @@ -187,8 +272,11 @@ body { @media (prefers-reduced-motion: reduce) { .flashcard, #author, - #new-quote { - transition: none; + #new-quote, + .autoplay-control, + .slider, + .slider::before { + transition: none !important; transform: none !important; } .flashcard:hover { From f598f041335a8ab99f4be8fab5ec16dba5181482 Mon Sep 17 00:00:00 2001 From: Tomislav Dukez Date: Thu, 23 Jul 2026 18:11:35 +0100 Subject: [PATCH 8/8] fix: trigger initial quote display when autoplay is enabled --- Sprint-3/quote-generator/quotes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index fd9e18707..7236051eb 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -541,6 +541,7 @@ newQuoteBtn.addEventListener("click", handleNewQuoteClick); autoplayToggle.addEventListener("change", (event) => { if (event.target.checked) { + displayQuote(); startAutoplay(); } else { stopAutoplay();