paza-bench / src /display /css_html_js.py
muchai-mercy's picture
pazabench version 2 release
2cdca7d
Raw
History Blame Contribute Delete
73.8 kB
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 &amp; 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">&copy; Microsoft Research 2026</a>
</div>
</footer>
"""