136136 cursor : pointer;
137137 }
138138 .lang-bar : hover { opacity : 0.85 ; }
139+ .lang-bar .lang-active { outline : 2px solid # 2D2D2D ; outline-offset : -2px ; }
139140 .lang-legend {
140141 display : flex; flex-wrap : wrap; gap : 12px ; margin-top : 12px ;
141142 font-size : 0.72rem ; color : # 9CA3AF ;
142143 }
143- .lang-legend-item { display : flex; align-items : center; gap : 5px ; }
144+ .lang-legend-item { display : flex; align-items : center; gap : 5px ; transition : color 0.15s ; }
145+ .lang-legend-item : hover { color : # 2D2D2D ; }
146+ .lang-legend-active { color : # F97B6D ; font-weight : 600 ; }
144147 .lang-dot { width : 8px ; height : 8px ; border-radius : 2px ; flex-shrink : 0 ; }
145148
146149 /* Explore table */
@@ -585,6 +588,7 @@ <h1>The largest classified corpus of Word documents</h1>
585588 if ( data . facets ) {
586589 renderTypesGrid ( data . facets . types ) ;
587590 renderTopicsGrid ( data . facets . topics ) ;
591+ renderLangStrip ( data . facets . languages ) ;
588592 }
589593 } catch {
590594 $ ( 'explore-count' ) . textContent = 'API unavailable' ;
@@ -636,37 +640,35 @@ <h1>The largest classified corpus of Word documents</h1>
636640 } ) ;
637641 }
638642
639- // ---------- render stats ----------
640- function renderStats ( stats ) {
641- const h = stats . hero ;
642- $ ( 'stat-docs' ) . textContent = fmt ( h . total_documents ) ;
643- $ ( 'stat-langs' ) . textContent = h . languages ;
644- $ ( 'stat-taxonomy' ) . textContent = `${ h . types } \u00d7 ${ h . topics } ` ;
645- $ ( 'stat-conf' ) . textContent = ( h . avg_confidence * 100 ) . toFixed ( 0 ) + '%' ;
646-
647- renderTypesGrid ( stats . types ) ;
648- renderTopicsGrid ( stats . topics ) ;
649-
650- // Language strip
651- const topLangs = stats . languages . slice ( 0 , 10 ) ;
652- const otherPct = stats . languages . slice ( 10 ) . reduce ( ( s , l ) => s + l . percentage , 0 ) ;
643+ function renderLangStrip ( languages ) {
644+ const topLangs = languages . slice ( 0 , 10 ) ;
645+ const otherPct = languages . slice ( 10 ) . reduce ( ( s , l ) => s + l . percentage , 0 ) ;
653646
647+ // Bar: top 10 + "other" segment
654648 let langHtml = '' ;
655- let legendHtml = '' ;
656649 topLangs . forEach ( ( l , i ) => {
657650 const color = i < 5 ? CORAL_SHADES [ i ] : GRAY_SHADES [ i - 5 ] ;
658- langHtml += `<div class="lang-bar" style="flex: ${ l . percentage } ;background: ${ color } " data- lang=" ${ l . code } " title=" ${ l . name } ${ l . percentage } %"> ${ l . code . toUpperCase ( ) } </div>` ;
659- legendHtml += `<div class="lang-legend-item"><span class=" lang-dot " style="background:${ color } "></span> ${ l . name } ${ l . percentage } %</div>` ;
651+ const active = filters . lang === l . code ;
652+ langHtml += `<div class="lang-bar ${ active ? ' lang-active' : '' } " style="flex: ${ l . percentage } ; background:${ color } " data-lang=" ${ l . code } " title=" ${ l . name } ${ l . percentage } %"> ${ l . code . toUpperCase ( ) } </div>` ;
660653 } ) ;
661654 if ( otherPct > 0 ) {
662- langHtml += `<div class="lang-bar" style="flex:${ otherPct } ;background:#d0d0d0;color:#888;font-size:0.6rem">+${ stats . languages . length - 10 } </div>` ;
655+ langHtml += `<div class="lang-bar" style="flex:${ otherPct } ;background:#d0d0d0;color:#888;font-size:0.6rem">+${ languages . length - 10 } </div>` ;
663656 }
664657
658+ // Legend: ALL languages, clickable
659+ let legendHtml = '' ;
660+ languages . forEach ( ( l , i ) => {
661+ const color = i < 5 ? CORAL_SHADES [ i ] : i < 10 ? GRAY_SHADES [ i - 5 ] : '#d0d0d0' ;
662+ const active = filters . lang === l . code ;
663+ legendHtml += `<div class="lang-legend-item${ active ? ' lang-legend-active' : '' } " data-lang="${ l . code } " style="cursor:pointer"><span class="lang-dot" style="background:${ color } "></span>${ l . name } ${ l . percentage } %</div>` ;
664+ } ) ;
665+
665666 $ ( 'lang-row' ) . innerHTML = langHtml ;
666667 $ ( 'lang-legend' ) . innerHTML = legendHtml ;
667668
668- document . querySelectorAll ( '.lang-bar[data-lang]' ) . forEach ( bar => {
669- bar . addEventListener ( 'click' , function ( ) {
669+ // Click handlers for both bars and legend items
670+ document . querySelectorAll ( '[data-lang]' ) . forEach ( el => {
671+ el . addEventListener ( 'click' , function ( ) {
670672 filters . lang = filters . lang === this . dataset . lang ? '' : this . dataset . lang ;
671673 currentPage = 1 ;
672674 updateActiveStates ( ) ;
@@ -676,6 +678,19 @@ <h1>The largest classified corpus of Word documents</h1>
676678 } ) ;
677679 }
678680
681+ // ---------- render stats ----------
682+ function renderStats ( stats ) {
683+ const h = stats . hero ;
684+ $ ( 'stat-docs' ) . textContent = fmt ( h . total_documents ) ;
685+ $ ( 'stat-langs' ) . textContent = h . languages ;
686+ $ ( 'stat-taxonomy' ) . textContent = `${ h . types } \u00d7 ${ h . topics } ` ;
687+ $ ( 'stat-conf' ) . textContent = ( h . avg_confidence * 100 ) . toFixed ( 0 ) + '%' ;
688+
689+ renderTypesGrid ( stats . types ) ;
690+ renderTopicsGrid ( stats . topics ) ;
691+ renderLangStrip ( stats . languages ) ;
692+ }
693+
679694 function renderSkeletons ( ) {
680695 $ ( 'types-grid' ) . innerHTML = Array ( 10 ) . fill (
681696 '<div class="skeleton skeleton-cell" style="width:100%"></div>'
0 commit comments