diff --git a/now-playing/settings/settings.json b/now-playing/settings/settings.json
index e9397c4..c68c7a3 100644
--- a/now-playing/settings/settings.json
+++ b/now-playing/settings/settings.json
@@ -38,6 +38,10 @@
"value": "card",
"label": "Card"
},
+ {
+ "value": "album-art",
+ "label": "Album Art"
+ },
{
"value": "vinyl",
"label": "Vinyl"
diff --git a/now-playing/themes/album-art/index.html b/now-playing/themes/album-art/index.html
new file mode 100644
index 0000000..bfac360
--- /dev/null
+++ b/now-playing/themes/album-art/index.html
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/now-playing/themes/album-art/script.js b/now-playing/themes/album-art/script.js
new file mode 100644
index 0000000..68d2cc0
--- /dev/null
+++ b/now-playing/themes/album-art/script.js
@@ -0,0 +1,93 @@
+///////////////////
+// PAGE ELEMENTS //
+///////////////////
+
+const mainWrapper = document.getElementById('main-wrapper');
+const songInfoContainer = document.getElementById('song-info-container');
+const albumArtContainer = document.getElementById('album-art-container');
+const albumArtLayer = document.getElementById('album-art-layer');
+const albumArtTransition = document.getElementById('album-art-transition-layer');
+const textInfoContainer = document.getElementById('text-info-container');
+const trackLabel = document.getElementById('track-label');
+const artistLabel = document.getElementById('artist-label');
+const progressBar = document.getElementById('progress-bar');
+
+
+
+////////////////
+// PAGE SETUP //
+////////////////
+
+// Set property visibility
+trackLabel.style.display = showPrimary ? '' : 'none';
+artistLabel.style.display = showSecondary ? '' : 'none';
+
+// Set container width
+if (maxWidth > 0)
+ mainWrapper.style.width = `${maxWidth}px`;
+else
+ mainWrapper.style.width = `100%`;
+
+mainWrapper.style.height = `${mainWrapper.style.clientWidth}px`;
+
+// Set progress bar visibility
+if (!showProgressBar)
+ progressBar.style.display = 'none';
+
+
+
+////////////////////
+// CORE FUNCTIONS //
+////////////////////
+
+async function ChangeTrack(mediaProps, accentColorPalette) {
+ // Fade in the overlay (shows the new text)
+ if (trackLabel.innerText != (swapArtistTrack ? mediaProps.Artist : mediaProps.Title))
+ trackLabel.style.opacity = "0";
+ if (artistLabel.innerText != (swapArtistTrack ? mediaProps.Title : mediaProps.Artist))
+ artistLabel.style.opacity = "0";
+ albumArtLayer.style.opacity = "0";
+
+ // Wait for fade (0.5s), then swap the real text and hide overlay
+ setTimeout(() => {
+ SetLabelText('track-label', swapArtistTrack ? mediaProps.Artist : mediaProps.Title);
+ SetLabelText('artist-label', swapArtistTrack ? mediaProps.Title : mediaProps.Artist);
+
+ // Extract the image source string (use fallback if Windows has no art)
+ const newArtUrl = mediaProps.Thumbnail ?? './images/placeholder.png';
+
+ // Set the image
+ albumArtLayer.style.backgroundImage = `url('${newArtUrl}')`;
+
+ // Apply a tint
+ const baseColor = accentColorPalette.DarkMuted;
+ // Solid from 0% to 30%, then fading to 0% opacity at 100%
+ textInfoContainer.style.background = `linear-gradient(to top, ${baseColor}FF 0%, ${baseColor}FF 10%, ${baseColor}00 100%)`;
+ songInfoContainer.style.background = accentColorPalette.LightVibrant;
+
+ // Apply text color
+ document.body.style.color = accentColorPalette.LightVibrant;
+
+ trackLabel.style.opacity = "";
+ artistLabel.style.opacity = "";
+ albumArtLayer.style.opacity = "";
+
+ setTimeout(() => {
+ // Set the image
+ albumArtTransition.style.backgroundImage = `url('${newArtUrl}')`;
+
+ SetVisibility(true); // Show the overlay for a few seconds if autoHide is enabled
+ }, 250);
+ }, 250);
+}
+
+function SetProgressInfo(timelineProps, currentPositionMs, accentColorPalette) {
+
+ // Set progressbar
+ // Ensure we don't divide by zero or exceed 100%
+ const durationMs = timelineProps.EndTime;
+ let progressPercent = durationMs > 0 ? (currentPositionMs / durationMs) * 100 : 0;
+ progressPercent = Math.min(100, Math.max(0, progressPercent));
+ progressBar.style.width = `${progressPercent}%`;
+ progressBar.style.setProperty('--accent-color', accentColorPalette.LightVibrant);
+}
\ No newline at end of file
diff --git a/now-playing/themes/album-art/style.css b/now-playing/themes/album-art/style.css
new file mode 100644
index 0000000..37bb8c4
--- /dev/null
+++ b/now-playing/themes/album-art/style.css
@@ -0,0 +1,89 @@
+:root {
+ --border-radius: 30px;
+}
+
+#main-wrapper {
+ width: 500px;
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+ gap: 0.5em;
+ opacity: 0;
+ aspect-ratio: 1 / 1;
+}
+
+#album-art-container {
+ aspect-ratio: 1 / 1;
+ overflow: hidden;
+ position: relative;
+ background-size: cover;
+ background-position: center;
+ display: var(--show-album-art);
+}
+
+#album-art-layer,
+#album-art-transition-layer {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-size: cover;
+ background-position: center;
+ transition: opacity 0.5s ease;
+}
+
+#album-art-layer {
+ z-index: 1;
+ transition: all 0.5s ease;
+}
+
+#album-art-transition-layer {
+ z-index: 0;
+}
+
+#song-info-container {
+ position: relative;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ border-radius: var(--border-radius);
+ overflow: hidden;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
+}
+
+#text-info-container {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ padding: 6% 7%;
+ padding-top: 50%;
+ box-sizing: border-box;
+ z-index: 2;
+ text-align: var(--text-alignment);
+}
+
+#track-label {
+ font-size: 2em;
+ font-weight: 700;
+ text-align: var(--text-alignment);
+}
+
+#artist-label {
+ font-size: 1.5em;
+ font-weight: 500;
+ opacity: 0.8;
+ text-align: var(--text-alignment);
+}
+
+#progress-bar {
+ height: 1%;
+ width: 0%; /* JS will control this */
+ background-color: var(--accent-color, #ffffff);
+ transition: width 1s ease-in-out, background-color 1s ease-in-out;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ z-index: 3;
+}
\ No newline at end of file