diff --git a/extension/locales/de.json b/extension/locales/de.json index 91e5136..6507be7 100644 --- a/extension/locales/de.json +++ b/extension/locales/de.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Wendet Audioeffekte wie Kompression auf die Videowiedergabe an", "AUDIO_OPEN_SETTINGS": "Öffnen", "NEW_FEATURE_AUDIO": "Neu: Audio-Verarbeitung — probiere den Kompressor aus!", + "NEW_FEATURE_THEME": "Neu: Themes — wechsle zum klassischen Look oder minimalem Graphit.", "AUDIO_BACK": "← Zurück", "AUDIO_PAGE_TITLE": "Audio-Einstellungen", "AUDIO_MASTER_TOGGLE": "Audio-Verarbeitung", diff --git a/extension/locales/en.json b/extension/locales/en.json index ed99f04..25f5c04 100644 --- a/extension/locales/en.json +++ b/extension/locales/en.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "AUDIO_OPEN_SETTINGS": "Open", "NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", + "NEW_FEATURE_THEME": "New: Themes — switch to the classic look or minimal graphite.", "AUDIO_BACK": "← Back", "AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_MASTER_TOGGLE": "Audio Processing", diff --git a/extension/locales/es.json b/extension/locales/es.json index b36643a..624e419 100644 --- a/extension/locales/es.json +++ b/extension/locales/es.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Aplica efectos de audio como compresión a la reproducción de video", "AUDIO_OPEN_SETTINGS": "Abrir", "NEW_FEATURE_AUDIO": "Nuevo: Procesamiento de audio — ¡prueba el compresor!", + "NEW_FEATURE_THEME": "Nuevo: Temas — cambia al aspecto clásico o al grafito minimalista.", "AUDIO_BACK": "← Volver", "AUDIO_PAGE_TITLE": "Configuración de audio", "AUDIO_MASTER_TOGGLE": "Procesamiento de audio", diff --git a/extension/locales/fr.json b/extension/locales/fr.json index 13a9192..67e0408 100644 --- a/extension/locales/fr.json +++ b/extension/locales/fr.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Applique des effets audio comme la compression à la lecture vidéo", "AUDIO_OPEN_SETTINGS": "Ouvrir", "NEW_FEATURE_AUDIO": "Nouveau : Traitement audio — essayez le compresseur !", + "NEW_FEATURE_THEME": "Nouveau : Thèmes — passez au look classique ou au graphite minimal.", "AUDIO_BACK": "← Retour", "AUDIO_PAGE_TITLE": "Paramètres audio", "AUDIO_MASTER_TOGGLE": "Traitement audio", diff --git a/extension/locales/it.json b/extension/locales/it.json index 303524f..bb72c95 100644 --- a/extension/locales/it.json +++ b/extension/locales/it.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Applica effetti sonori (come il compressore) ai video", "AUDIO_OPEN_SETTINGS": "Apri", "NEW_FEATURE_AUDIO": "Novità: Elaborazione Audio — prova il compressore!", + "NEW_FEATURE_THEME": "Nuovo: Temi — passa all'aspetto classico o al grafite minimale.", "AUDIO_BACK": "← Indietro", "AUDIO_PAGE_TITLE": "Impostazioni Audio", "AUDIO_MASTER_TOGGLE": "Elaborazione Audio", diff --git a/extension/locales/ja.json b/extension/locales/ja.json index 44ccc8e..70162a8 100644 --- a/extension/locales/ja.json +++ b/extension/locales/ja.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "動画再生に圧縮などのオーディオエフェクトを適用します", "AUDIO_OPEN_SETTINGS": "開く", "NEW_FEATURE_AUDIO": "新機能: オーディオ処理 — コンプレッサーを試してみよう!", + "NEW_FEATURE_THEME": "新機能:テーマ — クラシックな外観やミニマルなグラファイトに切り替え。", "AUDIO_BACK": "← 戻る", "AUDIO_PAGE_TITLE": "オーディオ設定", "AUDIO_MASTER_TOGGLE": "オーディオ処理", diff --git a/extension/locales/ko.json b/extension/locales/ko.json index b0787c1..d40a320 100644 --- a/extension/locales/ko.json +++ b/extension/locales/ko.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "비디오 재생에 압축과 같은 오디오 효과를 적용합니다", "AUDIO_OPEN_SETTINGS": "열기", "NEW_FEATURE_AUDIO": "신규: 오디오 처리 — 컴프레서를 사용해보세요!", + "NEW_FEATURE_THEME": "신규: 테마 — 클래식 룩이나 미니멀 그래파이트로 전환하세요.", "AUDIO_BACK": "← 뒤로", "AUDIO_PAGE_TITLE": "오디오 설정", "AUDIO_MASTER_TOGGLE": "오디오 처리", diff --git a/extension/locales/nl.json b/extension/locales/nl.json index 73316f7..dd2a201 100644 --- a/extension/locales/nl.json +++ b/extension/locales/nl.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Past audio-effecten zoals compressie toe op video-afspelen", "AUDIO_OPEN_SETTINGS": "Openen", "NEW_FEATURE_AUDIO": "Nieuw: Audioverwerking — probeer de compressor!", + "NEW_FEATURE_THEME": "Nieuw: Thema's — schakel naar de klassieke look of minimaal grafiet.", "AUDIO_BACK": "← Terug", "AUDIO_PAGE_TITLE": "Audio-instellingen", "AUDIO_MASTER_TOGGLE": "Audioverwerking", diff --git a/extension/locales/pl.json b/extension/locales/pl.json index 47c45b0..dde3e3d 100644 --- a/extension/locales/pl.json +++ b/extension/locales/pl.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Stosuje efekty dźwiękowe, takie jak kompresja, do odtwarzania wideo", "AUDIO_OPEN_SETTINGS": "Otwórz", "NEW_FEATURE_AUDIO": "Nowość: Przetwarzanie dźwięku — wypróbuj kompresor!", + "NEW_FEATURE_THEME": "Nowość: Motywy — przełącz na klasyczny wygląd lub minimalny grafit.", "AUDIO_BACK": "← Wstecz", "AUDIO_PAGE_TITLE": "Ustawienia dźwięku", "AUDIO_MASTER_TOGGLE": "Przetwarzanie dźwięku", diff --git a/extension/locales/pt-BR.json b/extension/locales/pt-BR.json index 37c2fa0..1d07782 100644 --- a/extension/locales/pt-BR.json +++ b/extension/locales/pt-BR.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Aplica efeitos de áudio (como compressão) aos vídeos", "AUDIO_OPEN_SETTINGS": "Abrir", "NEW_FEATURE_AUDIO": "Novo: Processamento de áudio — experimente o compressor!", + "NEW_FEATURE_THEME": "Novo: Temas — mude para o visual clássico ou grafite minimalista.", "AUDIO_BACK": "← Voltar", "AUDIO_PAGE_TITLE": "Configurações de áudio", "AUDIO_MASTER_TOGGLE": "Processamento de áudio", diff --git a/extension/locales/pt.json b/extension/locales/pt.json index 623cdba..b360401 100644 --- a/extension/locales/pt.json +++ b/extension/locales/pt.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Aplica efeitos de áudio (como compressão) aos vídeos", "AUDIO_OPEN_SETTINGS": "Abrir", "NEW_FEATURE_AUDIO": "Novo: Processamento de áudio — experimente o compressor!", + "NEW_FEATURE_THEME": "Novo: Temas — mude para o visual clássico ou grafite minimalista.", "AUDIO_BACK": "← Voltar", "AUDIO_PAGE_TITLE": "Configurações de Áudio", "AUDIO_MASTER_TOGGLE": "Processamento de Áudio", diff --git a/extension/locales/ru.json b/extension/locales/ru.json index 48ce4fc..7aa0e35 100644 --- a/extension/locales/ru.json +++ b/extension/locales/ru.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Применяет аудиоэффекты, такие как сжатие, к воспроизведению видео", "AUDIO_OPEN_SETTINGS": "Открыть", "NEW_FEATURE_AUDIO": "Новое: Обработка звука — попробуйте компрессор!", + "NEW_FEATURE_THEME": "Новое: Темы — переключитесь на классический вид или минимальный графит.", "AUDIO_BACK": "← Назад", "AUDIO_PAGE_TITLE": "Настройки звука", "AUDIO_MASTER_TOGGLE": "Обработка звука", diff --git a/extension/locales/tr.json b/extension/locales/tr.json index 74bae81..b5b29da 100644 --- a/extension/locales/tr.json +++ b/extension/locales/tr.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Video oynatımına sıkıştırma gibi ses efektleri uygular", "AUDIO_OPEN_SETTINGS": "Aç", "NEW_FEATURE_AUDIO": "Yeni: Ses işleme — kompresörü deneyin!", + "NEW_FEATURE_THEME": "Yeni: Temalar — klasik görünüme veya minimal grafite geçin.", "AUDIO_BACK": "← Geri", "AUDIO_PAGE_TITLE": "Ses ayarları", "AUDIO_MASTER_TOGGLE": "Ses işleme", diff --git a/extension/locales/uk.json b/extension/locales/uk.json index cf9f97f..22aa7d5 100644 --- a/extension/locales/uk.json +++ b/extension/locales/uk.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "Застосуйте звукові ефекти, такі як стиснення, до відтворення відео", "AUDIO_OPEN_SETTINGS": "Відкрити", "NEW_FEATURE_AUDIO": "Новинка: обробка звуку — спробуйте компресор!", + "NEW_FEATURE_THEME": "Нове: Теми — перемкніться на класичний вигляд або мінімальний графіт.", "AUDIO_BACK": "← Назад", "AUDIO_PAGE_TITLE": "Параметри звуку", "AUDIO_MASTER_TOGGLE": "Обробка аудіо", diff --git a/extension/locales/zh.json b/extension/locales/zh.json index 5ee51a5..dda1b53 100644 --- a/extension/locales/zh.json +++ b/extension/locales/zh.json @@ -209,6 +209,7 @@ "LABEL_AUDIO_PROCESSING_TOOLTIP": "将压缩等音频效果应用于视频播放", "AUDIO_OPEN_SETTINGS": "打开", "NEW_FEATURE_AUDIO": "新功能:音频处理 - 尝试压缩器!", + "NEW_FEATURE_THEME": "新功能:主题 — 切换到经典外观或极简石墨风格。", "AUDIO_BACK": "← 返回", "AUDIO_PAGE_TITLE": "音频设置", "AUDIO_MASTER_TOGGLE": "音频处理", diff --git a/extension/popup.html b/extension/popup.html index 3461a8a..6f1b518 100644 --- a/extension/popup.html +++ b/extension/popup.html @@ -73,6 +73,113 @@ color-scheme: light; } + /* ============================================================ + THEME: CYBER — the original indigo / slate look, kept for + people who prefer the pre-nature design. Cool navy neutrals + with an electric indigo brand accent and a violet companion. + ============================================================ */ + html[data-palette="cyber"] { + --bg-base: oklch(0.215 0.042 265); + --surface: oklch(0.285 0.05 265); + --surface-deep: oklch(0.185 0.04 265); + --surface-alt: oklch(0.25 0.048 265); + --border-soft: oklch(0.9 0.03 265 / 0.10); + --border-strong: oklch(0.42 0.05 265); + --text-primary: oklch(0.97 0.012 265); + --text-secondary: oklch(0.74 0.03 265); + --accent-green: oklch(0.59 0.20 275); + --accent-green-hover: oklch(0.69 0.17 275); + --accent-terracotta: oklch(0.64 0.21 320); + --success-green: oklch(0.74 0.17 150); + --warning-amber: oklch(0.79 0.15 75); + --danger: oklch(0.63 0.20 25); + --text-on-green: oklch(0.99 0.006 275); + --text-on-warm: oklch(0.99 0.006 320); + --status-success-text: oklch(0.82 0.15 150); + --status-warning-text: oklch(0.85 0.14 78); + --status-error-text: oklch(0.78 0.16 25); + --status-neutral-text: oklch(0.74 0.03 265); + color-scheme: dark; + } + + html[data-palette="cyber"].theme-light { + --bg-base: oklch(0.965 0.01 265); + --surface: oklch(0.995 0.005 265); + --surface-deep: oklch(0.945 0.014 265); + --surface-alt: oklch(0.915 0.02 265); + --border-soft: oklch(0.30 0.05 265 / 0.12); + --border-strong: oklch(0.79 0.03 265); + --text-primary: oklch(0.26 0.05 265); + --text-secondary: oklch(0.48 0.045 265); + --accent-green: oklch(0.53 0.21 275); + --accent-green-hover: oklch(0.46 0.20 275); + --accent-terracotta: oklch(0.55 0.23 320); + --success-green: oklch(0.52 0.16 150); + --warning-amber: oklch(0.62 0.15 72); + --danger: oklch(0.56 0.21 25); + --text-on-green: oklch(0.99 0.005 275); + --text-on-warm: oklch(0.99 0.005 320); + --status-success-text: oklch(0.45 0.15 150); + --status-warning-text: oklch(0.50 0.13 70); + --status-error-text: oklch(0.50 0.18 25); + --status-neutral-text: oklch(0.48 0.045 265); + color-scheme: light; + } + + /* ============================================================ + THEME: GRAPHITE — a quiet black-and-white minimal system. + Near-neutral cool greys, a monochrome accent (bright on dark, + ink on light); status hues are the only colour, kept muted so + they still read as success / warning / danger. + ============================================================ */ + html[data-palette="graphite"] { + --bg-base: oklch(0.19 0.004 260); + --surface: oklch(0.255 0.005 260); + --surface-deep: oklch(0.165 0.004 260); + --surface-alt: oklch(0.225 0.005 260); + --border-soft: oklch(0.92 0.008 260 / 0.11); + --border-strong: oklch(0.42 0.006 260); + --text-primary: oklch(0.97 0.003 260); + --text-secondary: oklch(0.72 0.005 260); + --accent-green: oklch(0.93 0.006 260); + --accent-green-hover: oklch(0.99 0.003 260); + --accent-terracotta: oklch(0.80 0.008 260); + --success-green: oklch(0.74 0.10 155); + --warning-amber: oklch(0.80 0.10 80); + --danger: oklch(0.64 0.14 25); + --text-on-green: oklch(0.20 0.004 260); + --text-on-warm: oklch(0.20 0.004 260); + --status-success-text: oklch(0.81 0.09 152); + --status-warning-text: oklch(0.84 0.10 80); + --status-error-text: oklch(0.76 0.12 25); + --status-neutral-text: oklch(0.72 0.005 260); + color-scheme: dark; + } + + html[data-palette="graphite"].theme-light { + --bg-base: oklch(0.955 0.002 260); + --surface: oklch(1 0 0); + --surface-deep: oklch(0.928 0.003 260); + --surface-alt: oklch(0.90 0.004 260); + --border-soft: oklch(0.20 0.006 260 / 0.13); + --border-strong: oklch(0.77 0.004 260); + --text-primary: oklch(0.22 0.005 260); + --text-secondary: oklch(0.46 0.006 260); + --accent-green: oklch(0.28 0.006 260); + --accent-green-hover: oklch(0.18 0.005 260); + --accent-terracotta: oklch(0.44 0.008 260); + --success-green: oklch(0.51 0.12 152); + --warning-amber: oklch(0.60 0.12 72); + --danger: oklch(0.55 0.17 25); + --text-on-green: oklch(0.98 0.002 260); + --text-on-warm: oklch(0.98 0.002 260); + --status-success-text: oklch(0.45 0.12 152); + --status-warning-text: oklch(0.49 0.11 70); + --status-error-text: oklch(0.49 0.16 25); + --status-neutral-text: oklch(0.46 0.006 260); + color-scheme: light; + } + body { width: 360px; margin: 0; @@ -94,6 +201,60 @@ radial-gradient(circle at 105% 5%, oklch(0.82 0.12 65 / 0.2), transparent 38%); } + /* Per-theme ambient glow: each palette carries its own signature + corner wash so the backdrop matches the accent, not eucalyptus. */ + html[data-palette="cyber"] body { + background-image: + radial-gradient(circle at 12% -8%, oklch(0.64 0.19 275 / 0.16), transparent 42%), + radial-gradient(circle at 105% 12%, oklch(0.64 0.21 320 / 0.11), transparent 34%); + } + html[data-palette="cyber"].theme-light body { + background-image: + radial-gradient(circle at 8% -5%, oklch(0.60 0.20 275 / 0.16), transparent 40%), + radial-gradient(circle at 105% 5%, oklch(0.62 0.20 320 / 0.14), transparent 38%); + } + html[data-palette="graphite"] body { + background-image: + radial-gradient(circle at 12% -8%, oklch(0.93 0.006 260 / 0.05), transparent 44%); + } + html[data-palette="graphite"].theme-light body { + background-image: + radial-gradient(circle at 12% -8%, oklch(0.20 0.006 260 / 0.045), transparent 46%); + } + + /* The Create Room button carries an inline eucalyptus glow; retint + its shadow per palette so the hero action stays on-theme. */ + html[data-palette="cyber"] #createRoomBtn, + html[data-palette="cyber"] #syncTabCreateRoomBtn { + box-shadow: 0 4px 12px oklch(0.64 0.19 275 / 0.4) !important; + } + html[data-palette="graphite"] #createRoomBtn, + html[data-palette="graphite"] #syncTabCreateRoomBtn { + box-shadow: 0 4px 12px oklch(0.20 0.006 260 / 0.4) !important; + } + + /* Cyber's brand ink is white (for the dark indigo accent), but its + success/warning fills are bright — so the few surfaces that print + text directly on those fills need dark ink to stay legible. */ + html[data-palette="cyber"] .toast-success, + html[data-palette="cyber"] .toast-warning, + html[data-palette="cyber"] .copy-success { + color: oklch(0.22 0.03 265) !important; + } + + /* Theme cross-fade: enabled only for the ~260ms around a user-initiated + theme/appearance switch (added by popup.js), so colours glide instead + of snapping — without slowing down normal hover/state transitions. */ + html.theme-anim, + html.theme-anim * { + transition: background-color 0.24s ease, border-color 0.24s ease, + color 0.24s ease, box-shadow 0.24s ease, fill 0.24s ease !important; + } + @media (prefers-reduced-motion: reduce) { + html.theme-anim, + html.theme-anim * { transition: none !important; } + } + .header-row { display: flex; align-items: center; @@ -216,7 +377,7 @@ input:focus, select:focus { border-color: var(--accent); - box-shadow: 0 0 0 3px oklch(0.68 0.13 150 / 0.18); + box-shadow: 0 0 0 3px color-mix(in oklch, var(--accent), transparent 82%); } button.primary { @@ -495,6 +656,23 @@ .click-leaf-amber i { background: linear-gradient(135deg, oklch(0.68 0.14 55 / 0.95), oklch(0.55 0.13 40 / 0.85)); } + /* Non-eucalyptus themes retint the burst from their own accent pair so + the particles stay on-theme and, because those vars flip with + light/dark, remain visible against every background. */ + html[data-palette="cyber"] .click-leaf i, + html[data-palette="graphite"] .click-leaf i { + background: linear-gradient(135deg, var(--accent), var(--accent-hover)); + } + html[data-palette="cyber"] .click-leaf-sage i, + html[data-palette="graphite"] .click-leaf-sage i { + background: linear-gradient(135deg, var(--accent-hover), var(--accent)); + } + html[data-palette="cyber"] .click-leaf-amber i { + background: linear-gradient(135deg, var(--accent-terracotta), var(--accent)); + } + html[data-palette="graphite"] .click-leaf-amber i { + background: linear-gradient(135deg, var(--text-secondary), var(--accent)); + } @keyframes leafBurst { 0% { opacity: 0; @@ -865,6 +1043,109 @@ color: var(--text); box-shadow: 0 1px 5px oklch(0.08 0.02 150 / 0.32), inset 0 0 0 1px var(--border-soft); } + + /* Theme (colour palette) picker: a full-width row of swatch cards so + each curated scheme previews its own colours before selection. */ + .palette-row { + display: block; + padding: 12px 0 4px; + border-bottom: 1px solid var(--border-soft); + } + .palette-row > label { + margin: 0 0 9px; + color: var(--text); + font-size: 12px; + font-weight: 600; + letter-spacing: 0; + text-transform: none; + } + .palette-picker { + position: relative; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + } + .palette-picker select { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0 0 0 0); + white-space: nowrap; + border: 0; + } + .palette-choice { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + min-height: 62px; + margin: 0; + padding: 10px 4px 9px; + border: 1px solid var(--border-strong); + border-radius: 10px; + background: var(--surface-deep); + color: var(--text-muted); + font-family: inherit; + font-size: 11px; + font-weight: 700; + line-height: 1; + cursor: pointer; + transition: border-color 0.18s ease, background-color 0.18s ease, color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease; + } + .palette-choice:hover { + color: var(--text); + border-color: var(--accent); + transform: translateY(-1px); + } + .palette-choice.active { + color: var(--text); + border-color: var(--accent); + background: color-mix(in oklch, var(--accent) 10%, var(--surface-deep)); + box-shadow: 0 0 0 1px var(--accent), 0 5px 14px oklch(0.08 0.02 260 / 0.28); + } + .palette-swatch { + display: inline-flex; + padding: 3px; + border-radius: 999px; + background: var(--surface-alt); + box-shadow: inset 0 0 0 1px var(--border-soft); + } + .palette-swatch i { + width: 13px; + height: 13px; + border-radius: 50%; + display: block; + box-shadow: inset 0 0 0 1px oklch(0 0 0 / 0.22); + } + .palette-swatch i + i { + margin-left: -5px; + } + .palette-labeltext { + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; + } + .palette-name { + font-size: 11px; + font-weight: 700; + line-height: 1.1; + } + .palette-desc { + font-size: 9px; + font-weight: 600; + line-height: 1.1; + letter-spacing: 0.01em; + color: var(--text-muted); + opacity: 0.85; + } + .palette-choice.active .palette-desc { + color: var(--accent); + opacity: 1; + } .tab-btn[data-tab="tab-dev"], #devToolsTabBtn { color: color-mix(in oklch, var(--text-muted), transparent 18%); @@ -1147,7 +1428,7 @@ -
+