Spaces:
Running
Running
| custom_css = """ | |
| /* ===== FORCE LIGHT MODE ===== */ | |
| /* Override Gradio's dark mode completely - this app is light mode only */ | |
| :root, html, body, .gradio-container, .dark, body.dark, html.dark { | |
| --body-background-fill: white !important; | |
| --background-fill-primary: white !important; | |
| --background-fill-secondary: #f9fafb !important; | |
| --body-text-color: #1f2937 !important; | |
| --body-text-color-subdued: #6b7280 !important; | |
| --block-background-fill: white !important; | |
| --block-border-color: #e5e7eb !important; | |
| --block-label-background-fill: #f3f4f6 !important; | |
| --block-label-text-color: #374151 !important; | |
| --block-title-text-color: #111827 !important; | |
| --input-background-fill: white !important; | |
| --input-border-color: #d1d5db !important; | |
| --table-even-background-fill: #f9fafb !important; | |
| --table-odd-background-fill: white !important; | |
| --table-row-focus: #e0f2fe !important; | |
| --table-border-color: #e5e7eb !important; | |
| --border-color-primary: #e5e7eb !important; | |
| --border-color-accent: #8CD0FF !important; | |
| --color-accent: #8CD0FF !important; | |
| --neutral-50: #f9fafb !important; | |
| --neutral-100: #f3f4f6 !important; | |
| --neutral-200: #e5e7eb !important; | |
| --neutral-300: #d1d5db !important; | |
| --neutral-400: #9ca3af !important; | |
| --neutral-500: #6b7280 !important; | |
| --neutral-600: #4b5563 !important; | |
| --neutral-700: #374151 !important; | |
| --neutral-800: #1f2937 !important; | |
| --neutral-900: #111827 !important; | |
| --neutral-950: #030712 !important; | |
| } | |
| /* Apply light mode background to main containers only, exclude Plotly */ | |
| html, body, .gradio-container { | |
| background: white !important; | |
| color: #1f2937 !important; | |
| } | |
| /* Force light mode on Gradio table components (not Plotly) */ | |
| .dark .svelte-table, body.dark .svelte-table, | |
| .dark [data-testid="dataframe"], body.dark [data-testid="dataframe"], | |
| .table-wrap:not(.js-plotly-plot *), | |
| .dataframe:not(.js-plotly-plot *) { | |
| background: white !important; | |
| color: #1f2937 !important; | |
| } | |
| /* Target Gradio tables specifically, exclude Plotly SVG tables */ | |
| .gradio-container table:not(.js-plotly-plot table), | |
| .dark .gradio-container table:not(.js-plotly-plot table) { | |
| background: white !important; | |
| color: #1f2937 !important; | |
| } | |
| .gradio-container th:not(.js-plotly-plot th), | |
| .gradio-container td:not(.js-plotly-plot td), | |
| .dark .gradio-container th:not(.js-plotly-plot th), | |
| .dark .gradio-container td:not(.js-plotly-plot td) { | |
| background-color: inherit !important; | |
| color: #1f2937 !important; | |
| border-color: #e5e7eb !important; | |
| } | |
| .gradio-container thead:not(.js-plotly-plot thead), | |
| .dark .gradio-container thead:not(.js-plotly-plot thead) { | |
| background: #f8fafc !important; | |
| } | |
| .gradio-container tbody tr:nth-child(even):not(.js-plotly-plot tr), | |
| .dark .gradio-container tbody tr:nth-child(even):not(.js-plotly-plot tr) { | |
| background: #f9fafb !important; | |
| } | |
| .gradio-container tbody tr:nth-child(odd):not(.js-plotly-plot tr), | |
| .dark .gradio-container tbody tr:nth-child(odd):not(.js-plotly-plot tr) { | |
| background: white !important; | |
| } | |
| /* Override prefers-color-scheme dark for main elements */ | |
| @media (prefers-color-scheme: dark) { | |
| :root, html, body, .gradio-container { | |
| --body-background-fill: white !important; | |
| --background-fill-primary: white !important; | |
| --body-text-color: #1f2937 !important; | |
| background: white !important; | |
| color: #1f2937 !important; | |
| } | |
| } | |
| /* Ensure Plotly charts render correctly - DO NOT override their styles */ | |
| .js-plotly-plot, .js-plotly-plot *, | |
| .plotly, .plotly *, | |
| .js-plotly-plot svg, .js-plotly-plot svg * { | |
| background: unset !important; | |
| background-color: unset !important; | |
| } | |
| /* Reset Plotly container backgrounds */ | |
| .js-plotly-plot .plotly .main-svg, | |
| .js-plotly-plot .plotly .bg { | |
| fill: white !important; | |
| } | |
| /* Microsoft-style font family - using system fonts with proper bold weights */ | |
| /* Note: Segoe UI from cdnfonts may not have all weights, rely on system fallbacks */ | |
| /* Apply font globally */ | |
| .gradio-container, | |
| .gradio-container *, | |
| body { | |
| font-family: 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif; | |
| } | |
| /* Bold text weights */ | |
| b, strong, | |
| .gradio-container b, | |
| .gradio-container strong, | |
| .prose b, | |
| .prose strong, | |
| .md b, | |
| .md strong, | |
| .markdown-code b, | |
| .markdown-code strong, | |
| [class*="markdown"] b, | |
| [class*="markdown"] strong, | |
| p b, p strong, | |
| span b, span strong, | |
| div b, div strong { | |
| font-weight: 600 !important; | |
| } | |
| /* Banner image styling */ | |
| #banner-image { | |
| width: 100%; | |
| margin-bottom: 1rem; | |
| } | |
| #banner-image img { | |
| width: 100%; | |
| height: auto; | |
| object-fit: contain; | |
| border-radius: 8px; | |
| } | |
| /* Custom metric table variables (light mode only) */ | |
| :root { | |
| --metric-table-bg: #ffffff; | |
| --metric-table-border: #d3d3d3; | |
| --metric-table-header-bg: #f8fafc; | |
| --metric-table-header-color: #0f172a; | |
| --metric-table-row-header-bg: #f2f5f9; | |
| --metric-table-caption: #666666; | |
| --metric-table-empty-color: #777777; | |
| --metric-table-row-highlight: #DDF1FF; | |
| } | |
| /* ===== GLOBAL TEXT SELECTION FIX ===== */ | |
| /* Fix text selection highlight for better contrast in dark mode */ | |
| ::selection { | |
| background-color: rgba(140, 208, 255, 0.4) !important; | |
| color: inherit !important; | |
| } | |
| ::-moz-selection { | |
| background-color: rgba(140, 208, 255, 0.4) !important; | |
| color: inherit !important; | |
| } | |
| /* PazaBench brand color for buttons */ | |
| button.primary { | |
| background-color: #8CD0FF !important; | |
| border-color: #8CD0FF !important; | |
| color: #0f172a !important; | |
| } | |
| button.primary:hover { | |
| background-color: #6bc0f5 !important; | |
| border-color: #6bc0f5 !important; | |
| color: #0f172a !important; | |
| } | |
| /* WCAG 4.1.2 Fix: Make buttons inside aria-hidden containers non-interactive */ | |
| /* Neutralize focusable buttons in aria-hidden containers */ | |
| .visually-hidden[aria-hidden="true"] button, | |
| [aria-hidden="true"] .tab-container button, | |
| .tab-container.visually-hidden[aria-hidden="true"] button, | |
| div[aria-hidden="true"] button { | |
| pointer-events: none !important; | |
| visibility: hidden !important; | |
| } | |
| /* Link color + markdown table styling */ | |
| a { | |
| text-decoration: none; | |
| color: #464feb; | |
| } | |
| /* Change Log cards: remove link horizontal padding */ | |
| .changelog-cards a { | |
| padding-left: 0; | |
| padding-right: 0; | |
| } | |
| .markdown-text table th, | |
| .markdown-text table td { | |
| border: 1px solid #e6e6e6; | |
| } | |
| .markdown-text table th { | |
| background-color: #f5f5f5; | |
| } | |
| /* Scroll the tall Sample Distribution chart inside a fixed-height container. */ | |
| #language-coverage-plot { | |
| max-height: 640px !important; | |
| overflow-y: auto !important; | |
| overflow-x: hidden !important; | |
| } | |
| /* Hide the Plotly logo ("Produced with Plotly") from every chart's modebar. */ | |
| .js-plotly-plot .modebar-btn--logo, | |
| .js-plotly-plot a[data-title="Produced with Plotly"] { | |
| display: none !important; | |
| } | |
| /* Typography hierarchy */ | |
| .markdown-text { | |
| font-size: 16px !important; | |
| line-height: 1.6 !important; | |
| } | |
| /* ===== FILTER & CUSTOMIZE ACCORDION STYLING ===== */ | |
| /* Match accordion text size to 15px */ | |
| #filter-customize-accordion .label-wrap span, | |
| #filter-customize-accordion .label-wrap .open-button, | |
| #filter-customize-accordion > div > button span { | |
| font-size: 15px !important; | |
| font-weight: 400 !important; /* Regular, not bold */ | |
| } | |
| /* ===== EXPLAINER TEXT STYLING ===== */ | |
| /* Reduce font size for 'Compare models at a glance' to 15px */ | |
| .explainer-text, | |
| .explainer-text h3, | |
| .explainer-text p { | |
| font-size: 15px !important; | |
| line-height: 1.5 !important; | |
| } | |
| /* ===== LEADERBOARD TABLE ROW NUMBER COLUMN ===== */ | |
| /* Make row number column (first column with empty header) narrow and regular weight */ | |
| #wer-leaderboard-table th:first-child, | |
| #cer-leaderboard-table th:first-child, | |
| #rtfx-leaderboard-table th:first-child { | |
| width: 40px !important; | |
| min-width: 40px !important; | |
| max-width: 60px !important; | |
| font-weight: 400 !important; | |
| } | |
| #wer-leaderboard-table td:first-child, | |
| #cer-leaderboard-table td:first-child, | |
| #rtfx-leaderboard-table td:first-child { | |
| width: 40px !important; | |
| min-width: 40px !important; | |
| max-width: 60px !important; | |
| font-weight: 400 !important; /* Regular, not bold */ | |
| text-align: center; | |
| } | |
| /* ===== LANGUAGE COLUMN BACKGROUND COLOR ===== */ | |
| /* Make language column (second column) have a light blue background for differentiation */ | |
| #wer-leaderboard-table th:nth-child(2), | |
| #cer-leaderboard-table th:nth-child(2), | |
| #rtfx-leaderboard-table th:nth-child(2) { | |
| background-color: #EEF8FF !important; | |
| } | |
| #wer-leaderboard-table td:nth-child(2), | |
| #cer-leaderboard-table td:nth-child(2), | |
| #rtfx-leaderboard-table td:nth-child(2) { | |
| background-color: #EEF8FF !important; | |
| } | |
| /* Dark mode language column - slightly muted blue */ | |
| body.dark #wer-leaderboard-table th:nth-child(2), | |
| body.dark #cer-leaderboard-table th:nth-child(2), | |
| body.dark #rtfx-leaderboard-table th:nth-child(2), | |
| body.dark #wer-leaderboard-table td:nth-child(2), | |
| body.dark #cer-leaderboard-table td:nth-child(2), | |
| body.dark #rtfx-leaderboard-table td:nth-child(2), | |
| [data-theme="dark"] #wer-leaderboard-table th:nth-child(2), | |
| [data-theme="dark"] #cer-leaderboard-table th:nth-child(2), | |
| [data-theme="dark"] #rtfx-leaderboard-table th:nth-child(2), | |
| [data-theme="dark"] #wer-leaderboard-table td:nth-child(2), | |
| [data-theme="dark"] #cer-leaderboard-table td:nth-child(2), | |
| [data-theme="dark"] #rtfx-leaderboard-table td:nth-child(2) { | |
| background-color: rgba(140, 208, 255, 0.3) !important; | |
| } | |
| /* ===== HIDE GRADIO DATAFRAME CONTEXT MENU ===== */ | |
| /* Hide the right-click context menu (filter option) as it has no function */ | |
| .cell-menu, | |
| .context-menu, | |
| [data-testid="dataframe"] .cell-menu, | |
| [data-testid="dataframe"] .context-menu, | |
| .table-wrap .cell-menu, | |
| .table-wrap .context-menu, | |
| .svelte-virtual-table-viewport .cell-menu, | |
| .svelte-virtual-table-viewport .context-menu, | |
| #wer-leaderboard-table .cell-menu, | |
| #cer-leaderboard-table .cell-menu, | |
| #rtfx-leaderboard-table .cell-menu, | |
| #wer-leaderboard-table .context-menu, | |
| #cer-leaderboard-table .context-menu, | |
| #rtfx-leaderboard-table .context-menu { | |
| display: none !important; | |
| visibility: hidden !important; | |
| pointer-events: none !important; | |
| } | |
| /* Metric direction notes styling */ | |
| .metric-note { | |
| font-size: 14px !important; | |
| color: #666 !important; | |
| margin-bottom: 8px !important; | |
| padding: 8px 12px !important; | |
| background-color: #f8f9fa !important; | |
| border-left: 3px solid #8CD0FF !important; | |
| border-radius: 4px !important; | |
| } | |
| /* Remove nested styling from markdown content inside metric-note */ | |
| .metric-note p, | |
| .metric-note .prose p, | |
| .metric-note .prose, | |
| .metric-note > div, | |
| .metric-note .markdown-code, | |
| .metric-note .md { | |
| margin: 0 !important; | |
| padding: 0 !important; | |
| background: transparent !important; | |
| border: none !important; | |
| } | |
| #models-to-add-text { | |
| font-size: 18px !important; | |
| } | |
| #citation-button span { | |
| font-size: 16px !important; | |
| } | |
| #citation-button textarea { | |
| font-size: 16px !important; | |
| } | |
| #citation-button > label > button { | |
| margin: 6px; | |
| transform: scale(1.3); | |
| } | |
| #leaderboard-table { | |
| margin-top: 15px | |
| } | |
| #leaderboard-table-lite { | |
| margin-top: 15px | |
| } | |
| /* Sortable Dataframe Leaderboard Styles */ | |
| #wer-leaderboard-table, | |
| #cer-leaderboard-table, | |
| #rtfx-leaderboard-table { | |
| margin-top: 15px; | |
| } | |
| #wer-leaderboard-table table, | |
| #cer-leaderboard-table table, | |
| #rtfx-leaderboard-table table { | |
| font-size: 14px; | |
| } | |
| /* ===== COLUMN SIZING ===== */ | |
| /* Headers styling */ | |
| #wer-leaderboard-table th, | |
| #cer-leaderboard-table th, | |
| #rtfx-leaderboard-table th { | |
| position: relative; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| min-width: 70px; /* Ensure short model names like "paza" are not truncated */ | |
| } | |
| /* Resize handle on right edge of headers */ | |
| #wer-leaderboard-table th .col-resize-handle, | |
| #cer-leaderboard-table th .col-resize-handle, | |
| #rtfx-leaderboard-table th .col-resize-handle { | |
| position: absolute; | |
| right: 0; | |
| top: 0; | |
| bottom: 0; | |
| width: 5px; | |
| cursor: col-resize; | |
| background: transparent; | |
| z-index: 10; | |
| } | |
| #wer-leaderboard-table th .col-resize-handle:hover, | |
| #cer-leaderboard-table th .col-resize-handle:hover, | |
| #rtfx-leaderboard-table th .col-resize-handle:hover, | |
| #wer-leaderboard-table th .col-resize-handle.resizing, | |
| #cer-leaderboard-table th .col-resize-handle.resizing, | |
| #rtfx-leaderboard-table th .col-resize-handle.resizing { | |
| background: #8CD0FF; | |
| } | |
| /* Cell content handling */ | |
| #wer-leaderboard-table td, | |
| #cer-leaderboard-table td, | |
| #rtfx-leaderboard-table td { | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| } | |
| /* Show full content on hover via tooltip */ | |
| #wer-leaderboard-table td[title], | |
| #cer-leaderboard-table td[title], | |
| #rtfx-leaderboard-table td[title], | |
| #wer-leaderboard-table th[title], | |
| #cer-leaderboard-table th[title], | |
| #rtfx-leaderboard-table th[title] { | |
| cursor: help; | |
| } | |
| /* Make column headers look clickable for sorting */ | |
| #wer-leaderboard-table th, | |
| #cer-leaderboard-table th, | |
| #rtfx-leaderboard-table th { | |
| cursor: pointer; | |
| user-select: none; | |
| transition: background-color 0.2s ease; | |
| font-weight: 600; | |
| } | |
| /* Force header font size to 15px - must target all descendants due to Gradio 6 Svelte component nesting */ | |
| #wer-leaderboard-table th, | |
| #wer-leaderboard-table th *, | |
| #cer-leaderboard-table th, | |
| #cer-leaderboard-table th *, | |
| #rtfx-leaderboard-table th, | |
| #rtfx-leaderboard-table th * { | |
| font-size: 15px !important; | |
| } | |
| #wer-leaderboard-table th:hover, | |
| #cer-leaderboard-table th:hover, | |
| #rtfx-leaderboard-table th:hover { | |
| background-color: transparent !important; | |
| text-decoration: underline; | |
| } | |
| /* ===== LEADERBOARD TABLE HEADER SELECTION FIX ===== */ | |
| /* Remove focus/selection highlight from leaderboard table headers */ | |
| /* Keep only sort arrows visible, remove the box-shadow ring */ | |
| #wer-leaderboard-table th.focus, | |
| #cer-leaderboard-table th.focus, | |
| #rtfx-leaderboard-table th.focus, | |
| #wer-leaderboard-table th:focus, | |
| #cer-leaderboard-table th:focus, | |
| #rtfx-leaderboard-table th:focus, | |
| #wer-leaderboard-table th.sorted, | |
| #cer-leaderboard-table th.sorted, | |
| #rtfx-leaderboard-table th.sorted { | |
| --ring-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| background-color: transparent !important; | |
| } | |
| /* Dark mode specific for leaderboard tables */ | |
| body.dark #wer-leaderboard-table th.focus, | |
| body.dark #cer-leaderboard-table th.focus, | |
| body.dark #rtfx-leaderboard-table th.focus, | |
| body.dark #wer-leaderboard-table th:focus, | |
| body.dark #cer-leaderboard-table th:focus, | |
| body.dark #rtfx-leaderboard-table th:focus, | |
| body.dark #wer-leaderboard-table th.sorted, | |
| body.dark #cer-leaderboard-table th.sorted, | |
| body.dark #rtfx-leaderboard-table th.sorted, | |
| [data-theme="dark"] #wer-leaderboard-table th.focus, | |
| [data-theme="dark"] #cer-leaderboard-table th.focus, | |
| [data-theme="dark"] #rtfx-leaderboard-table th.focus, | |
| [data-theme="dark"] #wer-leaderboard-table th:focus, | |
| [data-theme="dark"] #cer-leaderboard-table th:focus, | |
| [data-theme="dark"] #rtfx-leaderboard-table th:focus, | |
| [data-theme="dark"] #wer-leaderboard-table th.sorted, | |
| [data-theme="dark"] #cer-leaderboard-table th.sorted, | |
| [data-theme="dark"] #rtfx-leaderboard-table th.sorted { | |
| --ring-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| background-color: transparent !important; | |
| } | |
| /* Remove selection highlight from internal header elements */ | |
| #wer-leaderboard-table th .cell-wrap, | |
| #cer-leaderboard-table th .cell-wrap, | |
| #rtfx-leaderboard-table th .cell-wrap, | |
| #wer-leaderboard-table th .header-button, | |
| #cer-leaderboard-table th .header-button, | |
| #rtfx-leaderboard-table th .header-button { | |
| background-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| body.dark #wer-leaderboard-table th .cell-wrap, | |
| body.dark #cer-leaderboard-table th .cell-wrap, | |
| body.dark #rtfx-leaderboard-table th .cell-wrap, | |
| body.dark #wer-leaderboard-table th .header-button, | |
| body.dark #cer-leaderboard-table th .header-button, | |
| body.dark #rtfx-leaderboard-table th .header-button, | |
| [data-theme="dark"] #wer-leaderboard-table th .cell-wrap, | |
| [data-theme="dark"] #cer-leaderboard-table th .cell-wrap, | |
| [data-theme="dark"] #rtfx-leaderboard-table th .cell-wrap, | |
| [data-theme="dark"] #wer-leaderboard-table th .header-button, | |
| [data-theme="dark"] #cer-leaderboard-table th .header-button, | |
| [data-theme="dark"] #rtfx-leaderboard-table th .header-button { | |
| background-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| /* Language column styling (first column after index) */ | |
| #wer-leaderboard-table td:first-child, | |
| #cer-leaderboard-table td:first-child, | |
| #rtfx-leaderboard-table td:first-child { | |
| font-weight: 600; | |
| position: sticky; | |
| left: 0; | |
| background-color: var(--metric-table-row-header-bg); | |
| z-index: 1; | |
| } | |
| /* Make # and Language columns look clickable for row-level sorting */ | |
| #wer-leaderboard-table td:nth-child(1), | |
| #wer-leaderboard-table td:nth-child(2), | |
| #cer-leaderboard-table td:nth-child(1), | |
| #cer-leaderboard-table td:nth-child(2), | |
| #rtfx-leaderboard-table td:nth-child(1), | |
| #rtfx-leaderboard-table td:nth-child(2) { | |
| cursor: pointer; | |
| transition: background-color 0.2s ease, color 0.2s ease; | |
| position: relative; | |
| } | |
| /* Row sort button styling */ | |
| .row-sort-btn { | |
| display: inline-block; | |
| margin-left: 4px; | |
| font-size: 10px; | |
| opacity: 0.4; | |
| cursor: pointer; | |
| vertical-align: middle; | |
| } | |
| #wer-leaderboard-table td:nth-child(2):hover .row-sort-btn, | |
| #cer-leaderboard-table td:nth-child(2):hover .row-sort-btn, | |
| #rtfx-leaderboard-table td:nth-child(2):hover .row-sort-btn { | |
| opacity: 0.8; | |
| } | |
| #wer-leaderboard-table td:nth-child(1):hover, | |
| #wer-leaderboard-table td:nth-child(2):hover, | |
| #cer-leaderboard-table td:nth-child(1):hover, | |
| #cer-leaderboard-table td:nth-child(2):hover, | |
| #rtfx-leaderboard-table td:nth-child(1):hover, | |
| #rtfx-leaderboard-table td:nth-child(2):hover { | |
| background-color: rgba(140, 208, 255, 0.2) !important; | |
| text-decoration: underline; | |
| color: #0066cc !important; | |
| } | |
| #search-bar-table-box > div:first-child { | |
| background: none; | |
| border: none; | |
| } | |
| #search-bar { | |
| padding: 0px; | |
| } | |
| /* Limit the width of the first AutoEvalColumn so that names don't expand too much */ | |
| #leaderboard-table td:nth-child(2), | |
| #leaderboard-table th:nth-child(2) { | |
| max-width: 400px; | |
| overflow: auto; | |
| white-space: nowrap; | |
| } | |
| .tab-buttons button { | |
| font-size: 20px; | |
| } | |
| /* PazaBench brand color for active tabs */ | |
| .tab-buttons button.selected, | |
| .tabs button.selected, | |
| button.tab-nav.selected, | |
| [role="tab"][aria-selected="true"], | |
| .tab-nav.selected { | |
| background-color: #DDF1FF !important; | |
| border-color: #8CD0FF !important; | |
| color: #0f172a !important; | |
| } | |
| /* Subtle hover state for tabs - light mode */ | |
| .tab-buttons button:hover, | |
| .tabs button:hover, | |
| button.tab-nav:hover, | |
| [role="tab"]:hover { | |
| background-color: #DDF1FF !important; | |
| } | |
| /* ===== DARK MODE TAB HOVER FIX ===== */ | |
| /* Make tab hover transparent in dark mode to prevent text obscuring */ | |
| body.dark .tab-buttons button:hover, | |
| body.dark .tabs button:hover, | |
| body.dark button.tab-nav:hover, | |
| body.dark [role="tab"]:hover, | |
| [data-theme="dark"] .tab-buttons button:hover, | |
| [data-theme="dark"] .tabs button:hover, | |
| [data-theme="dark"] button.tab-nav:hover, | |
| [data-theme="dark"] [role="tab"]:hover, | |
| .dark .tab-buttons button:hover, | |
| .dark .tabs button:hover, | |
| .dark button.tab-nav:hover, | |
| .dark [role="tab"]:hover { | |
| background-color: transparent !important; | |
| text-decoration: underline; | |
| } | |
| /* Dark mode active tab - ensure text is visible */ | |
| body.dark .tab-buttons button.selected, | |
| body.dark .tabs button.selected, | |
| body.dark button.tab-nav.selected, | |
| body.dark [role="tab"][aria-selected="true"], | |
| [data-theme="dark"] .tab-buttons button.selected, | |
| [data-theme="dark"] .tabs button.selected, | |
| [data-theme="dark"] button.tab-nav.selected, | |
| [data-theme="dark"] [role="tab"][aria-selected="true"], | |
| .dark .tab-buttons button.selected, | |
| .dark .tabs button.selected, | |
| .dark button.tab-nav.selected, | |
| .dark [role="tab"][aria-selected="true"] { | |
| background-color: rgba(140, 208, 255, 0.2) !important; | |
| border-color: #8CD0FF !important; | |
| color: #e5e7eb !important; | |
| } | |
| /* Prevent text selection on tabs */ | |
| .tab-buttons button, | |
| .tabs button, | |
| button.tab-nav, | |
| [role="tab"] { | |
| -webkit-user-select: none !important; | |
| -moz-user-select: none !important; | |
| -ms-user-select: none !important; | |
| user-select: none !important; | |
| } | |
| /* Override Gradio's default orange accent colors with PazaBench blue */ | |
| /* Tab underline/border colors */ | |
| .tabs .tab-nav::after, | |
| .tab-buttons button::after, | |
| button.tab-nav::after, | |
| [role="tab"]::after { | |
| background-color: #8CD0FF !important; | |
| } | |
| .tabs .tab-nav.selected::after, | |
| .tab-buttons button.selected::after, | |
| button.tab-nav.selected::after, | |
| [role="tab"][aria-selected="true"]::after { | |
| background-color: #8CD0FF !important; | |
| } | |
| /* Gradio dataframe selected cell borders */ | |
| .table-wrap td.focus, | |
| .table-wrap th.focus, | |
| table td:focus, | |
| table th:focus, | |
| .dataframe td.selected, | |
| .dataframe th.selected, | |
| .svelte-table td.focus, | |
| .svelte-table th.focus, | |
| [data-testid="dataframe"] td.selected, | |
| [data-testid="dataframe"] th.selected { | |
| outline-color: #8CD0FF !important; | |
| border-color: #8CD0FF !important; | |
| box-shadow: 0 0 0 2px #8CD0FF !important; | |
| } | |
| /* Override orange focus rings and borders globally */ | |
| *:focus { | |
| outline-color: #8CD0FF !important; | |
| } | |
| input:focus, | |
| textarea:focus, | |
| select:focus, | |
| button:focus { | |
| border-color: #8CD0FF !important; | |
| box-shadow: 0 0 0 2px rgba(140, 208, 255, 0.3) !important; | |
| } | |
| /* Gradio specific accent color overrides */ | |
| .gradio-container { | |
| --color-accent: #8CD0FF !important; | |
| --color-accent-soft: #DDF1FF !important; | |
| /* Radio and Checkbox - only style the indicator dot, not the label background */ | |
| --checkbox-label-background-fill-selected: transparent !important; | |
| --checkbox-background-color-selected: #8CD0FF !important; | |
| --checkbox-border-color-selected: #8CD0FF !important; | |
| --slider-color: #8CD0FF !important; | |
| /* Primary button colors */ | |
| --primary-50: #DDF1FF !important; | |
| --primary-100: #c5e7ff !important; | |
| --primary-200: #aeddff !important; | |
| --primary-300: #8CD0FF !important; | |
| --primary-400: #6bc0f5 !important; | |
| --primary-500: #4ab0eb !important; | |
| --primary-600: #29a0e1 !important; | |
| --primary-700: #0890d7 !important; | |
| } | |
| /* Dark mode accent colors */ | |
| body.dark .gradio-container, | |
| [data-theme="dark"] .gradio-container { | |
| --color-accent: #8CD0FF !important; | |
| --color-accent-soft: #1e3a5f !important; | |
| /* Radio and Checkbox - only style the indicator dot, not the label background */ | |
| --checkbox-label-background-fill-selected: transparent !important; | |
| --checkbox-background-color-selected: #8CD0FF !important; | |
| --checkbox-border-color-selected: #8CD0FF !important; | |
| --slider-color: #8CD0FF !important; | |
| } | |
| /* ===== LOADING/PROGRESS BAR FIX FOR DARK MODE ===== */ | |
| /* Make loading indicator more subtle/transparent */ | |
| .progress-bar, | |
| .eta-bar, | |
| [class*="progress"], | |
| [class*="loader"], | |
| [class*="loading"], | |
| .wrap.svelte-j1gjts, | |
| .wrap.svelte-j1gjts .progress-bar { | |
| background-color: transparent !important; | |
| } | |
| /* Gradio's internal progress/loading indicators */ | |
| body.dark .progress-bar, | |
| body.dark .eta-bar, | |
| body.dark [class*="progress"], | |
| [data-theme="dark"] .progress-bar, | |
| [data-theme="dark"] .eta-bar, | |
| [data-theme="dark"] [class*="progress"], | |
| .dark .progress-bar, | |
| .dark .eta-bar, | |
| .dark [class*="progress"] { | |
| background-color: transparent !important; | |
| } | |
| /* ===== ACCORDION HOVER FIX FOR DARK MODE ===== */ | |
| /* Fix accordion text highlight/selection obscuring text in dark mode */ | |
| /* Target accordion header button hover states - using actual Gradio class names */ | |
| .label-wrap:hover, | |
| button.label-wrap:hover { | |
| background-color: transparent !important; | |
| -webkit-user-select: none !important; | |
| -moz-user-select: none !important; | |
| -ms-user-select: none !important; | |
| user-select: none !important; | |
| } | |
| /* Dark mode specific accordion hover fix */ | |
| body.dark .label-wrap:hover, | |
| body.dark button.label-wrap:hover, | |
| [data-theme="dark"] .label-wrap:hover, | |
| [data-theme="dark"] button.label-wrap:hover, | |
| .dark .label-wrap:hover, | |
| .dark button.label-wrap:hover { | |
| background-color: transparent !important; | |
| -webkit-user-select: none !important; | |
| user-select: none !important; | |
| } | |
| /* Prevent text selection highlight on accordion labels */ | |
| .label-wrap::selection, | |
| .label-wrap *::selection, | |
| button.label-wrap::selection, | |
| button.label-wrap *::selection { | |
| background-color: transparent !important; | |
| } | |
| body.dark .label-wrap::selection, | |
| body.dark .label-wrap *::selection, | |
| [data-theme="dark"] .label-wrap::selection, | |
| [data-theme="dark"] .label-wrap *::selection, | |
| .dark .label-wrap::selection, | |
| .dark .label-wrap *::selection { | |
| background-color: transparent !important; | |
| } | |
| /* ===== DATAFRAME/TABLE HEADER HOVER FIX FOR DARK MODE ===== */ | |
| /* Fix table header hover states obscuring text */ | |
| body.dark table th:hover, | |
| body.dark [data-testid="dataframe"] th:hover, | |
| body.dark .table-wrap th:hover, | |
| body.dark .svelte-table th:hover, | |
| [data-theme="dark"] table th:hover, | |
| [data-theme="dark"] [data-testid="dataframe"] th:hover, | |
| [data-theme="dark"] .table-wrap th:hover, | |
| [data-theme="dark"] .svelte-table th:hover, | |
| .dark table th:hover, | |
| .dark [data-testid="dataframe"] th:hover, | |
| .dark .table-wrap th:hover, | |
| .dark .svelte-table th:hover { | |
| background-color: transparent !important; | |
| -webkit-user-select: none !important; | |
| user-select: none !important; | |
| } | |
| /* More comprehensive table header fix - catch Gradio's generated classes */ | |
| body.dark th, | |
| body.dark thead th, | |
| body.dark .header, | |
| body.dark [class*="header"], | |
| body.dark th[role="columnheader"], | |
| [data-theme="dark"] th, | |
| [data-theme="dark"] thead th, | |
| [data-theme="dark"] .header, | |
| [data-theme="dark"] [class*="header"], | |
| [data-theme="dark"] th[role="columnheader"], | |
| .dark th, | |
| .dark thead th, | |
| .dark .header, | |
| .dark [class*="header"], | |
| .dark th[role="columnheader"] { | |
| -webkit-user-select: none !important; | |
| -moz-user-select: none !important; | |
| user-select: none !important; | |
| } | |
| body.dark th:hover, | |
| body.dark thead th:hover, | |
| body.dark th[role="columnheader"]:hover, | |
| [data-theme="dark"] th:hover, | |
| [data-theme="dark"] thead th:hover, | |
| [data-theme="dark"] th[role="columnheader"]:hover, | |
| .dark th:hover, | |
| .dark thead th:hover, | |
| .dark th[role="columnheader"]:hover { | |
| background-color: transparent !important; | |
| text-decoration: underline; | |
| } | |
| /* Prevent text selection on table headers */ | |
| th::selection, | |
| th *::selection, | |
| thead::selection, | |
| thead *::selection { | |
| background-color: transparent !important; | |
| } | |
| /* ===== GRADIO DATAFRAME HEADER SELECTION/FOCUS FIX ===== */ | |
| /* Remove the blue highlight ring from selected/focused column headers in dark mode */ | |
| /* Gradio uses .focus class and --ring-color variable for header selection state */ | |
| body.dark th.focus, | |
| body.dark thead th.focus, | |
| body.dark .table-wrap th.focus, | |
| body.dark [data-testid="dataframe"] th.focus, | |
| [data-theme="dark"] th.focus, | |
| [data-theme="dark"] thead th.focus, | |
| [data-theme="dark"] .table-wrap th.focus, | |
| [data-theme="dark"] [data-testid="dataframe"] th.focus, | |
| .dark th.focus, | |
| .dark thead th.focus, | |
| .dark .table-wrap th.focus, | |
| .dark [data-testid="dataframe"] th.focus { | |
| --ring-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| /* Also handle selected header state */ | |
| body.dark th.selected, | |
| body.dark thead th.selected, | |
| body.dark th[aria-selected="true"], | |
| [data-theme="dark"] th.selected, | |
| [data-theme="dark"] thead th.selected, | |
| [data-theme="dark"] th[aria-selected="true"], | |
| .dark th.selected, | |
| .dark thead th.selected, | |
| .dark th[aria-selected="true"] { | |
| --ring-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| background-color: transparent !important; | |
| } | |
| /* Header focus state */ | |
| th.focus, | |
| thead th.focus, | |
| .table-wrap th.focus, | |
| [data-testid="dataframe"] th.focus { | |
| --ring-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| th.selected, | |
| thead th.selected, | |
| th[aria-selected="true"] { | |
| --ring-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| /* ===== KEEP SORT ARROWS VISIBLE ===== */ | |
| /* Ensure sort arrows (SortArrowUp/SortArrowDown) remain visible */ | |
| /* Sort indicators container in Gradio dataframe header */ | |
| .sort-indicators, | |
| .table-wrap .sort-indicators, | |
| [data-testid="dataframe"] .sort-indicators, | |
| th .sort-indicators { | |
| display: flex !important; | |
| visibility: visible !important; | |
| opacity: 1 !important; | |
| } | |
| /* Sort arrow icons */ | |
| .sort-arrow, | |
| .sort-indicators .sort-arrow, | |
| th .sort-arrow { | |
| display: flex !important; | |
| visibility: visible !important; | |
| opacity: 1 !important; | |
| color: var(--body-text-color) !important; | |
| } | |
| /* Sort priority badge (shows order when multi-column sorting) */ | |
| .sort-priority, | |
| .sort-indicators .sort-priority, | |
| th .sort-priority { | |
| display: flex !important; | |
| visibility: visible !important; | |
| } | |
| /* Ensure sorted column headers show their state via arrows only, not highlight */ | |
| th.sorted, | |
| th[aria-sort="ascending"], | |
| th[aria-sort="descending"] { | |
| background-color: transparent !important; | |
| } | |
| body.dark th.sorted, | |
| body.dark th[aria-sort="ascending"], | |
| body.dark th[aria-sort="descending"], | |
| [data-theme="dark"] th.sorted, | |
| [data-theme="dark"] th[aria-sort="ascending"], | |
| [data-theme="dark"] th[aria-sort="descending"], | |
| .dark th.sorted, | |
| .dark th[aria-sort="ascending"], | |
| .dark th[aria-sort="descending"] { | |
| background-color: transparent !important; | |
| } | |
| /* ===== GRADIO DATAFRAME INTERNAL HEADER BUTTON FIX ===== */ | |
| /* Gradio's TableHeader uses .cell-wrap with a button.header-button inside */ | |
| /* Remove any selection/focus styling from these internal elements */ | |
| th .cell-wrap, | |
| thead th .cell-wrap, | |
| .table-wrap th .cell-wrap, | |
| [data-testid="dataframe"] th .cell-wrap { | |
| background-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| th .header-button, | |
| thead th .header-button, | |
| th .cell-wrap .header-button, | |
| th button.header-button { | |
| background-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| /* Dark mode specific for internal header elements */ | |
| body.dark th .cell-wrap, | |
| body.dark th .header-button, | |
| body.dark th .cell-wrap .header-button, | |
| [data-theme="dark"] th .cell-wrap, | |
| [data-theme="dark"] th .header-button, | |
| [data-theme="dark"] th .cell-wrap .header-button, | |
| .dark th .cell-wrap, | |
| .dark th .header-button, | |
| .dark th .cell-wrap .header-button { | |
| background-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| /* Remove highlight on header button focus/active states */ | |
| th .header-button:focus, | |
| th .header-button:active, | |
| th .header-button:hover, | |
| th .cell-wrap:focus, | |
| th .cell-wrap:active { | |
| background-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| body.dark th .header-button:focus, | |
| body.dark th .header-button:active, | |
| body.dark th .header-button:hover, | |
| body.dark th .cell-wrap:focus, | |
| body.dark th .cell-wrap:active, | |
| [data-theme="dark"] th .header-button:focus, | |
| [data-theme="dark"] th .header-button:active, | |
| [data-theme="dark"] th .header-button:hover, | |
| [data-theme="dark"] th .cell-wrap:focus, | |
| [data-theme="dark"] th .cell-wrap:active, | |
| .dark th .header-button:focus, | |
| .dark th .header-button:active, | |
| .dark th .header-button:hover, | |
| .dark th .cell-wrap:focus, | |
| .dark th .cell-wrap:active { | |
| background-color: transparent !important; | |
| box-shadow: none !important; | |
| outline: none !important; | |
| } | |
| /* Fix table cell selection/focus in dark mode - make background subtle */ | |
| body.dark table th:focus, | |
| body.dark table td:focus, | |
| body.dark [data-testid="dataframe"] th:focus, | |
| body.dark [data-testid="dataframe"] td:focus, | |
| [data-theme="dark"] table th:focus, | |
| [data-theme="dark"] table td:focus, | |
| [data-theme="dark"] [data-testid="dataframe"] th:focus, | |
| [data-theme="dark"] [data-testid="dataframe"] td:focus, | |
| .dark table th:focus, | |
| .dark table td:focus, | |
| .dark [data-testid="dataframe"] th:focus, | |
| .dark [data-testid="dataframe"] td:focus { | |
| background-color: rgba(140, 208, 255, 0.15) !important; | |
| } | |
| /* Prevent text selection on table headers */ | |
| table th::selection, | |
| table th *::selection, | |
| [data-testid="dataframe"] th::selection, | |
| [data-testid="dataframe"] th *::selection { | |
| background-color: transparent !important; | |
| } | |
| /* ===== GLOBAL DARK MODE TEXT SELECTION FIX ===== */ | |
| /* Fix text selection color in dark mode globally for better contrast */ | |
| body.dark ::selection, | |
| [data-theme="dark"] ::selection, | |
| .dark ::selection { | |
| background-color: rgba(140, 208, 255, 0.4) !important; | |
| color: inherit !important; | |
| } | |
| /* Override Radio button selected indicator (the inner dot) - Gradio 5 specific */ | |
| input[type="radio"]:checked { | |
| accent-color: #8CD0FF !important; | |
| } | |
| /* Radio group - remove background fill, keep only dot styled */ | |
| .gradio-radio label.selected, | |
| [data-testid*="radio-label"].selected { | |
| background-color: transparent !important; | |
| border-color: transparent !important; | |
| } | |
| /* Checkbox checked styling */ | |
| input[type="checkbox"]:checked { | |
| accent-color: #8CD0FF !important; | |
| } | |
| #scale-logo { | |
| border-style: none !important; | |
| box-shadow: none; | |
| display: block; | |
| margin-left: auto; | |
| margin-right: auto; | |
| max-width: 600px; | |
| } | |
| #scale-logo .download { | |
| display: none; | |
| } | |
| #filter_type{ | |
| border: 0; | |
| padding-left: 0; | |
| padding-top: 0; | |
| } | |
| #filter_type label { | |
| display: flex; | |
| } | |
| #filter_type label > span{ | |
| margin-top: var(--spacing-lg); | |
| margin-right: 0.5em; | |
| } | |
| #filter_type label > .wrap{ | |
| width: 103px; | |
| } | |
| #filter_type label > .wrap .wrap-inner{ | |
| padding: 2px; | |
| } | |
| #filter_type label > .wrap .wrap-inner input{ | |
| width: 1px | |
| } | |
| #filter-columns-type{ | |
| border:0; | |
| padding:0.5; | |
| } | |
| #filter-columns-size{ | |
| border:0; | |
| padding:0.5; | |
| } | |
| #box-filter > .form{ | |
| border: 0 | |
| } | |
| .metric-tabs button { | |
| font-size: 18px; | |
| } | |
| .metric-table-wrapper { | |
| overflow-x: auto; | |
| margin-top: 1rem; | |
| } | |
| /* ===== MARKDOWN TABLE COLUMN WIDTHS ===== */ | |
| /* Ensure Datasets and Evaluated Models tables have proper column widths */ | |
| /* Target markdown-rendered tables in Benchmark Inputs tab */ | |
| .markdown-text table th:nth-child(4), | |
| .markdown-text table td:nth-child(4), | |
| .prose table th:nth-child(4), | |
| .prose table td:nth-child(4) { | |
| min-width: 80px !important; | |
| white-space: nowrap; | |
| } | |
| .markdown-text table th:nth-child(5), | |
| .markdown-text table td:nth-child(5), | |
| .prose table th:nth-child(5), | |
| .prose table td:nth-child(5) { | |
| min-width: 100px !important; | |
| white-space: nowrap; | |
| } | |
| /* Chart Gallery Styles */ | |
| .chart-gallery { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); | |
| gap: 1rem; | |
| margin: 1rem 0; | |
| } | |
| /* Plotly Chart Responsiveness */ | |
| .js-plotly-plot, .plotly { | |
| width: 100% !important; | |
| } | |
| .js-plotly-plot .plotly .main-svg { | |
| width: 100% !important; | |
| } | |
| /* Better mobile display for Plotly charts */ | |
| @media (max-width: 768px) { | |
| .js-plotly-plot .plotly .legend { | |
| font-size: 9px !important; | |
| } | |
| .js-plotly-plot .plotly .gtitle { | |
| font-size: 14px !important; | |
| } | |
| .js-plotly-plot .plotly .xtitle, | |
| .js-plotly-plot .plotly .ytitle { | |
| font-size: 11px !important; | |
| } | |
| /* Stack the map and info/chart column full-width on mobile. */ | |
| #language-coverage-row { | |
| flex-direction: column !important; | |
| } | |
| #language-coverage-row > * { | |
| width: 100% !important; | |
| min-width: 0 !important; | |
| } | |
| /* Wide content tables scroll horizontally on mobile. */ | |
| .markdown-text table { | |
| display: block; | |
| overflow-x: auto; | |
| -webkit-overflow-scrolling: touch; | |
| } | |
| .markdown-text table th, | |
| .markdown-text table td { | |
| white-space: nowrap; | |
| } | |
| /* Visualisation charts keep a usable min-width and scroll horizontally on mobile. */ | |
| .viz-scroll-plot { | |
| overflow-x: auto !important; | |
| -webkit-overflow-scrolling: touch; | |
| } | |
| .viz-scroll-plot .js-plotly-plot { | |
| min-width: 700px !important; | |
| } | |
| /* Leaderboard metric tables keep their min-width but scroll inside their wrapper. */ | |
| .metric-table-wrapper, | |
| .metric-table-container, | |
| .table-wrap { | |
| overflow-x: auto !important; | |
| -webkit-overflow-scrolling: touch; | |
| } | |
| } | |
| .chart-card { | |
| background: var(--metric-table-bg, #ffffff); | |
| border: 1px solid var(--metric-table-border, #d3d3d3); | |
| border-radius: 8px; | |
| padding: 1rem; | |
| transition: box-shadow 0.2s ease, transform 0.2s ease; | |
| } | |
| .chart-card:hover { | |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); | |
| transform: translateY(-2px); | |
| } | |
| .chart-card h4 { | |
| margin: 0 0 0.5rem 0; | |
| color: var(--metric-table-header-color, #0f172a); | |
| font-size: 1.1rem; | |
| } | |
| .chart-card p { | |
| margin: 0; | |
| color: var(--metric-table-caption, #666666); | |
| font-size: 0.9rem; | |
| line-height: 1.4; | |
| } | |
| .metric-table { | |
| border-collapse: collapse; | |
| width: 100%; | |
| min-width: 600px; | |
| text-align: center; | |
| font-size: 16px; | |
| background-color: var(--metric-table-bg); | |
| } | |
| .metric-table caption { | |
| caption-side: bottom; | |
| padding-top: 0.5rem; | |
| color: var(--metric-table-caption); | |
| font-size: 0.9rem; | |
| } | |
| .metric-table th, | |
| .metric-table td { | |
| border: 1px solid var(--metric-table-border); | |
| padding: 0.5rem; | |
| } | |
| .metric-table thead th { | |
| background-color: var(--metric-table-header-bg); | |
| color: var(--metric-table-header-color); | |
| position: sticky; | |
| top: 0; | |
| z-index: 1; | |
| } | |
| .metric-table tbody th { | |
| text-align: left; | |
| background-color: var(--metric-table-row-header-bg); | |
| color: var(--metric-table-header-color); | |
| position: sticky; | |
| left: 0; | |
| z-index: 2; | |
| cursor: pointer; | |
| } | |
| .metric-table tbody th:hover { | |
| text-decoration: underline; | |
| } | |
| .metric-table tbody tr.row-highlighted { | |
| background-color: var(--metric-table-row-highlight) !important; | |
| } | |
| .metric-table tbody tr.row-highlighted td, | |
| .metric-table tbody tr.row-highlighted th { | |
| background-color: var(--metric-table-row-highlight) !important; | |
| } | |
| /* Leaderboard Gradio dataframe row highlighting */ | |
| #wer-leaderboard-table tbody tr.leaderboard-row-highlighted, | |
| #cer-leaderboard-table tbody tr.leaderboard-row-highlighted, | |
| #rtfx-leaderboard-table tbody tr.leaderboard-row-highlighted { | |
| background-color: var(--metric-table-row-highlight, rgba(140, 208, 255, 0.3)) !important; | |
| } | |
| #wer-leaderboard-table tbody tr.leaderboard-row-highlighted td, | |
| #cer-leaderboard-table tbody tr.leaderboard-row-highlighted td, | |
| #rtfx-leaderboard-table tbody tr.leaderboard-row-highlighted td { | |
| background-color: var(--metric-table-row-highlight, rgba(140, 208, 255, 0.3)) !important; | |
| } | |
| /* Dark mode leaderboard row highlighting */ | |
| body.dark #wer-leaderboard-table tbody tr.leaderboard-row-highlighted, | |
| body.dark #cer-leaderboard-table tbody tr.leaderboard-row-highlighted, | |
| body.dark #rtfx-leaderboard-table tbody tr.leaderboard-row-highlighted, | |
| [data-theme="dark"] #wer-leaderboard-table tbody tr.leaderboard-row-highlighted, | |
| [data-theme="dark"] #cer-leaderboard-table tbody tr.leaderboard-row-highlighted, | |
| [data-theme="dark"] #rtfx-leaderboard-table tbody tr.leaderboard-row-highlighted { | |
| background-color: rgba(140, 208, 255, 0.25) !important; | |
| } | |
| body.dark #wer-leaderboard-table tbody tr.leaderboard-row-highlighted td, | |
| body.dark #cer-leaderboard-table tbody tr.leaderboard-row-highlighted td, | |
| body.dark #rtfx-leaderboard-table tbody tr.leaderboard-row-highlighted td, | |
| [data-theme="dark"] #wer-leaderboard-table tbody tr.leaderboard-row-highlighted td, | |
| [data-theme="dark"] #cer-leaderboard-table tbody tr.leaderboard-row-highlighted td, | |
| [data-theme="dark"] #rtfx-leaderboard-table tbody tr.leaderboard-row-highlighted td { | |
| background-color: rgba(140, 208, 255, 0.25) !important; | |
| } | |
| /* Make all leaderboard cells clickable for row highlighting */ | |
| #wer-leaderboard-table tbody td, | |
| #cer-leaderboard-table tbody td, | |
| #rtfx-leaderboard-table tbody td { | |
| cursor: pointer; | |
| } | |
| .metric-table-empty { | |
| padding: 1rem; | |
| text-align: center; | |
| color: var(--metric-table-empty-color); | |
| } | |
| /* Footer Styles */ | |
| .paza-footer { | |
| margin-top: 2rem; | |
| padding: 1.5rem 1rem; | |
| border-top: 1px solid var(--metric-table-border, #d3d3d3); | |
| text-align: center; | |
| font-size: 0.9rem; | |
| color: var(--metric-table-caption, #666666); | |
| } | |
| .paza-footer a { | |
| color: #0078d4; | |
| text-decoration: none; | |
| transition: color 0.2s ease; | |
| } | |
| .paza-footer a:hover { | |
| color: #106ebe; | |
| text-decoration: underline; | |
| } | |
| /* Dark mode footer link colors */ | |
| body.dark .paza-footer a, | |
| [data-theme="dark"] .paza-footer a, | |
| body[class*="dark"] .paza-footer a, | |
| [data-color-mode="dark"] .paza-footer a { | |
| color: #60a5fa; | |
| } | |
| body.dark .paza-footer a:hover, | |
| [data-theme="dark"] .paza-footer a:hover, | |
| body[class*="dark"] .paza-footer a:hover, | |
| [data-color-mode="dark"] .paza-footer a:hover { | |
| color: #93c5fd; | |
| } | |
| .paza-footer-links { | |
| display: flex; | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| align-items: center; | |
| gap: 1rem 1.5rem; | |
| } | |
| .paza-footer-links .copyright { | |
| font-size: 0.85rem; | |
| } | |
| """ | |
| get_window_url_params = """ | |
| function(url_params) { | |
| const params = new URLSearchParams(window.location.search); | |
| url_params = Object.fromEntries(params); | |
| return url_params; | |
| } | |
| """ | |
| # WCAG 4.1.2 Fix: JavaScript to remove focusability from aria-hidden elements. | |
| # Also includes dark mode flash prevention script. | |
| fix_aria_hidden_focus_js = """ | |
| <script> | |
| // Dark mode flash prevention - run immediately before page renders | |
| (function() { | |
| // Check for HuggingFace Spaces dark mode preference or system preference | |
| const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; | |
| const isHFDark = document.documentElement.classList.contains('dark') || | |
| document.body?.classList.contains('dark') || | |
| document.documentElement.getAttribute('data-theme') === 'dark' || | |
| document.documentElement.getAttribute('data-color-mode') === 'dark'; | |
| if (isDarkMode || isHFDark) { | |
| // Apply dark class immediately to prevent flash | |
| document.documentElement.classList.add('dark'); | |
| document.documentElement.setAttribute('data-theme', 'dark'); | |
| if (document.body) { | |
| document.body.classList.add('dark'); | |
| } else { | |
| // If body not ready, wait for it | |
| document.addEventListener('DOMContentLoaded', function() { | |
| document.body.classList.add('dark'); | |
| }); | |
| } | |
| } | |
| // Also listen for theme changes from HF Spaces | |
| const observer = new MutationObserver(function(mutations) { | |
| mutations.forEach(function(mutation) { | |
| if (mutation.attributeName === 'class' || | |
| mutation.attributeName === 'data-theme' || | |
| mutation.attributeName === 'data-color-mode') { | |
| const html = document.documentElement; | |
| const body = document.body; | |
| if (html.classList.contains('dark') || | |
| html.getAttribute('data-theme') === 'dark' || | |
| html.getAttribute('data-color-mode') === 'dark') { | |
| if (body && !body.classList.contains('dark')) { | |
| body.classList.add('dark'); | |
| } | |
| } | |
| } | |
| }); | |
| }); | |
| observer.observe(document.documentElement, { | |
| attributes: true, | |
| attributeFilter: ['class', 'data-theme', 'data-color-mode'] | |
| }); | |
| })(); | |
| </script> | |
| <script> | |
| (function() { | |
| function fixAriaHiddenFocus() { | |
| // Find all aria-hidden containers and make their focusable children unfocusable | |
| const hiddenContainers = document.querySelectorAll('[aria-hidden="true"]'); | |
| hiddenContainers.forEach(container => { | |
| const focusableElements = container.querySelectorAll( | |
| 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' | |
| ); | |
| focusableElements.forEach(el => { | |
| el.setAttribute('tabindex', '-1'); | |
| el.setAttribute('aria-disabled', 'true'); | |
| el.setAttribute('data-a11y-fixed', 'true'); | |
| // Also disable the button to prevent any form of focus | |
| if (el.tagName === 'BUTTON') { | |
| el.disabled = true; | |
| } | |
| }); | |
| }); | |
| } | |
| // Run immediately | |
| fixAriaHiddenFocus(); | |
| // Run on DOMContentLoaded | |
| document.addEventListener('DOMContentLoaded', fixAriaHiddenFocus); | |
| // Run after a short delay to catch late-loading Gradio components | |
| setTimeout(fixAriaHiddenFocus, 100); | |
| setTimeout(fixAriaHiddenFocus, 500); | |
| setTimeout(fixAriaHiddenFocus, 1000); | |
| setTimeout(fixAriaHiddenFocus, 2000); | |
| // Use MutationObserver to handle dynamically added content | |
| const observer = new MutationObserver((mutations) => { | |
| fixAriaHiddenFocus(); | |
| }); | |
| // Start observing when body is available | |
| function startObserver() { | |
| if (document.body) { | |
| observer.observe(document.body, { | |
| childList: true, | |
| subtree: true, | |
| attributes: true, | |
| attributeFilter: ['aria-hidden'] | |
| }); | |
| fixAriaHiddenFocus(); | |
| } else { | |
| setTimeout(startObserver, 10); | |
| } | |
| } | |
| startObserver(); | |
| })(); | |
| // Row highlighting for metric tables when clicking on language | |
| (function() { | |
| function setupRowHighlighting() { | |
| const tables = document.querySelectorAll('.metric-table'); | |
| tables.forEach(table => { | |
| if (table.dataset.highlightSetup) return; | |
| table.dataset.highlightSetup = 'true'; | |
| const rows = table.querySelectorAll('tbody tr'); | |
| rows.forEach(row => { | |
| const languageCell = row.querySelector('th'); | |
| if (languageCell) { | |
| languageCell.addEventListener('click', function() { | |
| // Toggle highlight on the clicked row | |
| const isHighlighted = row.classList.contains('row-highlighted'); | |
| // Remove highlight from all rows in this table | |
| rows.forEach(r => r.classList.remove('row-highlighted')); | |
| // If row wasn't highlighted, highlight it now | |
| if (!isHighlighted) { | |
| row.classList.add('row-highlighted'); | |
| } | |
| }); | |
| } | |
| }); | |
| }); | |
| } | |
| // Run on load and observe for dynamically added tables | |
| document.addEventListener('DOMContentLoaded', setupRowHighlighting); | |
| setTimeout(setupRowHighlighting, 100); | |
| setTimeout(setupRowHighlighting, 500); | |
| setTimeout(setupRowHighlighting, 1000); | |
| setTimeout(setupRowHighlighting, 2000); | |
| const rowObserver = new MutationObserver((mutations) => { | |
| setupRowHighlighting(); | |
| }); | |
| function startRowObserver() { | |
| if (document.body) { | |
| rowObserver.observe(document.body, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| setupRowHighlighting(); | |
| } else { | |
| setTimeout(startRowObserver, 10); | |
| } | |
| } | |
| startRowObserver(); | |
| })(); | |
| // Row highlighting and row-based sorting for Gradio leaderboard dataframes (WER, CER, RTFx tables) | |
| (function() { | |
| // Track sort state per table per row | |
| const rowSortState = {}; | |
| // Track which containers have event listeners attached | |
| const setupContainers = new WeakSet(); | |
| function setupLeaderboardRowSorting() { | |
| const leaderboardIds = ['#wer-leaderboard-table', '#cer-leaderboard-table', '#rtfx-leaderboard-table']; | |
| leaderboardIds.forEach(tableId => { | |
| const container = document.querySelector(tableId); | |
| if (!container) return; | |
| // Initialize sort state for this table | |
| if (!rowSortState[tableId]) { | |
| rowSortState[tableId] = { rowIndex: null, ascending: true }; | |
| } | |
| // Skip if this specific container element already has event listener | |
| if (setupContainers.has(container)) return; | |
| setupContainers.add(container); | |
| // Use event delegation on the container - Gradio uses divs, not tables | |
| container.addEventListener('click', function(e) { | |
| // Don't intercept clicks on sort buttons in header | |
| if (e.target.closest('button') || e.target.closest('.sort-button')) { | |
| return; | |
| } | |
| // Ignore clicks in the aria-hidden sizing table | |
| const ariaHiddenTable = e.target.closest('table[aria-hidden="true"]'); | |
| if (ariaHiddenTable) { | |
| return; | |
| } | |
| // Find the clicked cell - Gradio uses div.cell-wrap or td | |
| let clickedCell = e.target.closest('td'); | |
| if (!clickedCell) { | |
| // Maybe clicked on span.text inside cell-wrap | |
| const cellWrap = e.target.closest('.cell-wrap'); | |
| if (cellWrap) { | |
| clickedCell = cellWrap.closest('td'); | |
| } | |
| } | |
| if (!clickedCell) { | |
| return; | |
| } | |
| const clickedRow = clickedCell.closest('tr'); | |
| if (!clickedRow) { | |
| return; | |
| } | |
| // Check if this is a body row (not header) - use the specific class | |
| const tbody = clickedRow.closest('tbody.tbody') || clickedRow.closest('tbody'); | |
| if (!tbody) { | |
| return; | |
| } | |
| // Make sure this tbody is inside a svelte-virtual-table-viewport (not the hidden sizing table) | |
| const virtualViewport = tbody.closest('svelte-virtual-table-viewport'); | |
| if (!virtualViewport) { | |
| return; | |
| } | |
| // Get all cells in the row | |
| const allCells = Array.from(clickedRow.querySelectorAll('td')); | |
| const cellIndex = allCells.indexOf(clickedCell); | |
| // If clicking on # column (index 0) or Language column (index 1), sort the row | |
| if (cellIndex === 0 || cellIndex === 1) { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| // Find the virtual table (the one with actual data, not aria-hidden one) | |
| const virtualTableViewport = container.querySelector('svelte-virtual-table-viewport'); | |
| const table = virtualTableViewport ? | |
| virtualTableViewport.querySelector('table.table') : | |
| container.querySelector('table:not([aria-hidden="true"])'); | |
| const thead = table ? table.querySelector('thead.thead') || table.querySelector('thead') : null; | |
| const virtualTbody = table ? table.querySelector('tbody.tbody') || table.querySelector('tbody') : null; | |
| if (table && thead && virtualTbody) { | |
| sortRowColumns(tableId, table, thead, virtualTbody, clickedRow); | |
| } | |
| return; | |
| } | |
| // For other cells, just toggle highlight | |
| const allRows = tbody.querySelectorAll('tr'); | |
| const isHighlighted = clickedRow.classList.contains('leaderboard-row-highlighted'); | |
| // Remove highlight from all rows | |
| allRows.forEach(row => row.classList.remove('leaderboard-row-highlighted')); | |
| // If row wasn't highlighted, highlight it now | |
| if (!isHighlighted) { | |
| clickedRow.classList.add('leaderboard-row-highlighted'); | |
| } | |
| }, true); // Use capture phase | |
| // Add tooltips to # and Language columns to explain row sorting | |
| addRowSortTooltips(container); | |
| }); | |
| } | |
| function addRowSortTooltips(container) { | |
| // Find the virtual table tbody (not the aria-hidden one) | |
| const virtualTableViewport = container.querySelector('svelte-virtual-table-viewport'); | |
| const table = virtualTableViewport ? | |
| virtualTableViewport.querySelector('table.table') : | |
| container.querySelector('table:not([aria-hidden="true"])'); | |
| const tbody = table ? table.querySelector('tbody.tbody') || table.querySelector('tbody') : null; | |
| if (!tbody) return; | |
| const rows = tbody.querySelectorAll('tr'); | |
| rows.forEach(row => { | |
| const cells = row.querySelectorAll('td'); | |
| if (cells.length >= 2) { | |
| // # column (index 0) | |
| if (cells[0] && !cells[0].dataset.tooltipSet) { | |
| cells[0].title = 'Click to sort columns by this row\'s values'; | |
| cells[0].dataset.tooltipSet = 'true'; | |
| } | |
| // Language column (index 1) | |
| if (cells[1] && !cells[1].dataset.tooltipSet) { | |
| const langName = cells[1].textContent.trim(); | |
| cells[1].title = `Click to sort model columns by ${langName}'s scores`; | |
| cells[1].dataset.tooltipSet = 'true'; | |
| } | |
| } | |
| }); | |
| } | |
| function sortRowColumns(tableId, table, thead, tbody, clickedRow) { | |
| // Get all header cells | |
| const headerRow = thead.querySelector('tr'); | |
| if (!headerRow) { | |
| return; | |
| } | |
| const headerCells = Array.from(headerRow.querySelectorAll('th')); | |
| const rowCells = Array.from(clickedRow.querySelectorAll('td')); | |
| // First 2 columns are # and Language - don't include in sort | |
| const fixedCols = 2; | |
| // Extract model columns (starting from index 2) | |
| const modelHeaders = headerCells.slice(fixedCols); | |
| const modelCells = rowCells.slice(fixedCols); | |
| if (modelHeaders.length === 0 || modelCells.length === 0) { | |
| return; | |
| } | |
| // Get row index to track sort state | |
| const allBodyRows = Array.from(tbody.querySelectorAll('tr')); | |
| const rowIndex = allBodyRows.indexOf(clickedRow); | |
| // Determine sort direction - toggle if same row clicked again | |
| let ascending; | |
| if (rowSortState[tableId].rowIndex === rowIndex) { | |
| ascending = !rowSortState[tableId].ascending; | |
| } else { | |
| // Determine default direction based on table type | |
| // WER/CER: lower is better, so ascending (best first) | |
| // RTFx: higher is better, so descending (best first) | |
| ascending = !tableId.includes('rtfx'); | |
| } | |
| rowSortState[tableId] = { rowIndex, ascending }; | |
| // Create array of {header, cell, value} for sorting | |
| const columnsData = modelHeaders.map((header, i) => { | |
| const cell = modelCells[i]; | |
| // Get text content - handle Gradio's nested structure | |
| let cellText = ''; | |
| if (cell) { | |
| // Try different selectors for Gradio's structure | |
| const textEl = cell.querySelector('.cell-wrap .text') || | |
| cell.querySelector('.cell-wrap') || | |
| cell.querySelector('span') || | |
| cell; | |
| cellText = textEl.textContent.trim(); | |
| } | |
| // Parse value, treating '--' or empty as Infinity (worst) | |
| let value = parseFloat(cellText); | |
| if (isNaN(value) || cellText === '--' || cellText === '') { | |
| value = ascending ? Infinity : -Infinity; | |
| } | |
| return { header, cell, value, originalIndex: i }; | |
| }); | |
| // Sort columns by value | |
| columnsData.sort((a, b) => { | |
| if (ascending) { | |
| return a.value - b.value; | |
| } else { | |
| return b.value - a.value; | |
| } | |
| }); | |
| // Store new column order indices | |
| const newOrder = columnsData.map(col => col.originalIndex); | |
| // Reorder header cells (after fixed columns) | |
| const newHeaderOrder = []; | |
| for (let i = 0; i < fixedCols; i++) { | |
| newHeaderOrder.push(headerCells[i]); | |
| } | |
| newOrder.forEach(idx => { | |
| newHeaderOrder.push(headerCells[fixedCols + idx]); | |
| }); | |
| // Clear and rebuild header row | |
| while (headerRow.firstChild) { | |
| headerRow.removeChild(headerRow.firstChild); | |
| } | |
| newHeaderOrder.forEach(cell => { | |
| if (cell) headerRow.appendChild(cell); | |
| }); | |
| // Reorder cells in all body rows | |
| allBodyRows.forEach((row, rIdx) => { | |
| const cells = Array.from(row.querySelectorAll('td')); | |
| const newCellOrder = []; | |
| for (let i = 0; i < fixedCols; i++) { | |
| newCellOrder.push(cells[i]); | |
| } | |
| newOrder.forEach(idx => { | |
| newCellOrder.push(cells[fixedCols + idx]); | |
| }); | |
| // Clear and rebuild row | |
| while (row.firstChild) { | |
| row.removeChild(row.firstChild); | |
| } | |
| newCellOrder.forEach(cell => { | |
| if (cell) row.appendChild(cell); | |
| }); | |
| }); | |
| // Highlight the clicked row to show it was used for sorting | |
| allBodyRows.forEach(row => row.classList.remove('leaderboard-row-highlighted')); | |
| // Find the row at the same index after reordering | |
| const newRows = tbody.querySelectorAll('tr'); | |
| if (newRows[rowIndex]) { | |
| newRows[rowIndex].classList.add('leaderboard-row-highlighted'); | |
| } | |
| } | |
| // Run on load and observe for dynamically added tables | |
| document.addEventListener('DOMContentLoaded', setupLeaderboardRowSorting); | |
| setTimeout(setupLeaderboardRowSorting, 500); | |
| setTimeout(setupLeaderboardRowSorting, 1000); | |
| setTimeout(setupLeaderboardRowSorting, 2000); | |
| setTimeout(setupLeaderboardRowSorting, 3000); | |
| setTimeout(setupLeaderboardRowSorting, 5000); | |
| const leaderboardObserver = new MutationObserver((mutations) => { | |
| // Check if table content was updated - need to reset sort state | |
| for (const m of mutations) { | |
| if (m.type === 'childList') { | |
| // Check if this affects one of our leaderboard tables | |
| const targetContainer = m.target.closest('#wer-leaderboard-table, #cer-leaderboard-table, #rtfx-leaderboard-table'); | |
| if (targetContainer) { | |
| // Reset sort state for this table when its content changes | |
| const tableId = '#' + targetContainer.id; | |
| if (rowSortState[tableId]) { | |
| rowSortState[tableId] = { rowIndex: null, ascending: true }; | |
| } | |
| // Refresh tooltips for the updated content | |
| addRowSortTooltips(targetContainer); | |
| } | |
| } | |
| } | |
| // Always try to set up - the WeakSet will prevent duplicate listeners | |
| setupLeaderboardRowSorting(); | |
| // Also add tooltips to any newly added tables | |
| const containers = document.querySelectorAll('#wer-leaderboard-table, #cer-leaderboard-table, #rtfx-leaderboard-table'); | |
| containers.forEach(addRowSortTooltips); | |
| }); | |
| function startLeaderboardObserver() { | |
| if (document.body) { | |
| leaderboardObserver.observe(document.body, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| setupLeaderboardRowSorting(); | |
| } else { | |
| setTimeout(startLeaderboardObserver, 10); | |
| } | |
| } | |
| startLeaderboardObserver(); | |
| })(); | |
| // Column resizing for leaderboard dataframes (WER, CER, RTFx tables) | |
| (function() { | |
| function setupColumnResize() { | |
| const leaderboardIds = ['#wer-leaderboard-table', '#cer-leaderboard-table', '#rtfx-leaderboard-table']; | |
| leaderboardIds.forEach(tableId => { | |
| const container = document.querySelector(tableId); | |
| if (!container) return; | |
| const table = container.querySelector('table'); | |
| if (!table || table.dataset.resizeSetup) return; | |
| table.dataset.resizeSetup = 'true'; | |
| const headers = table.querySelectorAll('thead th'); | |
| headers.forEach((th, index) => { | |
| // Skip if resize handle already exists | |
| if (th.querySelector('.col-resize-handle')) return; | |
| // Add title attribute for tooltip showing full header text | |
| const headerText = th.textContent.trim(); | |
| if (headerText && !th.getAttribute('title')) { | |
| th.setAttribute('title', headerText); | |
| } | |
| // Create resize handle | |
| const resizeHandle = document.createElement('div'); | |
| resizeHandle.className = 'col-resize-handle'; | |
| th.appendChild(resizeHandle); | |
| let startX, startWidth, isResizing = false; | |
| resizeHandle.addEventListener('mousedown', function(e) { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| isResizing = true; | |
| startX = e.pageX; | |
| startWidth = th.offsetWidth; | |
| resizeHandle.classList.add('resizing'); | |
| document.body.style.cursor = 'col-resize'; | |
| document.body.style.userSelect = 'none'; | |
| }); | |
| document.addEventListener('mousemove', function(e) { | |
| if (!isResizing) return; | |
| const diff = e.pageX - startX; | |
| const newWidth = Math.max(60, Math.min(300, startWidth + diff)); | |
| th.style.width = newWidth + 'px'; | |
| th.style.minWidth = newWidth + 'px'; | |
| th.style.maxWidth = newWidth + 'px'; | |
| // Also resize corresponding cells in tbody | |
| const tbody = table.querySelector('tbody'); | |
| if (tbody) { | |
| const rows = tbody.querySelectorAll('tr'); | |
| rows.forEach(row => { | |
| const cell = row.children[index]; | |
| if (cell) { | |
| cell.style.width = newWidth + 'px'; | |
| cell.style.minWidth = newWidth + 'px'; | |
| cell.style.maxWidth = newWidth + 'px'; | |
| } | |
| }); | |
| } | |
| }); | |
| document.addEventListener('mouseup', function() { | |
| if (isResizing) { | |
| isResizing = false; | |
| resizeHandle.classList.remove('resizing'); | |
| document.body.style.cursor = ''; | |
| document.body.style.userSelect = ''; | |
| } | |
| }); | |
| }); | |
| // Add title attributes to all cells for tooltip on truncated content | |
| const cells = table.querySelectorAll('tbody td'); | |
| cells.forEach(cell => { | |
| const cellText = cell.textContent.trim(); | |
| if (cellText && !cell.getAttribute('title')) { | |
| cell.setAttribute('title', cellText); | |
| } | |
| }); | |
| }); | |
| } | |
| // Run on load and observe for dynamically added tables | |
| document.addEventListener('DOMContentLoaded', setupColumnResize); | |
| setTimeout(setupColumnResize, 100); | |
| setTimeout(setupColumnResize, 500); | |
| setTimeout(setupColumnResize, 1000); | |
| setTimeout(setupColumnResize, 2000); | |
| setTimeout(setupColumnResize, 3000); | |
| const resizeObserver = new MutationObserver((mutations) => { | |
| setupColumnResize(); | |
| }); | |
| function startResizeObserver() { | |
| if (document.body) { | |
| resizeObserver.observe(document.body, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| setupColumnResize(); | |
| } else { | |
| setTimeout(startResizeObserver, 10); | |
| } | |
| } | |
| startResizeObserver(); | |
| })(); | |
| // Disable right-click context menu on dataframes (filter option has no function) | |
| (function() { | |
| function disableDataframeContextMenu() { | |
| const leaderboardIds = ['#wer-leaderboard-table', '#cer-leaderboard-table', '#rtfx-leaderboard-table']; | |
| leaderboardIds.forEach(tableId => { | |
| const container = document.querySelector(tableId); | |
| if (!container || container.dataset.contextMenuDisabled) return; | |
| container.dataset.contextMenuDisabled = 'true'; | |
| // Prevent default context menu on right-click | |
| container.addEventListener('contextmenu', function(e) { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| return false; | |
| }, true); | |
| }); | |
| // Also target any dataframe tables globally | |
| const dataframes = document.querySelectorAll('[data-testid="dataframe"], .table-wrap, .svelte-virtual-table-viewport'); | |
| dataframes.forEach(df => { | |
| if (df.dataset.contextMenuDisabled) return; | |
| df.dataset.contextMenuDisabled = 'true'; | |
| df.addEventListener('contextmenu', function(e) { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| return false; | |
| }, true); | |
| }); | |
| } | |
| // Run on load and observe for dynamically added tables | |
| document.addEventListener('DOMContentLoaded', disableDataframeContextMenu); | |
| setTimeout(disableDataframeContextMenu, 100); | |
| setTimeout(disableDataframeContextMenu, 500); | |
| setTimeout(disableDataframeContextMenu, 1000); | |
| setTimeout(disableDataframeContextMenu, 2000); | |
| const contextMenuObserver = new MutationObserver((mutations) => { | |
| disableDataframeContextMenu(); | |
| }); | |
| function startContextMenuObserver() { | |
| if (document.body) { | |
| contextMenuObserver.observe(document.body, { | |
| childList: true, | |
| subtree: true | |
| }); | |
| disableDataframeContextMenu(); | |
| } else { | |
| setTimeout(startContextMenuObserver, 10); | |
| } | |
| } | |
| startContextMenuObserver(); | |
| })(); | |
| </script> | |
| """ | |
| light_mode_head = """ | |
| <script> | |
| // Force light mode immediately to prevent flash of dark mode | |
| (function() { | |
| // Remove dark class if present | |
| document.documentElement.classList.remove('dark'); | |
| document.body && document.body.classList.remove('dark'); | |
| // Set theme parameter in URL if not already light (only once on initial load) | |
| var url = new URL(window.location); | |
| if (url.searchParams.get('__theme') !== 'light') { | |
| url.searchParams.set('__theme', 'light'); | |
| // Preserve the hash fragment when updating URL | |
| var newUrl = url.pathname + url.search + url.hash; | |
| history.replaceState(null, '', newUrl); | |
| } | |
| // Also watch for dark class being added and remove it | |
| var observer = new MutationObserver(function(mutations) { | |
| mutations.forEach(function(mutation) { | |
| if (mutation.attributeName === 'class') { | |
| var target = mutation.target; | |
| if (target.classList.contains('dark')) { | |
| target.classList.remove('dark'); | |
| } | |
| } | |
| }); | |
| }); | |
| // Start observing document element | |
| observer.observe(document.documentElement, { attributes: true }); | |
| // Also observe body when it's ready | |
| if (document.body) { | |
| observer.observe(document.body, { attributes: true }); | |
| } else { | |
| document.addEventListener('DOMContentLoaded', function() { | |
| document.body.classList.remove('dark'); | |
| observer.observe(document.body, { attributes: true }); | |
| }); | |
| } | |
| })(); | |
| </script> | |
| <style> | |
| /* Force light mode by overriding Gradio's CSS variables */ | |
| :root, html, body, .gradio-container, .dark, body.dark { | |
| --body-background-fill: white !important; | |
| --background-fill-primary: white !important; | |
| --background-fill-secondary: #f9fafb !important; | |
| --body-text-color: #1f2937 !important; | |
| --body-text-color-subdued: #6b7280 !important; | |
| --block-background-fill: white !important; | |
| --block-border-color: #e5e7eb !important; | |
| --block-label-background-fill: #f3f4f6 !important; | |
| --block-label-text-color: #374151 !important; | |
| --block-title-text-color: #111827 !important; | |
| --input-background-fill: white !important; | |
| --input-border-color: #d1d5db !important; | |
| --table-even-background-fill: #f9fafb !important; | |
| --table-odd-background-fill: white !important; | |
| --table-row-focus: #e0f2fe !important; | |
| --border-color-primary: #e5e7eb !important; | |
| --neutral-50: #f9fafb !important; | |
| --neutral-100: #f3f4f6 !important; | |
| --neutral-200: #e5e7eb !important; | |
| --neutral-700: #374151 !important; | |
| --neutral-800: #1f2937 !important; | |
| --neutral-900: #111827 !important; | |
| --neutral-950: #030712 !important; | |
| } | |
| /* Apply light background to main containers only */ | |
| html, body, .gradio-container { | |
| background: white !important; | |
| color: #1f2937 !important; | |
| } | |
| /* Target Gradio tables specifically, exclude Plotly */ | |
| .gradio-container table:not(.js-plotly-plot table), | |
| .dark .gradio-container table:not(.js-plotly-plot table) { | |
| background: white !important; | |
| color: #1f2937 !important; | |
| } | |
| .gradio-container th:not(.js-plotly-plot th), | |
| .gradio-container td:not(.js-plotly-plot td) { | |
| background: inherit !important; | |
| color: #1f2937 !important; | |
| border-color: #e5e7eb !important; | |
| } | |
| /* Override system dark mode preference */ | |
| @media (prefers-color-scheme: dark) { | |
| :root, html, body, .gradio-container { | |
| --body-background-fill: white !important; | |
| --background-fill-primary: white !important; | |
| --background-fill-secondary: #f9fafb !important; | |
| --body-text-color: #1f2937 !important; | |
| --block-background-fill: white !important; | |
| background: white !important; | |
| color: #1f2937 !important; | |
| } | |
| } | |
| /* Plotly charts */ | |
| .js-plotly-plot, .js-plotly-plot *, | |
| .plotly, .plotly * { | |
| background: unset !important; | |
| background-color: unset !important; | |
| } | |
| </style> | |
| """ | |
| # ============================================================================= | |
| # HTML Templates | |
| # ============================================================================= | |
| chart_gallery_html = """ | |
| <div class="chart-gallery"> | |
| <div class="chart-card"> | |
| <h4>π CER Performance Leaderboard</h4> | |
| <p>Ranks models by Character Error Rate. Especially useful for agglutinative and low-resource languages.</p> | |
| </div> | |
| <div class="chart-card"> | |
| <h4>π WER Performance Leaderboard</h4> | |
| <p>Ranks model families or top individual models by Word Error Rate. Filter by language to see top performers.</p> | |
| </div> | |
| <div class="chart-card"> | |
| <h4>π Speed vs Accuracy Tradeoffs</h4> | |
| <p>Scatter plot comparing model speed (RTFx) against accuracy (WER). Find the sweet spot between fast and accurate models.</p> | |
| </div> | |
| <div class="chart-card"> | |
| <h4>π CER vs WER Correlation</h4> | |
| <p>Scatter plot showing relationship between character and word error rates. Understand error patterns across models.</p> | |
| </div> | |
| </div> | |
| """ | |
| section_divider_html = "<hr style='margin: 2rem 0;'>" | |
| footer_html = """ | |
| <footer class="paza-footer"> | |
| <div class="paza-footer-links"> | |
| <a href="https://go.microsoft.com/fwlink/?LinkId=521839" target="_blank" rel="noopener noreferrer">Privacy & Cookies</a> | |
| <a href="https://www.microsoft.com/en-us/research/lab/microsoft-research-lab-africa-nairobi/" target="_blank" rel="noopener noreferrer">Microsoft Research Africa, Nairobi</a> | |
| <a href="https://www.microsoft.com/en-us/research/project/project-gecko/" target="_blank" rel="noopener noreferrer">Project Gecko</a> | |
| <a href="https://www.microsoft.com/en-us/research/" target="_blank" rel="noopener noreferrer" class="copyright">© Microsoft Research 2026</a> | |
| </div> | |
| </footer> | |
| """ | |