395395 min-width : unset;
396396 }
397397 }
398+ /* Rich search result styles */
399+ # searchResults {
400+ display : none;
401+ position : absolute;
402+ top : calc (100% + 4px );
403+ left : 0 ;
404+ background-color : var (--bg-secondary );
405+ width : 320px ;
406+ box-shadow : 0 8px 24px rgba (0 , 0 , 0 , 0.5 );
407+ border : 1px solid var (--accent-color );
408+ z-index : 200 ;
409+ max-height : 400px ;
410+ overflow-y : auto;
411+ }
412+ # searchResults a {
413+ display : flex;
414+ flex-direction : column;
415+ padding : 10px 14px ;
416+ text-decoration : none;
417+ border-bottom : 1px solid # 2a2a2a ;
418+ transition : background-color 0.2s ease;
419+ }
420+ # searchResults a : hover {
421+ background-color : # 2a2a2a ;
422+ }
423+ .result-title {
424+ font-family : 'Inknut Antiqua' , serif;
425+ font-size : 13px ;
426+ color : var (--red );
427+ margin-bottom : 3px ;
428+ }
429+ .result-title strong { color : # cc3355 ; }
430+ .result-meta {
431+ display : flex;
432+ flex-direction : column;
433+ gap : 2px ;
434+ }
435+ .result-category {
436+ font-size : 10px ;
437+ color : # 666 ;
438+ text-transform : uppercase;
439+ letter-spacing : 0.1em ;
440+ }
441+ .result-snippet {
442+ font-size : 11px ;
443+ color : # 888 ;
444+ line-height : 1.4 ;
445+ }
446+ .result-snippet strong { color : # aaa ; }
447+ .no-results {
448+ padding : 12px 14px ;
449+ font-size : 12px ;
450+ color : # 666 ;
451+ font-style : italic;
452+ }
398453 </ style >
399454</ head >
400455
@@ -489,117 +544,7 @@ <h5>3 / Publication Title</h5>
489544 < span class ="quote "> Quod Latet, Se Aperit Quaerenti</ span >
490545 < span class ="copyright "> © 2025 The Liminal Archive</ span >
491546 </ footer >
492- < script >
493- console . log ( "Search script started" ) ;
494-
495- let searchData = [ ] ;
496-
497- fetch ( "/titles.json" )
498- . then ( response => {
499- if ( ! response . ok ) {
500- throw new Error ( `HTTP error! Status: ${ response . status } ` ) ;
501- }
502- return response . text ( ) ;
503- } )
504- . then ( text => {
505- console . log ( "Raw titles.json response:" , text ) ;
506- try {
507- const data = JSON . parse ( text ) ;
508- console . log ( "titles.json parsed successfully:" , data ) ;
509- searchData = data ;
510- } catch ( e ) {
511- throw new Error ( "JSON parse error: " + e . message ) ;
512- }
513-
514- const searchBar = document . getElementById ( 'searchBar' ) ;
515- const searchButton = document . getElementById ( 'searchButton' ) ;
516- const resultsDiv = document . getElementById ( 'searchResults' ) ;
517-
518- if ( ! searchBar || ! searchButton || ! resultsDiv ) {
519- console . error ( "One or more elements not found:" , { searchBar, searchButton, resultsDiv } ) ;
520- return ;
521- }
522-
523- console . log ( "Search elements found" ) ;
524-
525- function showDropdownResults ( searchTerm ) {
526- resultsDiv . innerHTML = '' ;
527-
528- if ( searchTerm . length === 0 ) {
529- resultsDiv . style . display = 'none' ;
530- return ;
531- }
532-
533- const matches = searchData . filter ( item =>
534- item . title . toLowerCase ( ) . includes ( searchTerm )
535- ) ;
536-
537- if ( matches . length > 0 ) {
538- matches . forEach ( item => {
539- const resultItem = document . createElement ( "p" ) ;
540- const link = document . createElement ( "a" ) ;
541- link . href = item . url ;
542- link . textContent = item . title ;
543- resultItem . appendChild ( link ) ;
544- resultsDiv . appendChild ( resultItem ) ;
545- } ) ;
546- resultsDiv . style . display = 'block' ;
547- } else {
548- resultsDiv . innerHTML = `<p>No matching titles found.</p>` ;
549- resultsDiv . style . display = 'block' ;
550- }
551- }
552-
553- searchBar . addEventListener ( 'input' , ( ) => {
554- const searchTerm = searchBar . value . trim ( ) . toLowerCase ( ) ;
555- console . log ( "Input event. Searching for:" , searchTerm ) ;
556- showDropdownResults ( searchTerm ) ;
557- } ) ;
558-
559- searchButton . addEventListener ( 'click' , ( ) => {
560- const searchTerm = searchBar . value . trim ( ) . toLowerCase ( ) ;
561- console . log ( "Button clicked. Searching for:" , searchTerm ) ;
562- const firstMatch = searchData . find ( item =>
563- item . title . toLowerCase ( ) . includes ( searchTerm )
564- ) ;
565- if ( firstMatch ) {
566- console . log ( "Navigating to:" , firstMatch . url ) ;
567- window . location . href = firstMatch . url ;
568- } else {
569- console . log ( "No matches for navigation" ) ;
570- showDropdownResults ( searchTerm ) ;
571- }
572- } ) ;
573-
574- searchBar . addEventListener ( 'keypress' , function ( e ) {
575- if ( e . key === 'Enter' ) {
576- const searchTerm = searchBar . value . trim ( ) . toLowerCase ( ) ;
577- console . log ( "Enter key pressed. Searching for:" , searchTerm ) ;
578- const firstMatch = searchData . find ( item =>
579- item . title . toLowerCase ( ) . includes ( searchTerm )
580- ) ;
581- if ( firstMatch ) {
582- console . log ( "Navigating to:" , firstMatch . url ) ;
583- window . location . href = firstMatch . url ;
584- } else {
585- console . log ( "No matches for navigation" ) ;
586- showDropdownResults ( searchTerm ) ;
587- }
588- }
589- } ) ;
590-
591- document . addEventListener ( 'click' , function ( e ) {
592- if ( ! searchBar . contains ( e . target ) && ! searchButton . contains ( e . target ) && ! resultsDiv . contains ( e . target ) ) {
593- console . log ( "Clicked outside. Hiding results" ) ;
594- resultsDiv . style . display = 'none' ;
595- }
596- } ) ;
597- } )
598- . catch ( error => {
599- console . error ( "Error loading titles.json:" , error . message ) ;
600- console . error ( "Check titles.json at your GitHub Pages root (e.g., https://your-username.github.io/your-repo/titles.json)." ) ;
601- } ) ;
602- </ script >
547+ < script src ="search.js "> </ script >
603548</ body >
604549
605550</ html >
0 commit comments