diff --git a/index.html b/index.html
index a6fc642..6070a69 100644
--- a/index.html
+++ b/index.html
@@ -2413,6 +2413,37 @@
+
Waveform Seekbar
diff --git a/js/settings.js b/js/settings.js
index 6fa82ab..2c406a1 100644
--- a/js/settings.js
+++ b/js/settings.js
@@ -2558,6 +2558,59 @@ function initializeFontSettings() {
}
renderUploadedFontsList();
+
+ // Font Size Controls
+ const fontSizeSlider = document.getElementById('font-size-slider');
+ const fontSizeInput = document.getElementById('font-size-input');
+ const fontSizeReset = document.getElementById('font-size-reset');
+
+ // Helper function to update both controls
+ const updateFontSizeControls = (size) => {
+ const validSize = Math.max(50, Math.min(200, parseInt(size, 10) || 100));
+ if (fontSizeSlider) fontSizeSlider.value = validSize;
+ if (fontSizeInput) fontSizeInput.value = validSize;
+ return validSize;
+ };
+
+ // Initialize with saved value
+ const savedSize = fontSettings.getFontSize();
+ updateFontSizeControls(savedSize);
+
+ // Slider change handler
+ if (fontSizeSlider) {
+ fontSizeSlider.addEventListener('input', () => {
+ const size = parseInt(fontSizeSlider.value, 10);
+ if (fontSizeInput) fontSizeInput.value = size;
+ fontSettings.setFontSize(size);
+ });
+ }
+
+ // Number input change handler
+ if (fontSizeInput) {
+ fontSizeInput.addEventListener('change', () => {
+ let size = parseInt(fontSizeInput.value, 10);
+ // Clamp to valid range
+ size = Math.max(50, Math.min(200, size || 100));
+ updateFontSizeControls(size);
+ fontSettings.setFontSize(size);
+ });
+
+ // Also update on input for real-time feedback
+ fontSizeInput.addEventListener('input', () => {
+ let size = parseInt(fontSizeInput.value, 10);
+ if (!isNaN(size) && size >= 50 && size <= 200) {
+ if (fontSizeSlider) fontSizeSlider.value = size;
+ fontSettings.setFontSize(size);
+ }
+ });
+ }
+
+ if (fontSizeReset) {
+ fontSizeReset.addEventListener('click', () => {
+ const defaultSize = fontSettings.resetFontSize();
+ updateFontSizeControls(defaultSize);
+ });
+ }
}
function setupSettingsSearch() {
diff --git a/js/storage.js b/js/storage.js
index 8716f0d..e779e3d 100644
--- a/js/storage.js
+++ b/js/storage.js
@@ -1732,6 +1732,7 @@ if (typeof window !== 'undefined' && window.matchMedia) {
export const fontSettings = {
STORAGE_KEY: 'monochrome-font-config-v2',
CUSTOM_FONTS_KEY: 'monochrome-custom-fonts',
+ FONT_SIZE_KEY: 'monochrome-font-size',
FONT_LINK_ID: 'monochrome-dynamic-font',
FONT_FACE_ID: 'monochrome-dynamic-fontface',
@@ -1744,6 +1745,43 @@ export const fontSettings = {
};
},
+ getDefaultFontSize() {
+ return 100; // 100% = default size
+ },
+
+ getFontSize() {
+ try {
+ const stored = localStorage.getItem(this.FONT_SIZE_KEY);
+ if (stored) {
+ const size = parseInt(stored, 10);
+ if (!isNaN(size) && size >= 50 && size <= 200) {
+ return size;
+ }
+ }
+ } catch {
+ // ignore
+ }
+ return this.getDefaultFontSize();
+ },
+
+ setFontSize(size) {
+ const validSize = Math.max(50, Math.min(200, parseInt(size, 10) || 100));
+ localStorage.setItem(this.FONT_SIZE_KEY, validSize.toString());
+ this.applyFontSize();
+ return validSize;
+ },
+
+ applyFontSize() {
+ const size = this.getFontSize();
+ document.documentElement.style.setProperty('--font-size-scale', `${size}%`);
+ },
+
+ resetFontSize() {
+ localStorage.removeItem(this.FONT_SIZE_KEY);
+ this.applyFontSize();
+ return this.getDefaultFontSize();
+ },
+
getConfig() {
try {
const stored = localStorage.getItem(this.STORAGE_KEY);
diff --git a/js/ui.js b/js/ui.js
index 8c910b8..5613747 100644
--- a/js/ui.js
+++ b/js/ui.js
@@ -47,6 +47,7 @@ import {
} from './tracker.js';
fontSettings.applyFont();
+fontSettings.applyFontSize();
function sortTracks(tracks, sortType) {
if (sortType === 'custom') return [...tracks];
diff --git a/styles.css b/styles.css
index 0d8bb4f..87ff749 100644
--- a/styles.css
+++ b/styles.css
@@ -4,6 +4,7 @@
/* Font - default to Inter for instant render, JS will override if needed */
--font-family: 'Inter', sans-serif;
+ --font-size-scale: 100%; /* Dynamic font size scale (50% - 200%) */
/* Spacing */
--spacing-xs: 0.25rem;
@@ -279,6 +280,7 @@ html {
-moz-osx-font-smoothing: grayscale;
height: 100%;
overflow: hidden;
+ font-size: var(--font-size-scale, 100%);
}
body {
@@ -2016,6 +2018,94 @@ input[type='search']::-webkit-search-cancel-button {
gap: 0.5rem;
}
+/* Font Size Control */
+.font-size-control {
+ display: flex;
+ align-items: center;
+ gap: var(--spacing-md);
+}
+
+.font-size-slider {
+ -webkit-appearance: none;
+ width: 150px;
+ height: 6px;
+ background: var(--border);
+ border-radius: var(--radius-full);
+ outline: none;
+}
+
+.font-size-slider::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ width: 18px;
+ height: 18px;
+ background: var(--primary);
+ border-radius: 50%;
+ cursor: pointer;
+ transition: background-color var(--transition-fast);
+}
+
+.font-size-slider::-webkit-slider-thumb:hover {
+ background: var(--highlight);
+}
+
+.font-size-slider::-moz-range-thumb {
+ width: 18px;
+ height: 18px;
+ background: var(--primary);
+ border-radius: 50%;
+ cursor: pointer;
+ border: none;
+ transition: background-color var(--transition-fast);
+}
+
+.font-size-slider::-moz-range-thumb:hover {
+ background: var(--highlight);
+}
+
+.font-size-number-input {
+ width: 60px;
+ padding: 0.4rem 0.5rem;
+ background: var(--input);
+ border: 1px solid var(--border);
+ border-radius: var(--radius);
+ color: var(--foreground);
+ font-size: 0.9rem;
+ text-align: center;
+ transition: border-color var(--transition-fast);
+}
+
+.font-size-number-input:hover {
+ border-color: var(--primary);
+}
+
+.font-size-number-input:focus {
+ outline: none;
+ border-color: var(--ring);
+ box-shadow: 0 0 0 3px rgb(var(--highlight-rgb), 0.2);
+}
+
+/* Hide number input arrows */
+.font-size-number-input::-webkit-outer-spin-button,
+.font-size-number-input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+.font-size-number-input[type='number'] {
+ -moz-appearance: textfield;
+}
+
+.font-size-unit {
+ font-size: 0.9rem;
+ color: var(--muted-foreground);
+ margin-left: -0.25rem;
+}
+
+#font-size-reset {
+ padding: 0.4rem 0.75rem;
+ font-size: 0.85rem;
+}
+
.uploaded-font-item .btn-icon {
padding: 0.25rem 0.5rem;
background-color: var(--secondary);