@@ -131,6 +131,7 @@ const quizStartBtn = document.getElementById("quiz-start");
131131const quizResetBtn = document . getElementById ( "quiz-reset" ) ;
132132const quizScore = document . getElementById ( "quiz-score" ) ;
133133const headerThemeSelect = document . getElementById ( "header-theme-select" ) ;
134+ const material3PaletteSelect = document . getElementById ( "m3-palette-select" ) ;
134135const themeCycleBtn = document . getElementById ( "theme-cycle-btn" ) ;
135136const heroName = document . getElementById ( "hero-name" ) ;
136137const heroStatus = document . getElementById ( "hero-status" ) ;
@@ -144,6 +145,7 @@ const miniTerminalTheme = document.getElementById("mini-terminal-theme");
144145const NEPAL_TIMEZONE = "Asia/Kathmandu" ;
145146const BS_CONVERTER_URL = "https://cdn.jsdelivr.net/npm/nepali-date-library@1.1.9/+esm" ;
146147const THEME_STORAGE_KEY = "neoThemeVariant.v1" ;
148+ const M3_PALETTE_STORAGE_KEY = "neoMaterial3Palette.v1" ;
147149const ACTION_STORAGE_KEY = "neoAutoAction.v1" ;
148150const HERO_TYPED_KEY = "neoHeroTyped.v1" ;
149151const MINI_PROMPT = "╰─❯" ;
@@ -168,6 +170,7 @@ const THEME_OPTIONS = [
168170 "paper" ,
169171 "blackflag" ,
170172] ;
173+ const MATERIAL3_PALETTES = [ "lavender" , "emerald" , "sunset" ] ;
171174const MAX_TERMINAL_LINES = 220 ;
172175const TERMINAL_COMMANDS = [
173176 "help" , "whoami" , "mission" , "status" , "clear" ,
@@ -181,6 +184,7 @@ let launches = 0;
181184let adToBsConverter = null ;
182185let startPersonaQuiz = null ;
183186let currentTheme = "neo" ;
187+ let currentMaterial3Palette = "lavender" ;
184188let terminalHistory = [ ] ;
185189let terminalHistoryIndex = 0 ;
186190let terminalDraft = "" ;
@@ -727,6 +731,11 @@ function applyTheme(theme, notify = false) {
727731 miniTerminalTheme . textContent = `theme: ${ selected } ` ;
728732 }
729733
734+ document . body . classList . toggle ( "m3-palette-active" , selected === "material3" ) ;
735+ if ( selected === "material3" ) {
736+ applyMaterial3Palette ( currentMaterial3Palette , false ) ;
737+ }
738+
730739 try {
731740 window . localStorage . setItem ( THEME_STORAGE_KEY , selected ) ;
732741 } catch ( error ) {
@@ -739,33 +748,73 @@ function applyTheme(theme, notify = false) {
739748 if ( notify ) showToast ( `Theme changed: ${ selected } ` ) ;
740749}
741750
751+ function applyMaterial3Palette ( palette , notify = false ) {
752+ const selected = MATERIAL3_PALETTES . includes ( palette ) ? palette : "lavender" ;
753+ currentMaterial3Palette = selected ;
754+ document . documentElement . dataset . m3Palette = selected ;
755+ document . body . dataset . m3Palette = selected ;
756+ if ( material3PaletteSelect ) {
757+ material3PaletteSelect . value = selected ;
758+ }
759+
760+ try {
761+ window . localStorage . setItem ( M3_PALETTE_STORAGE_KEY , selected ) ;
762+ } catch ( error ) {
763+ // Ignore storage errors.
764+ }
765+
766+ if ( notify && currentTheme === "material3" ) {
767+ showToast ( `M3 palette: ${ selected } ` ) ;
768+ }
769+ }
770+
742771function initThemeSwitcher ( ) {
743772 let savedTheme = "neo" ;
744773 let urlTheme = null ;
774+ let savedPalette = "lavender" ;
745775 try {
746776 urlTheme = getThemeFromUrl ( ) ;
747777 const storedTheme = window . localStorage . getItem ( THEME_STORAGE_KEY ) ;
778+ const storedPalette = window . localStorage . getItem ( M3_PALETTE_STORAGE_KEY ) ;
748779 savedTheme = storedTheme || urlTheme || "neo" ;
780+ savedPalette = MATERIAL3_PALETTES . includes ( storedPalette ) ? storedPalette : "lavender" ;
749781 if ( ! storedTheme && urlTheme ) {
750782 window . localStorage . setItem ( THEME_STORAGE_KEY , urlTheme ) ;
751783 }
752784 } catch ( error ) {
753785 savedTheme = "neo" ;
786+ savedPalette = "lavender" ;
754787 }
755788
789+ applyMaterial3Palette ( savedPalette , false ) ;
756790 applyTheme ( savedTheme , false ) ;
757791 window . addEventListener ( "pageshow" , ( ) => {
758792 let latestTheme = "neo" ;
793+ let latestPalette = "lavender" ;
759794 try {
760795 latestTheme = window . localStorage . getItem ( THEME_STORAGE_KEY ) || getThemeFromUrl ( ) || "neo" ;
796+ const storedPalette = window . localStorage . getItem ( M3_PALETTE_STORAGE_KEY ) ;
797+ latestPalette = MATERIAL3_PALETTES . includes ( storedPalette ) ? storedPalette : "lavender" ;
761798 } catch ( error ) {
762799 latestTheme = "neo" ;
800+ latestPalette = "lavender" ;
801+ }
802+ if ( latestPalette !== currentMaterial3Palette ) {
803+ applyMaterial3Palette ( latestPalette , false ) ;
763804 }
764805 if ( latestTheme !== currentTheme ) {
765806 applyTheme ( latestTheme , false ) ;
766807 }
767808 } ) ;
768809 window . addEventListener ( "storage" , ( event ) => {
810+ if ( event . key === M3_PALETTE_STORAGE_KEY && event . newValue ) {
811+ if ( ! MATERIAL3_PALETTES . includes ( event . newValue ) ) return ;
812+ if ( event . newValue !== currentMaterial3Palette ) {
813+ applyMaterial3Palette ( event . newValue , false ) ;
814+ }
815+ return ;
816+ }
817+
769818 if ( event . key !== THEME_STORAGE_KEY || ! event . newValue ) return ;
770819 if ( ! THEME_OPTIONS . includes ( event . newValue ) ) return ;
771820 if ( event . newValue !== currentTheme ) {
@@ -776,6 +825,10 @@ function initThemeSwitcher() {
776825 applyTheme ( event . target . value , true ) ;
777826 } ) ;
778827
828+ material3PaletteSelect ?. addEventListener ( "change" , ( event ) => {
829+ applyMaterial3Palette ( event . target . value , true ) ;
830+ } ) ;
831+
779832 themeCycleBtn ?. addEventListener ( "click" , ( ) => {
780833 const idx = THEME_OPTIONS . indexOf ( currentTheme ) ;
781834 const next = THEME_OPTIONS [ ( idx + 1 + THEME_OPTIONS . length ) % THEME_OPTIONS . length ] ;
@@ -1436,6 +1489,9 @@ function initCommandPalette() {
14361489 { label : "Theme: Sunset Warp" , keywords : "theme sunset orange" , run : ( ) => applyTheme ( "sunset" , true ) } ,
14371490 { label : "Theme: Liquid Glass" , keywords : "theme liquid glass apple" , run : ( ) => applyTheme ( "liquidglass" , true ) } ,
14381491 { label : "Theme: Material 3" , keywords : "theme material3 google" , run : ( ) => applyTheme ( "material3" , true ) } ,
1492+ { label : "M3 Palette: Lavender" , keywords : "material3 palette lavender" , run : ( ) => applyMaterial3Palette ( "lavender" , true ) } ,
1493+ { label : "M3 Palette: Emerald" , keywords : "material3 palette emerald" , run : ( ) => applyMaterial3Palette ( "emerald" , true ) } ,
1494+ { label : "M3 Palette: Sunset" , keywords : "material3 palette sunset" , run : ( ) => applyMaterial3Palette ( "sunset" , true ) } ,
14391495 { label : "Theme: Paper Link" , keywords : "theme paper" , run : ( ) => applyTheme ( "paper" , true ) } ,
14401496 { label : "Theme: Black Flag Uprising" , keywords : "theme blackflag anarchy" , run : ( ) => applyTheme ( "blackflag" , true ) } ,
14411497 { label : "Mode: Toggle Matrix Rain" , keywords : "matrix rain mode" , run : ( ) => toggleMatrixMode ( ) } ,
0 commit comments