1313< link rel ="apple-touch-icon " sizes ="180x180 " href ="/favicon/apple-touch-icon.png ">
1414< link rel ="icon " type ="image/png " sizes ="32x32 " href ="/favicon/favicon-32x32.png ">
1515< link rel ="icon " type ="image/png " sizes ="16x16 " href ="/favicon/favicon-16x16.png ">
16+ < link rel ="preload " href ="/assets/images/logo-light.svg " as ="image " type ="image/svg+xml ">
17+ < link rel ="preload " href ="/assets/images/logo-dark.svg " as ="image " type ="image/svg+xml ">
1618< link rel ="license " href ="https://www.gnu.org/licenses/agpl-3.0.html ">
1719< link href ="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;500;700&family=Lexend:wght@400;500;700&family=Montserrat:wght@400;500;700&family=Atkinson+Hyperlegible:wght@400;700&display=swap " rel ="stylesheet ">
1820< style >
120122--color-dark-gray : # 666 ;
121123}
122124
125+ body .dark-mode # siteLogo {
126+ content : url ("/assets/images/logo-dark.svg" );
127+ }
128+
123129main {
124130flex : 1 ;
125131}
317323background : # 222 ;
318324}
319325
320- .greeting-container {
321- display : flex;
322- align-items : center;
323- gap : 1rem ;
324- margin-bottom : 1rem ;
325- margin : 0 auto;
326- }
327-
328- .greeting-icon svg {
329- width : 32px ;
330- height : 32px ;
331- }
332-
333- .greeting-text h2 {
334- font-size : var (--text-2xl );
335- margin-bottom : 0.5rem ;
336- font-weight : 500 ;
337- }
338-
339- .mind-booster {
340- font-size : var (--text-md );
341- font-style : italic;
342- color : var (--color-secondary );
343- margin-top : 1rem ;
344- }
345-
346326.documents-container {
347327max-width : var (--max-width );
348328background-color : var (--white );
652632color : var (--color-primary );
653633}
654634
635+ .page-select {
636+ position : relative;
637+ display : inline-block;
638+ }
639+
640+ .page-select-toggle {
641+ padding : 0.5rem 1rem ;
642+ border : 1px dashed var (--color-secondary );
643+ border-radius : var (--radius-sm );
644+ min-width : 60px ;
645+ text-align : center;
646+ cursor : pointer;
647+ position : relative;
648+ background : var (--white );
649+ color : var (--color-primary );
650+ }
651+
652+ .page-select-toggle ::after {
653+ content : "▼" ;
654+ margin-left : 8px ;
655+ font-size : 0.8em ;
656+ }
657+
658+ .page-select-dropdown {
659+ position : absolute;
660+ top : 100% ;
661+ left : 50% ;
662+ transform : translateX (-50% );
663+ background : var (--white );
664+ border : 1px solid var (--color-gray );
665+ border-radius : var (--radius-sm );
666+ box-shadow : var (--shadow-md );
667+ z-index : 10 ;
668+ display : none;
669+ max-height : 200px ;
670+ overflow-y : auto;
671+ width : 80px ;
672+ }
673+
674+ .page-select-dropdown .show {
675+ display : block;
676+ }
677+
678+ .page-select-item {
679+ padding : 0.5rem ;
680+ text-align : center;
681+ cursor : pointer;
682+ }
683+
684+ .page-select-item : hover {
685+ background : var (--color-light );
686+ }
687+
655688.modal {
656689position : fixed;
657690top : 0 ;
10401073max-height : 80vh ;
10411074}
10421075
1043- .greeting-text h2 {
1044- font-size : var (--text-xl );
1045- }
1046-
10471076.documents-grid {
10481077grid-template-columns : 1fr ;
10491078}
11331162</ aside >
11341163
11351164< main id ="main-content " role ="main ">
1136- < section class ="hero ">
1137- < div class ="greeting-container ">
1138- < div class ="greeting-icon " id ="time-icon ">
1139- </ div >
1140- < div class ="greeting-text ">
1141- < h2 > < span id ="greeting-text "> Good Morning</ span > </ h2 >
1142- </ div >
1143- </ div >
1144- < p class ="mind-booster "> < strong > Your daily booster</ strong > : < span id ="mind-booster "> Perfection is an infinite journey, just start.</ span > </ p >
1145- </ section >
11461165
11471166< section class ="documents-container ">
11481167< div class ="document-controls ">
@@ -1237,7 +1256,10 @@ <h2><span id="greeting-text">Good Morning</span></h2>
12371256< path d ="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z "/>
12381257</ svg >
12391258</ button >
1240- < span class ="page-number " id ="current-page " contenteditable ="true "> 1</ span >
1259+ < div class ="page-select ">
1260+ < div class ="page-select-toggle " id ="page-select-toggle " aria-haspopup ="true " aria-expanded ="false "> 1</ div >
1261+ < div class ="page-select-dropdown " id ="page-select-dropdown " role ="menu "> </ div >
1262+ </ div >
12411263< span > /</ span >
12421264< span id ="total-pages "> 1</ span >
12431265< button class ="pagination-button " id ="next-page " disabled aria-label ="Next page ">
@@ -1450,48 +1472,6 @@ <h3>Read Aloud</h3>
14501472} ) ;
14511473} ) ;
14521474
1453- // Quotes data
1454- const quotes = [
1455- "Perfection is an infinite journey, just start." ,
1456- "Small steps every day lead to big results over time." ,
1457- "The expert in anything was once a beginner." ,
1458- "Done is better than perfect." ,
1459- "Progress, not perfection, is the goal." ,
1460- "Consistency is the key to mastery." ,
1461- "Every masterpiece started as a draft." ,
1462- "You don't have to be great to start, but you have to start to be great." ,
1463- "The only way to do great work is to love what you do." ,
1464- "Quality is not an act, it's a habit."
1465- ] ;
1466-
1467- // Time-based greeting
1468- function updateGreeting ( ) {
1469- const now = new Date ( ) ;
1470- const hours = now . getHours ( ) ;
1471- let greeting , icon ;
1472-
1473- if ( hours >= 5 && hours < 12 ) {
1474- greeting = "Wake and shine" ;
1475- icon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79 1.42-1.41zM4 10.5H1v2h3v-2zm9-9.95h-2V3.5h2V.55zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41 1.79-1.79zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM20 10.5v2h3v-2h-3zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2v2.95zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8z"/></svg>` ;
1476- } else if ( hours >= 12 && hours < 17 ) {
1477- greeting = "Sun's still high" ;
1478- icon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41l-1.06-1.06zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z"/></svg>` ;
1479- } else if ( hours >= 17 && hours < 21 ) {
1480- greeting = "Evening greetings" ;
1481- icon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z"/></svg>` ;
1482- } else {
1483- greeting = "Shut-eye time" ;
1484- icon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12.34 2.02C6.59 1.82 2 6.42 2 12c0 5.52 4.48 10 10 10 3.71 0 6.93-2.02 8.66-5.02-7.51-.25-12.09-8.43-8.32-14.96z"/></svg>` ;
1485- }
1486-
1487- document . getElementById ( 'greeting-text' ) . textContent = greeting ;
1488- document . getElementById ( 'time-icon' ) . innerHTML = icon ;
1489-
1490- // Random quote
1491- const randomQuote = quotes [ Math . floor ( Math . random ( ) * quotes . length ) ] ;
1492- document . getElementById ( 'mind-booster' ) . textContent = randomQuote ;
1493- }
1494-
14951475// Format time ago
14961476function formatTimeAgo ( dateString ) {
14971477const now = new Date ( ) ;
@@ -1651,6 +1631,27 @@ <h3>Read Aloud</h3>
16511631document . getElementById ( 'prev-page' ) . title = currentPage === 1 ? 'You are on the first page' : 'Previous page' ;
16521632document . getElementById ( 'next-page' ) . title = currentPage === totalPages ? 'You are on the last page' : 'Next page' ;
16531633
1634+ // Update page dropdown
1635+ const pageToggle = document . getElementById ( 'page-select-toggle' ) ;
1636+ const pageDropdown = document . getElementById ( 'page-select-dropdown' ) ;
1637+ pageToggle . textContent = currentPage ;
1638+ pageToggle . setAttribute ( 'aria-label' , `Current page: ${ currentPage } ` ) ;
1639+
1640+ // Populate dropdown with page numbers
1641+ pageDropdown . innerHTML = '' ;
1642+ for ( let i = 1 ; i <= totalPages ; i ++ ) {
1643+ const pageItem = document . createElement ( 'div' ) ;
1644+ pageItem . className = 'page-select-item' ;
1645+ pageItem . textContent = i ;
1646+ pageItem . addEventListener ( 'click' , ( ) => {
1647+ currentPage = i ;
1648+ applyFiltersAndSort ( ) ;
1649+ pageDropdown . classList . remove ( 'show' ) ;
1650+ pageToggle . setAttribute ( 'aria-expanded' , 'false' ) ;
1651+ } ) ;
1652+ pageDropdown . appendChild ( pageItem ) ;
1653+ }
1654+
16541655const startIdx = ( currentPage - 1 ) * docsPerPage ;
16551656const endIdx = Math . min ( startIdx + docsPerPage , docs . length ) ;
16561657
@@ -1830,7 +1831,6 @@ <h3>Read Aloud</h3>
18301831if ( currentPage > 1 ) {
18311832currentPage -- ;
18321833applyFiltersAndSort ( ) ;
1833- document . getElementById ( 'current-page' ) . textContent = currentPage ;
18341834}
18351835} ) ;
18361836
@@ -1839,31 +1839,29 @@ <h3>Read Aloud</h3>
18391839if ( currentPage < totalPages ) {
18401840currentPage ++ ;
18411841applyFiltersAndSort ( ) ;
1842- document . getElementById ( 'current-page' ) . textContent = currentPage ;
18431842}
18441843} ) ;
18451844
1846- document . getElementById ( 'current-page' ) . addEventListener ( 'blur' , ( ) => {
1847- const totalPages = Math . ceil ( documents . length / docsPerPage ) ;
1848- let newPage = parseInt ( document . getElementById ( 'current- page' ) . textContent ) ;
1845+ // Page dropdown functionality
1846+ const pageToggle = document . getElementById ( 'page-select-toggle' ) ;
1847+ const pageDropdown = document . getElementById ( 'page-select-dropdown' ) ;
18491848
1850- if ( isNaN ( newPage ) || newPage < 1 ) {
1851- newPage = 1 ;
1852- } else if ( newPage > totalPages ) {
1853- newPage = totalPages ;
1854- showModal ( 'page-modal ') ;
1855- }
1849+ pageToggle . addEventListener ( 'click' , ( e ) => {
1850+ e . stopPropagation ( ) ;
1851+ const isExpanded = pageToggle . getAttribute ( 'aria-expanded' ) === 'true' ;
1852+ pageToggle . setAttribute ( 'aria-expanded' , ! isExpanded ) ;
1853+ pageDropdown . classList . toggle ( 'show ') ;
1854+ } ) ;
18561855
1857- currentPage = newPage ;
1858- document . getElementById ( 'current-page' ) . textContent = currentPage ;
1859- applyFiltersAndSort ( ) ;
1856+ // Close dropdown when clicking outside
1857+ document . addEventListener ( 'click' , ( ) => {
1858+ pageDropdown . classList . remove ( 'show' ) ;
1859+ pageToggle . setAttribute ( 'aria-expanded' , 'false' ) ;
18601860} ) ;
18611861
1862- document . getElementById ( 'current-page' ) . addEventListener ( 'keydown' , ( e ) => {
1863- if ( e . key === 'Enter' ) {
1864- e . preventDefault ( ) ;
1865- document . getElementById ( 'current-page' ) . blur ( ) ;
1866- }
1862+ // Close dropdown when selecting a page
1863+ pageDropdown . addEventListener ( 'click' , ( e ) => {
1864+ e . stopPropagation ( ) ;
18671865} ) ;
18681866}
18691867
@@ -2186,7 +2184,6 @@ <h3>Read Aloud</h3>
21862184}
21872185
21882186function init ( ) {
2189- updateGreeting ( ) ;
21902187loadDocuments ( ) ;
21912188setupPagination ( ) ;
21922189setupSearchAndFilters ( ) ;
0 commit comments