/* Video Benchmark — custom styling layered on top of the Gradio theme. * * Strategy: Gradio's theme handles buttons, inputs, tabs, dataframes, * plots. This file owns only the non-Gradio pieces — the HF-branded hero, * About-page prose, parameter cards — plus a few overrides so Gradio * widgets inherit HF spacing / typography. * * All HF brand tokens live at the top as CSS variables so anything below * can reference them without pulling an extra stylesheet. */ :root { /* Brand core */ --hf-yellow: #FFD21E; --hf-yellow-deep: #FFBD59; --hf-orange: #FF9D00; --hf-blue: #496EF0; --hf-blue-deep: #353E60; --hf-red: #DB3328; --hf-green: #009B3A; --hf-purple: #9747FF; /* Neutrals */ --hf-gray-900: #1B1B1D; --hf-gray-800: #32343D; --hf-gray-700: #475169; --hf-gray-600: #6A768F; --hf-gray-500: #9BA3AF; --hf-gray-300: #E5E7EB; --hf-gray-200: #EEEFF2; --hf-gray-100: #F5F6F8; --hf-white: #FFFFFF; /* Warm backgrounds */ --hf-cream: #FFF8DE; /* Semantic */ --fg-1: var(--hf-gray-900); --fg-2: var(--hf-gray-700); --fg-3: var(--hf-gray-600); --bg-1: var(--hf-white); --bg-2: var(--hf-gray-100); --bg-3: var(--hf-gray-200); --border-1: var(--hf-gray-200); --border-2: var(--hf-gray-300); /* Spacing + radii */ --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px; --radius-sm: 6px; --radius-md: 8px; --radius-lg: 12px; --radius-2xl: 24px; --radius-pill: 999px; /* Type scale */ --fs-xs: 12px; --fs-sm: 14px; --fs-md: 18px; --fs-lg: 20px; --fs-xl: 24px; --fs-2xl: 30px; --fs-4xl: 48px; --lh-4xl: 56px; --fw-medium: 500; --fw-semibold: 600; --fw-bold: 700; --fw-black: 900; } /* Dark-mode semantic tokens. Flipping the `--fg-*` / `--bg-*` / `--border-*` * scale in one place keeps typography consistent across every tab — any rule * that reads these tokens (prose, param cards, chips, tables, leaderboard * cards, tab strip) automatically picks up the dark palette without needing * its own `.dark` override. Covers both Gradio's `.dark` root class and the * OS-level `prefers-color-scheme` fallback. */ .dark, body.dark { --fg-1: var(--hf-gray-100); --fg-2: var(--hf-gray-300); --fg-3: var(--hf-gray-500); --bg-1: #1E2233; --bg-2: rgba(255, 255, 255, 0.04); --bg-3: rgba(255, 255, 255, 0.07); --border-1: rgba(255, 255, 255, 0.08); --border-2: rgba(255, 255, 255, 0.18); } @media (prefers-color-scheme: dark) { :root:not(.light) { --fg-1: var(--hf-gray-100); --fg-2: var(--hf-gray-300); --fg-3: var(--hf-gray-500); --bg-1: #1E2233; --bg-2: rgba(255, 255, 255, 0.04); --bg-3: rgba(255, 255, 255, 0.07); --border-1: rgba(255, 255, 255, 0.08); --border-2: rgba(255, 255, 255, 0.18); } } /* --- Hero --- * The hero is now a plain `gr.Row` of two `gr.Column`s (copy + mascot). Since * Gradio owns layout and widths, CSS here only paints — no escape-hatch * positioning, no viewport-unit math. * * Colors are driven by local CSS variables so dark mode can flip the whole * hero in one place (see the `.dark .hero` block at the bottom of this * section). Gradio applies `.dark` to the root when the dark theme is on, * and the `prefers-color-scheme` fallback covers cases where Gradio's theme * isn't overriding the OS preference. */ .hero { --hero-bg: var(--hf-cream); --hero-title: var(--hf-blue-deep); --hero-text: var(--hf-gray-800); --hero-tag-bg: var(--hf-white); --hero-tag-fg: var(--hf-blue-deep); --hero-tag-border: rgba(53, 62, 96, 0.12); --hero-stat-v: var(--hf-blue-deep); background: var(--hero-bg); border-radius: var(--radius-2xl); padding: var(--space-8) var(--space-10); margin-bottom: var(--space-6); align-items: center; } .hero .hero-copy h1 { font-size: var(--fs-4xl); line-height: var(--lh-4xl); font-weight: var(--fw-black); letter-spacing: -0.025em; margin: var(--space-2) 0 var(--space-3); color: var(--hero-title); } .hero .hero-copy p { font-size: var(--fs-md); color: var(--hero-text); max-width: 620px; line-height: 1.5; margin: 0; } .hero .hero-copy strong:first-child { display: inline-block; font-size: var(--fs-xs); font-weight: var(--fw-semibold); letter-spacing: 0.08em; text-transform: uppercase; color: var(--hero-tag-fg); background: var(--hero-tag-bg); border: 1px solid var(--hero-tag-border); border-radius: var(--radius-pill); padding: 4px 10px; } /* Dark-mode palette: keep the HF feel (yellow accent pill on deep navy) * while staying legible on a dark theme. Cover both Gradio's `.dark` root * class and the OS-level `prefers-color-scheme` media query. */ .dark .hero, body.dark .hero { --hero-bg: #1E2233; --hero-title: #FFFFFF; --hero-text: #C7CCD6; --hero-tag-bg: rgba(255, 209, 30, 0.16); --hero-tag-fg: var(--hf-yellow); --hero-tag-border: rgba(255, 209, 30, 0.3); --hero-stat-v: var(--hf-yellow); } @media (prefers-color-scheme: dark) { .hero:not(.light *) { --hero-bg: #1E2233; --hero-title: #FFFFFF; --hero-text: #C7CCD6; --hero-tag-bg: rgba(255, 209, 30, 0.16); --hero-tag-fg: var(--hf-yellow); --hero-tag-border: rgba(255, 209, 30, 0.3); --hero-stat-v: var(--hf-yellow); } } /* Stats are rendered as a 4-column markdown table — header row = numbers * (big, blue), body row = labels (small caps). The negative top margin pulls * the table up tight against the subtitle above it (Gradio adds its own * sibling-block gap which we don't want here). */ .hero .hero-stats { margin-top: var(--space-2) !important; padding-top: 0 !important; } .hero .hero-stats table, .hero .hero-stats thead, .hero .hero-stats tbody, .hero .hero-stats tr, .hero .hero-stats th, .hero .hero-stats td { border: 0 !important; background: transparent !important; box-shadow: none !important; } .hero .hero-stats table { border-collapse: collapse; width: auto; } .hero .hero-stats th, .hero .hero-stats td { padding: 0 var(--space-6) 0 0; text-align: left; vertical-align: top; white-space: nowrap; } .hero .hero-stats th:last-child, .hero .hero-stats td:last-child { padding-right: 0; } .hero .hero-stats th { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--fs-2xl); font-weight: var(--fw-semibold); color: var(--hero-stat-v); letter-spacing: -0.01em; padding-bottom: 2px; } .hero .hero-stats td { font-size: var(--fs-xs); color: var(--hero-text); text-transform: uppercase; letter-spacing: 0.08em; font-weight: var(--fw-semibold); } .hero .hero-mascot, .hero .hero-mascot img { max-width: 220px; margin-left: auto; } .hero .hero-mascot img { filter: drop-shadow(0 8px 24px rgba(53, 62, 96, 0.18)); } /* Gradio's `` custom element defaults to `display: inline`, * which makes any flex/grid child collapse to its intrinsic width. Force * the About-tab wrappers (prose + parameters grid) to behave as blocks * so they each use the full tab width instead of shrinking to content. */ gradio-html:has(.params-page), gradio-html:has(.prose) { display: block; width: 100%; } /* --- Parameters page --- * * Rendered at the bottom of the About tab after ``schema.ABOUT_HTML``, * so the top margin separates the parameter reference from the prose * and draws a visible yellow rule — the same ``.tab-intro`` treatment * used elsewhere — to introduce the new section. */ .params-page { display: flex; flex-direction: column; gap: var(--space-6); /* Gradio renders `gr.HTML` inside a `` custom element * that defaults to `display: inline`, so the flex/grid children * collapse to their intrinsic width and the cards wrap long before * the window edge. Force the tree to span the full tab width. */ width: 100%; margin-top: var(--space-6); } .param-group { width: 100%; } .param-group-head { margin-bottom: var(--space-4); } .param-group-head h3 { font-size: var(--fs-md); font-weight: var(--fw-semibold); margin: 0 0 4px; padding-bottom: 6px; border-bottom: 2px solid var(--hf-yellow); display: inline-block; } .param-group-head p { margin: 8px 0 0; color: var(--fg-2); font-size: var(--fs-sm); max-width: 760px; } .param-cards { /* Fixed 4-column grid: parameters read as a comparison table at a * glance, so equal track widths are more useful than ``auto-fit`` * here. ``minmax(0, 1fr)`` is what stops long descriptions from * blowing past their column (grid items default to ``min-width: * auto``, which uses the *content* min as the lower bound). The * narrower-viewport fallbacks below collapse the grid gracefully * before the cards become unreadable. */ display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-3); /* Explicit full width so the grid fills the Gradio tab content area * instead of shrinking to its intrinsic width inside the inline * `` wrapper, which would otherwise make the cards wrap * mid-window. */ width: 100%; } @media (max-width: 1100px) { .param-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } } @media (max-width: 820px) { .param-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (max-width: 540px) { .param-cards { grid-template-columns: 1fr; } } .param-card { --param-card-bg: var(--hf-white); --param-key-bg: var(--hf-cream); --param-key-fg: var(--hf-blue-deep); min-width: 0; background: var(--param-card-bg); border: 1px solid var(--border-1); border-radius: var(--radius-lg); padding: var(--space-4); transition: border-color 120ms cubic-bezier(0.16, 1, 0.3, 1); } .param-card:hover { border-color: var(--hf-yellow-deep); } .param-card-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; } .param-card-head .param-key { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--fs-xs); background: var(--param-key-bg); color: var(--param-key-fg); padding: 2px 8px; border-radius: var(--radius-sm); font-weight: var(--fw-semibold); } /* Dark-mode palette for param cards — drop the HF cream/blue chip * (which is a light-mode-only brand accent) and borrow the generic * `--bg-2` / `--bg-3` / `--fg-1` tokens so the pill matches `.prose * code` on the About tab exactly. Cover both Gradio's `.dark` root * class and the OS-level `prefers-color-scheme` media query. */ .dark .param-card, body.dark .param-card { --param-card-bg: var(--bg-1); --param-key-bg: var(--bg-3); --param-key-fg: var(--fg-1); } @media (prefers-color-scheme: dark) { .param-card:not(.light *) { --param-card-bg: var(--bg-1); --param-key-bg: var(--bg-3); --param-key-fg: var(--fg-1); } } .param-card-head .param-label { font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--fg-1); } .param-card p { margin: 0; color: var(--fg-2); font-size: var(--fs-sm); line-height: 1.55; } /* --- About --- * No ``max-width`` on the prose wrapper: the About tab intentionally * spans the full tab width so it lines up with the Parameters card grid * below it. Per-element line length is kept readable by the smaller * font-size + generous line-height instead. */ .prose { font-size: 15px; line-height: 1.6; color: var(--fg-1); width: 100%; } .prose h3 { font-size: var(--fs-lg); font-weight: var(--fw-semibold); margin: var(--space-6) 0 var(--space-2); } .prose h3:first-child { margin-top: 0; } .prose p { margin: 0 0 var(--space-3); } .prose ul { margin: 0 0 var(--space-3); padding-left: 20px; } .prose li { margin-bottom: 4px; } .prose code { /* Both `--bg-3` and `--fg-1` flip at the root in dark mode, so the * inline-code chip picks up the right palette automatically — no * per-element dark override needed. */ background: var(--bg-3); color: var(--fg-1); padding: 1px 6px; border-radius: 4px; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 0.88em; } /* --- Results-tab accordions (Filters / Visible columns) --- * Both panels are `gr.Accordion(elem_classes="results-accordion")` so * the header chrome is identical — a small uppercase title with Gradio's * chevron on the right. Filters starts open, Visible columns starts * closed, but the card border / typography / padding all match. */ .results-accordion { margin-bottom: var(--space-3); } .results-accordion > .label-wrap { padding: 4px var(--space-2) !important; gap: var(--space-2); } .results-accordion > .label-wrap > span, .results-accordion > .label-wrap span.label { padding-left: 0 !important; margin-left: 0 !important; font-size: var(--fs-sm); font-weight: var(--fw-semibold); letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); } .results-accordion[open] > .label-wrap { border-bottom: 1px solid var(--border-1); } /* Inset the accordion body so its contents aren't flush against the card * border. `.label-wrap ~ *` targets every sibling after the header, * which in Gradio's accordion is the single content div. */ .gradio-container .results-accordion > .label-wrap ~ * { padding: 2px var(--space-2) 4px !important; box-sizing: border-box; } .gradio-container .results-accordion:not(.filters-accordion) > .label-wrap ~ * { padding-bottom: 0 !important; } .gradio-container .results-accordion:not(.filters-accordion) > .label-wrap ~ * *:last-child { margin-bottom: 0 !important; padding-bottom: 0 !important; } /* Kill any bottom margin on the last content element in either accordion * body, so the visible gap between last row and the card bottom border * is identical in Filters and Visible columns (driven purely by the * body's own 12px bottom padding above). */ .gradio-container .results-accordion > .label-wrap ~ * > *:last-child, .gradio-container .results-accordion > .label-wrap ~ * > * > *:last-child { margin-bottom: 0 !important; } /* Strip every inner wrapper background + border inside both results * accordions, so filter chips and column checkboxes sit flat on the * accordion's own card — no nested "inner window" compartments. * Per-category color still applies because it's driven by checkbox / * label styling, not by wrapper backgrounds. */ .gradio-container .results-accordion .form, .gradio-container .results-accordion .block, .gradio-container .results-accordion .wrap, .gradio-container .results-accordion .gr-group, .gradio-container .results-accordion .gr-form { background: transparent !important; border: 0 !important; box-shadow: none !important; } /* --- Filter chips (toggle-button CheckboxGroup) --- * Each value in a `.filter-chips` CheckboxGroup renders as a pill button. * The underlying native checkbox is hidden; the whole label is the click * target. Checked state is detected with `:has(input:checked)` so Gradio's * own state management still works — we just restyle the presentation. * * All filters share the HF deep-navy selected color; we strip the * CheckboxGroup's own background + border so the chips sit directly on * the accordion's card instead of inside a nested "inner window". */ .filter-chips { --chip-color: var(--hf-yellow); --chip-color-text: var(--hf-gray-900); background: transparent !important; border: 0 !important; box-shadow: none !important; padding: 0 !important; min-width: 0 !important; overflow: visible; } /* Filters row: flex-wrap row so the five filter groups sit on one line * when there's room, and gracefully wrap to a second line when there * isn't. Each group asks for 20% of the row but is allowed to shrink * (min-width: 0) so its chips wrap inside it, and is allowed to grow * into the full width on narrow viewports. */ .filters-accordion, .filters-accordion * { box-sizing: border-box; } .filters-row { display: flex !important; flex-direction: row !important; flex-wrap: wrap !important; align-items: flex-start !important; gap: var(--space-5) var(--space-6) !important; width: 100% !important; } /* All 5 groups share the row equally (flex: 1 1 0). Inter-group * spacing is added inside each group via a transparent spacer on the * label+option wrapper, because Gradio reliably overrides outer `gap` * / `margin` / `padding` on our CheckboxGroup root. */ .filter-chips { box-sizing: border-box !important; } .filters-accordion .filter-chips { flex: 1 1 132px !important; min-width: 132px !important; max-width: 100% !important; } /* Target whichever container Gradio wraps its CheckboxGroup options in * (class name varies between versions) by matching any direct child of * `.filter-chips` that itself contains at least one checkbox label. */ .filter-chips > *:has(> label input[type="checkbox"]) { display: flex !important; flex-direction: row !important; flex-wrap: wrap !important; gap: 6px !important; align-items: flex-start; width: 100% !important; min-width: 0 !important; max-width: 100% !important; } /* Labels must be allowed to shrink below their content width so the * container can wrap them aggressively instead of letting a long pill * push the row wider than its column. */ .filter-chips label { flex: 0 0 auto; max-width: 100%; } .filter-chips label { display: inline-flex; align-items: center; justify-content: center; text-align: center; gap: 0 !important; min-width: 56px; padding: 6px 12px; border: 1px solid var(--border-2); border-radius: var(--radius-pill); background: var(--bg-1); color: var(--fg-2); font-size: var(--fs-sm); font-weight: var(--fw-medium); font-family: "IBM Plex Mono", ui-monospace, monospace; cursor: pointer; transition: background 120ms ease, color 120ms ease, border-color 120ms ease; user-select: none; } .filter-chips label > * { margin: 0 !important; } .filter-chips label:hover { border-color: var(--fg-3); color: var(--fg-1); } .filter-chips label input[type="checkbox"] { position: absolute !important; opacity: 0 !important; width: 0 !important; height: 0 !important; margin: 0 !important; pointer-events: none !important; } .filter-chips label:has(input:checked), .filter-chips label.selected, .filter-chips label[aria-checked="true"] { background: var(--chip-color) !important; border-color: var(--chip-color) !important; color: var(--chip-color-text) !important; } .filter-chips label:has(input:checked):hover, .filter-chips label.selected:hover, .filter-chips label[aria-checked="true"]:hover { filter: brightness(0.94); } /* Click feedback — flash the pill yellow on press for tactile feedback, * independent of its checked state. */ .filter-chips label:active { background: var(--chip-color) !important; border-color: var(--chip-color) !important; color: var(--chip-color-text) !important; } /* Filter category labels (Codec, Pixel format, Backend, GOP, CRF) reuse * the same font treatment as the Visible-columns category headers * (`.col-cat-master label > span:last-child`) so the two accordions read * as one visual system. We keep the neutral `--fg-3` color (no per- * category tint) and drop the weight one notch from semibold → medium * so the labels sit visually behind the chip pills below them. */ .filter-chips > .block-label, .filter-chips > label > span:first-child { font-size: var(--fs-sm); font-weight: var(--fw-medium); letter-spacing: 0.02em; text-transform: uppercase; color: #ffffff; margin-bottom: 2px; } /* Codec / Pixel format / Backend filter labels mirror the typography * of the `.col-cat-master` Visible-columns category headers (uppercase * + small + slight letter-spacing) but stay one weight step thinner * (medium instead of semibold) and keep the inherited neutral `--fg-3` * color so the labels don't compete visually with the category-colored * headers in the Visible-columns accordion. Descendant combinators * (not `>`) are used so the rule matches regardless of any wrapper * Gradio inserts between the CheckboxGroup root and its label * element — the pre-existing `.filter-chips > .block-label` rule uses * `>` and doesn't match in current Gradio versions, which is why these * `!important` declarations are needed to take effect. */ .filter-cat .block-label, .filter-cat label > span:first-child, .filter-cat span[data-testid="block-info"] { font-size: var(--fs-sm) !important; font-weight: var(--fw-medium) !important; letter-spacing: 0.02em !important; text-transform: uppercase !important; color: #ffffff !important; white-space: normal !important; overflow: visible !important; text-overflow: clip !important; /* Nudge the category label (Codec, Pixel format, …) a touch right so * it sits visually inset from the accordion edge instead of crowding * the chevron / left rail. */ padding-left: 8px !important; } /* Category-tinted checkboxes — each `CheckboxGroup` inside the Visible- * columns accordion gets a brand color applied through Gradio's own * checkbox CSS variables. Overriding the variables (not the `input` * itself) means the hover / focus / disabled states still track * Gradio's theme; we just recolor the selected chip. * * Colors are pulled from the leaderboard ``PODIUM_COLORS`` palette in * ``src/schema.py`` — chromatic neighbours of the brand hues, pulled * 20–30% toward gray. Using the same desaturated set across the column * picker and the leaderboard radar / cards keeps the page reading as * one visual system instead of two competing palettes (the saturated * HF brand colors fight the muted heatmap chips in the table below). * * Config · dusty blue (#6B8EBF) * Compression · warm sand (#D99B5A) * Speed · sage (#7FA97E) * Quality · muted lavender (#A98FBF) */ .col-cat { --cat-color: #6B8EBF; } .col-cat-config { --cat-color: #6B8EBF; } .col-cat-compression { --cat-color: #D99B5A; } .col-cat-speed { --cat-color: #7FA97E; } .col-cat-quality { --cat-color: #A98FBF; } .col-cat { --checkbox-background-color-selected: var(--cat-color); --checkbox-border-color-selected: var(--cat-color); --checkbox-background-color-focus: var(--cat-color); --checkbox-border-color-focus: var(--cat-color); } .col-cat input[type="checkbox"] { accent-color: var(--cat-color); } .col-cat input[type="checkbox"]:checked { background-color: var(--cat-color) !important; border-color: var(--cat-color) !important; } .col-cat > .block-label, .col-cat > label > span:first-child, .col-cat span[data-testid="block-info"] { color: var(--cat-color) !important; font-weight: var(--fw-semibold); } /* Strip the default pill / border Gradio renders around each * CheckboxGroup option so the category picker reads as a flat list of * checkbox + label rows, not buttons. Forcing zero left padding on * every wrapper ensures the first sub-checkbox of each row aligns * vertically with the master checkbox above it. */ .col-cat, .col-cat > *, .col-cat .wrap { padding-left: 0 !important; margin-left: 0 !important; } .col-cat .wrap { gap: 6px 28px !important; padding: 0 !important; } .col-cat label { padding: 0 !important; margin-left: 0 !important; background: transparent !important; border: 0 !important; box-shadow: none !important; gap: 6px; min-height: 0; } .col-cat-master, .col-cat-master > *, .col-cat-master label { padding-left: 0 !important; margin-left: 0 !important; } /* Master "toggle all" checkbox sitting above each category group. Uses * the same per-category color variable, but renders bolder/bigger so it * reads as the category header rather than another option. It's aligned * flush-left with the option checkboxes below by zeroing its padding. */ .col-cat-master { padding: 0 !important; margin: 0 0 6px !important; background: transparent !important; border: 0 !important; } .col-cat-master label { padding: 0 !important; gap: 6px !important; background: transparent !important; border: 0 !important; display: inline-flex !important; align-items: center !important; } .col-cat-master, .col-cat-master > *, .col-cat-master label, .col-cat-master label > span, .col-cat, .col-cat > *, .col-cat .wrap, .col-cat label, .col-cat label > span { overflow: visible !important; } .col-cat-master label, .col-cat label { padding: 4px 0 !important; line-height: 1.6 !important; min-height: 28px !important; align-items: center !important; } .col-cat-master input[type="checkbox"], .col-cat input[type="checkbox"] { width: 18px !important; height: 18px !important; min-width: 18px !important; min-height: 18px !important; flex: 0 0 18px !important; margin: 0 !important; padding: 0 !important; border-radius: 4px !important; box-sizing: border-box !important; overflow: visible !important; display: inline-block !important; vertical-align: middle !important; } .col-cat-master label > span:last-child, .col-cat-master span[data-testid="block-info"] { font-size: var(--fs-sm); font-weight: var(--fw-semibold); letter-spacing: 0.02em; color: var(--cat-color) !important; text-transform: uppercase; } .col-cat-master input[type="checkbox"] { accent-color: var(--cat-color); } .col-cat-master input[type="checkbox"]:checked { background-color: var(--cat-color) !important; border-color: var(--cat-color) !important; } /* --- Results table --- * Each metric cell carries an inline `style="--chip-bg: rgb(...)"` set by * the Python renderer (see ``_chip_style`` in app.py), which Gradio * applies to the outer `
` wrapper through the * ``metadata.styling`` channel. We let that variable cascade down into * the inner span and paint a content-sized pill there — full-cell * backgrounds (the default for ``cell_style``) would flood the whole * column track since the body-cell is a fixed-width grid slot. * * Going through ``metadata.styling`` (instead of baking the chip into * the cell as raw HTML) is what lets the metric columns keep * ``datatype="number"`` and sort by the underlying value rather than * by the ```` HTML prefix. * * We kill the default Gradio row / column separators and lighten the * header so the colored chips carry the visual weight. */ .gradio-container .table-wrap { --table-head-bg: var(--bg-2); --table-head-fg: var(--fg-1); --table-head-border: var(--border-1); } /* Results table: column widths come from ``column_widths`` in Python * (see ``_column_widths_for`` in app.py), which Gradio's JS applies to * both header cells and body cells at once — keeping them in sync. * * The rules below are purely cosmetic: they let header labels wrap onto * a second line inside the (data-sized, capped) column track instead of * overflowing or being clipped. * * 1. ``height: auto`` on the th lets the header row grow when a label * needs two lines. * 2. ``display: block`` on ``.cell-wrap`` converts it from a flex * container to a block box, so ``.header-content`` fills the full * column width and gives the text a bounded width to wrap against. * (While cell-wrap is flex, header-content is a flex item sized to * its own content width — not the column width — so text never * wraps.) * 3. ``white-space: normal`` on all descendants overrides Gradio's * scoped ``span { white-space: nowrap }`` so the label text flows * onto a second line. */ .results-table .table-wrap thead .header-cell { height: auto !important; } .results-table .table-wrap thead .cell-wrap { display: block !important; height: auto !important; } .results-table .table-wrap thead .header-content { overflow: visible !important; } .results-table .table-wrap thead .header-cell * { white-space: normal !important; overflow: visible !important; text-overflow: clip !important; } .gradio-container .table-wrap thead th { border: 0 !important; box-shadow: none !important; border-bottom: 1px solid var(--table-head-border) !important; background: var(--table-head-bg) !important; color: var(--table-head-fg) !important; } /* Heatmap chip painted via the ``--chip-bg`` CSS variable that the * Python renderer sets on each metric cell's wrapper through * ``metadata.styling`` (see ``_chip_style`` in app.py). The cell wrapper * itself stays unpainted — only the inner `` that holds the value * is collapsed to its content width and tinted with the rdylgn color, * so each cell reads as "small colored pill behind the number" instead * of a full-cell color flood. * * EditableCell.svelte ships the value span with ``display: block; * width: 100%; flex: 1 1 0%; white-space: nowrap; overflow: hidden`` * (Svelte-scoped ``span`` selector). Those defaults outweigh any plain * declaration we add, so every property below uses ``!important`` to * win — including ``overflow: visible``, otherwise the chip's * ``border-radius`` is clipped at the cell's edges. * * The attribute selector ``[style*="--chip-bg"]`` only fires on cells * whose inline ``style=`` actually carries the variable, so non-metric * cells (and metric cells with null values, where ``_chip_style`` is * skipped) keep their plain text rendering. */ .results-table .body-cell[style*="--chip-bg"] .cell-wrap > span { display: inline-block !important; flex: 0 0 auto !important; width: fit-content !important; background: var(--chip-bg); color: var(--hf-gray-900); padding: 2px 8px; border-radius: var(--radius-sm); white-space: nowrap !important; overflow: visible !important; text-overflow: clip !important; font-variant-numeric: tabular-nums; line-height: 1.4; } /* Row-count caption sits below the table as a quiet, right-aligned * annotation so it reads as metadata about the table above rather than * a heading. */ .results-count { margin-top: var(--space-2) !important; text-align: right; color: var(--fg-3); font-size: var(--fs-xs); letter-spacing: 0.04em; } /* Dark mode: flip the header to a deep slate with light text so the * column names stay legible against Gradio's dark table surface. * Cover both the `.dark` root class Gradio sets on theme toggle and the * OS-level `prefers-color-scheme` fallback. */ .dark .gradio-container .table-wrap, body.dark .gradio-container .table-wrap { --table-head-bg: #2A2E3E; --table-head-fg: #F5F6F8; --table-head-border: rgba(255, 255, 255, 0.08); } @media (prefers-color-scheme: dark) { .gradio-container .table-wrap:not(.light *) { --table-head-bg: #2A2E3E; --table-head-fg: #F5F6F8; --table-head-border: rgba(255, 255, 255, 0.08); } } /* --- Leaderboards tab --- * Two-column layout: a Plotly radar on the left, a stack of "podium" * cards on the right. The card color (rank badge + left accent bar) * maps 1:1 to its polygon in the radar via schema.PODIUM_COLORS, so * users can trace any shape back to its config at a glance. * * Controls row uses a gr.Radio restyled into pill buttons for the * Ranking selector (Overall / Quality / Encoding / Decoding); the * pattern mirrors .filter-chips but in single-select semantics. */ /* One-card header: promote .lb-controls from a multi-column Row of card * surfaces to a single flat surface, then strip the background / border / * shadow from every nested wrapper Gradio inserts between the row and the * actual controls. The three columns (Access pattern / Top N / Ranking) * sit on one unified card with the dropdown + slider on the left and the * access-pattern pill buttons aligned to the right. */ .lb-controls { gap: var(--space-6) !important; align-items: start !important; margin-bottom: var(--space-4); padding: var(--space-3) var(--space-4); background: var(--bg-1); border: 1px solid var(--border-1); border-radius: var(--radius-lg); overflow: visible !important; } /* Gradio's slider renders its number-input + reset overlay above the * trough; keep the column non-clipping so its rounded corners stay * visible inside .lb-controls' padded card. */ .lb-controls, .lb-controls > *, .lb-controls .block, .lb-controls .form, .lb-controls .gr-form { overflow: visible !important; } /* All three columns of the controls card align to the top of the row * (driven by ``align-items: start`` on ``.lb-controls`` above). Each * column then lays out its label + control naturally from the top, * so the three column labels — "Access pattern", "Top N configs", * "Ranking" (visually replaced by the pills since * ``show_label=False``) — sit on a shared baseline. */ .lb-controls .lb-topn-col { display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: flex-start !important; } .lb-controls .lb-topn-col .lb-topn { width: 100%; max-width: 360px; } /* Right-align the ranking pills horizontally so they hug the right edge * of the controls card, and vertically center the whole column within * the row using ``align-self: center`` (which overrides the parent's * ``align-items: start``). The dropdown column is taller, so the row's * height is driven by it; the shorter pills column then sits in the * vertical middle while the dropdown / slider keep their top-aligned * labels. */ .lb-controls .lb-cats-col { display: flex !important; flex-direction: column !important; align-items: flex-end !important; align-self: center !important; } .lb-controls > .gr-column, .lb-controls .gr-form, .lb-controls .form, .lb-controls .block, .lb-controls > * > .block, .lb-controls > * > .form { background: transparent !important; border: 0 !important; box-shadow: none !important; padding: 0 !important; } /* Dark-mode surface: every "window" in the app (controls bar, podium * cards, compare-controls strip, param cards) shares one background * token (``--bg-1``) so the page reads as a consistent visual system * instead of a stack of subtly-different gray slabs. ``--bg-1`` already * flips between light (white) and dark (#1E2233), so per-theme * overrides only need to soften the border. */ .dark .lb-controls, body.dark .lb-controls { border-color: rgba(255, 255, 255, 0.08); } @media (prefers-color-scheme: dark) { .lb-controls:not(.light *) { border-color: rgba(255, 255, 255, 0.08); } } /* Ranking pills — restyled gr.Radio. Gradio's default renders each * option as a stacked radio+label row; we hide the native input and * paint the wrapping label as a pill, using :has(input:checked) to * pick up the current selection. */ .ranking-pills, .ranking-pills > *, .ranking-pills .wrap { background: transparent !important; border: 0 !important; box-shadow: none !important; padding: 0 !important; } .ranking-pills .wrap { display: flex !important; flex-direction: row !important; flex-wrap: wrap !important; justify-content: flex-end !important; gap: 6px !important; } .ranking-pills > .block-label, .ranking-pills > label > span:first-child { font-size: var(--fs-xs); font-weight: var(--fw-semibold); letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); margin-bottom: var(--space-2); } .ranking-pills label { display: inline-flex; align-items: center; justify-content: center; gap: 0 !important; padding: 6px 14px; min-width: 72px; border: 1px solid var(--border-2); border-radius: var(--radius-pill); background: var(--bg-1); color: var(--fg-2); font-size: var(--fs-sm); font-weight: var(--fw-medium); cursor: pointer; transition: background 120ms ease, color 120ms ease, border-color 120ms ease; user-select: none; } .ranking-pills label > * { margin: 0 !important; } .ranking-pills label:hover { border-color: var(--fg-3); color: var(--fg-1); } .ranking-pills label input[type="radio"] { position: absolute !important; opacity: 0 !important; width: 0 !important; height: 0 !important; margin: 0 !important; pointer-events: none !important; } .ranking-pills label:has(input:checked), .ranking-pills label[aria-checked="true"] { background: var(--hf-gray-900) !important; border-color: var(--hf-gray-900) !important; color: var(--hf-white) !important; } .dark .ranking-pills label:has(input:checked), .dark .ranking-pills label[aria-checked="true"] { background: var(--hf-yellow) !important; border-color: var(--hf-yellow) !important; color: var(--hf-gray-900) !important; } /* Main row: radar plot | cards. Kill the plot's own card chrome so the * radar floats inside the same surface as the controls above it. */ .lb-main { gap: var(--space-4) !important; align-items: stretch !important; } .lb-radar .plot-container, .lb-cards-wrap { background: transparent; } /* Card list — sized to match the 520px radar plot on the left so both * columns share the same bottom edge. When the Top-N slider produces * more cards than fit in that height, the column scrolls internally * instead of pushing the whole tab taller. The header is `position: * sticky` so the "Top configurations" title stays visible while the * reader scrolls through the podium. */ .lb-cards-wrap { width: 100%; max-height: 520px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border-2) transparent; } .lb-cards-wrap::-webkit-scrollbar { width: 8px; } .lb-cards-wrap::-webkit-scrollbar-track { background: transparent; } .lb-cards-wrap::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: var(--radius-pill); } .lb-cards-wrap::-webkit-scrollbar-thumb:hover { background: var(--fg-3); } .lb-cards { display: flex; flex-direction: column; gap: var(--space-3); padding-right: var(--space-2); } /* Per-tab section heading rendered by ``_tab_intro`` in app.py. The *

is visually matched to the Parameters page's

s: yellow * underline, semibold, inline-block so the bar only stretches under * the title text. The muted subtitle paragraph sits below, capped at * a comfortable reading width. */ .tab-intro-wrap { margin-top: var(--space-2); margin-bottom: var(--space-4); } .tab-intro { display: flex; flex-direction: column; gap: 4px; } .tab-intro h2 { font-size: var(--fs-xl); font-weight: var(--fw-bold); margin: 0; padding-bottom: 6px; border-bottom: 2px solid var(--hf-yellow); display: inline-block; align-self: flex-start; color: var(--fg-1); letter-spacing: -0.01em; } .tab-intro p { margin: 0; color: var(--fg-3); font-size: var(--fs-sm); line-height: 1.5; max-width: 760px; } .dark .tab-intro h2, body.dark .tab-intro h2 { color: var(--hf-white); } .dark .tab-intro p, body.dark .tab-intro p { color: var(--hf-gray-500); } @media (prefers-color-scheme: dark) { .tab-intro h2:not(.light *) { color: var(--hf-white); } .tab-intro p:not(.light *) { color: var(--hf-gray-500); } } .lb-empty { padding: var(--space-5); text-align: center; color: var(--fg-3); border: 1px dashed var(--border-2); border-radius: var(--radius-lg); } .lb-card { position: relative; display: flex; align-items: stretch; gap: var(--space-3); padding: var(--space-3) var(--space-4) var(--space-3) calc(var(--space-4) + 6px); background: var(--bg-1); border: 1px solid var(--border-1); border-radius: var(--radius-lg); transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease; } .lb-card::before { /* Left accent strip keyed to the polygon color — lets users eyeball * "which card goes with which shape" even before reading the badge. */ content: ""; position: absolute; left: 0; top: 10px; bottom: 10px; width: 4px; background: var(--rank-color, var(--hf-gray-300)); border-radius: 0 4px 4px 0; } .lb-card:hover { border-color: var(--border-2); box-shadow: 0 2px 8px rgba(27, 27, 29, 0.06); } .lb-badge { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 999px; background: var(--rank-color, var(--hf-gray-500)); color: var(--hf-white); font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--fs-sm); font-weight: var(--fw-bold); line-height: 1; align-self: center; box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.9) inset; } .lb-card-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); } .lb-card-head { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; } .lb-codec { display: inline-flex; align-items: center; padding: 2px 0; color: var(--fg-1); font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--fs-xs); font-weight: var(--fw-semibold); letter-spacing: 0.02em; } .lb-config { color: var(--fg-2); font-size: var(--fs-sm); } .lb-config code { background: var(--bg-3); color: var(--fg-1); padding: 1px 6px; border-radius: 4px; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 0.88em; } .lb-metrics { display: flex; flex-wrap: wrap; gap: 6px; } .lb-metric { display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px; border-radius: var(--radius-sm); background: var(--bg-2); border: 1px solid var(--border-1); font-size: var(--fs-xs); white-space: nowrap; } .lb-metric-k { color: var(--fg-3); text-transform: uppercase; letter-spacing: 0.06em; font-weight: var(--fw-semibold); font-size: 10px; } .lb-metric-v { color: var(--fg-1); font-family: "IBM Plex Mono", ui-monospace, monospace; font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums; } /* Dark-mode tweaks — cards need a slightly lifted background and * lighter metric chips so they don't disappear into the tab surface. */ .dark .lb-card, body.dark .lb-card { border-color: rgba(255, 255, 255, 0.08); } .dark .lb-card:hover, body.dark .lb-card:hover { border-color: rgba(255, 255, 255, 0.18); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25); } .dark .lb-metric, body.dark .lb-metric { background: rgba(255, 255, 255, 0.05); border-color: rgba(255, 255, 255, 0.08); } .dark .lb-metric-v, body.dark .lb-metric-v { color: var(--hf-gray-100); } .dark .lb-metric-k, body.dark .lb-metric-k { color: var(--hf-gray-500); } .dark .lb-config, body.dark .lb-config { color: var(--hf-gray-300); } .dark .lb-config code, body.dark .lb-config code { background: rgba(255, 255, 255, 0.07); color: var(--hf-gray-100); } .dark .lb-badge, body.dark .lb-badge { box-shadow: 0 0 0 3px rgba(27, 27, 29, 0.9) inset; } @media (prefers-color-scheme: dark) { .lb-card:not(.light *) { border-color: rgba(255, 255, 255, 0.08); } .lb-metric:not(.light *) { background: rgba(255, 255, 255, 0.05); border-color: rgba(255, 255, 255, 0.08); } } /* "Selected configurations" section heading sits under the radar/card * row and introduces the dataframe. Match the prose scale used in the * params page so the tab reads as header → content → header → content. */ .lb-table-head { margin-top: var(--space-6) !important; margin-bottom: var(--space-2) !important; } .lb-table-head h3 { font-size: var(--fs-lg); font-weight: var(--fw-semibold); margin: 0; padding-bottom: 6px; border-bottom: 2px solid var(--hf-yellow); display: inline-block; color: var(--fg-1); } .dark .lb-table-head h3, body.dark .lb-table-head h3 { color: var(--hf-white); } /* Kill the dataframe's outer card so the table reads as part of the * tab (matching the Results table treatment), and bump the Score * column to monospace tabular numerals for quick top-down scanning. * Rank is now a colored badge (rendered as HTML inside the cell), so * the span's monospace font handles alignment — no need to restyle * the td. */ .lb-table .table-wrap { border: 0 !important; box-shadow: none !important; background: transparent !important; } .lb-table .table-wrap tbody td:last-child { font-family: "IBM Plex Mono", ui-monospace, monospace; font-variant-numeric: tabular-nums; font-weight: var(--fw-semibold); } /* Center header labels in the leaderboard table. Gradio nests the label * text inside ``.cell-wrap`` > ``.header-content`` flex wrappers, so we * also need to neutralize their ``justify-content`` (defaults to * ``flex-start``) — otherwise ``text-align: center`` on the ``th`` * alone is overridden by the inner flex layout. */ .lb-table .table-wrap thead th, .lb-table .table-wrap thead th * { text-align: center !important; justify-content: center !important; } /* Inline rank badge used inside the table's Rank column. Same visual * as the card badge, just smaller and without the inset ring that * makes sense only on the card's white surface. */ .lb-badge-inline { width: 26px; height: 26px; font-size: var(--fs-xs); box-shadow: none; } /* --- Compare tab plots --- * Plotly renders text via SVG `` with a `fill=...` attribute * set server-side (see `_PLOTLY_FG` in app.py). That baked-in color * is a single mid-slate for both themes, which works but leaves * titles / legends a bit washed-out. CSS `fill` overrides the SVG * attribute, so we swap in theme-aware tokens (`--fg-1` / `--fg-2`) * only for Compare plots — the Leaderboards radar keeps its muted * gray on purpose, to avoid stealing attention from the polygons. */ .compare-plot .gtitle, .compare-plot .g-gtitle { fill: var(--fg-1) !important; font-weight: var(--fw-semibold) !important; } .compare-plot .xtitle, .compare-plot .ytitle, .compare-plot .legendtitletext { fill: var(--fg-1) !important; } .compare-plot .legendtext, .compare-plot .xtick > text, .compare-plot .ytick > text, .compare-plot .annotation-text { fill: var(--fg-2) !important; } /* Axis spines + grid lines: use the neutral border token so they * stay visible on dark without turning harsh on light. */ .compare-plot .xaxislayer-above path.domain, .compare-plot .yaxislayer-above path.domain, .compare-plot .zerolinelayer path { stroke: var(--border-2) !important; } .compare-plot .gridlayer path { stroke: var(--border-1) !important; } /* The caption sits above each bar plot and explains the current * selection; keep it readable but subordinate to the plot title. */ .compare-caption { color: var(--fg-2) !important; font-size: var(--fs-sm) !important; margin: var(--space-1) 0 var(--space-2) !important; } /* Per-chart titles ("Metric averages by configuration axis", "Quality * vs. compression", "Decoding latency by codec and access pattern") * render as ``

`` from the Markdown ``###`` prefix. The default * Gradio prose h3 is too loud for these section headers — shrink one * step from `--fs-lg` (20px) to `--fs-md` (18px) and tighten the gap * between the title and the description paragraph below it. */ .compare-caption h3 { font-size: var(--fs-md) !important; margin: 0 0 4px !important; line-height: 1.3 !important; } /* The configurable bar chart + its title + its dropdowns live in one * `.compare-panel` group so they read as a single unit. The panel * itself is the outer "card": one border + radius wraps the header * strip and the chart together, with extra bottom padding so the * chart breathes inside the card. The `.compare-controls` strip on * top keeps its own tinted `--bg-1` background (its previous color), * so the header reads as a distinct band against the chart area * (which sits on the page background) without breaking the shared * card outline. */ .compare-panel { margin-bottom: var(--space-4); background: transparent !important; border: 1px solid var(--border-1) !important; border-radius: var(--radius-lg); box-shadow: none !important; padding: 0 !important; overflow: hidden; } /* Gradio wraps every `gr.Group` / `gr.Column` child in its own `.block` * container that ships a default 1px border + box-shadow. Without this * reset those inner borders paint a second / third outline at the * bottom of the panel, stacking under the `.compare-panel` border and * reading as two parallel lines. Strip chrome on every wrapper so only * the panel's own border is visible. */ .compare-panel > div, .compare-panel > div > div, .compare-panel .block, .compare-panel .form { background: transparent !important; border: 0 !important; box-shadow: none !important; } /* Header strip uses the shared `--bg-1` surface token — same shade as * every other "window" in the app (leaderboard controls card, param * cards, podium cards). The selector is scoped under `.compare-panel` * so its specificity (2 classes) matches the generic `.compare-panel * .block` reset earlier and this rule wins — otherwise Gradio tags * the gr.Column with both `.compare-controls` and `.block`, and the * reset's higher specificity would force the header to `transparent` * and the strip would vanish. */ .compare-panel .compare-controls { background: var(--bg-1) !important; border: 0 !important; border-bottom: 1px solid var(--border-1) !important; padding: var(--space-4) !important; margin: 0 !important; border-radius: 0; } .compare-controls .compare-caption { margin-top: 0 !important; margin-bottom: 0 !important; } .compare-controls .compare-caption p:last-child { margin-bottom: 0 !important; } /* Control-label treatment for the Leaderboards "Top N configs" slider * and the Compare-tab "Metric" / "Group by" dropdowns — small uppercase * semibold cap in ``--fg-3`` so they all match the ``.filter-chips`` / * ``.ranking-pills`` label family. */ .lb-topn > .block-label, .lb-topn > label > span:first-child, .lb-topn span[data-testid="block-info"], .cmp-control > .block-label, .cmp-control > label > span:first-child, .cmp-control span[data-testid="block-info"] { font-size: var(--fs-xs); font-weight: var(--fw-semibold); letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); margin-bottom: var(--space-2); } /* Chart area sits below the `.compare-controls` header inside the * shared `.compare-panel` card. It picks up the same `--bg-1` surface * token as the controls strip above it so the whole panel reads as * one continuous tinted card — the bottom border on `.compare-controls` * is the only visual divider between header and chart. Plotly itself * paints transparent (`paper_bgcolor` / `plot_bgcolor` are * `rgba(0,0,0,0)`; see `_PLOTLY_*` in app.py), so the container's * background shows through cleanly; we just have to strip every nested * Gradio + plotly wrapper so nothing paints a contrasting band over it. */ .compare-plot { background: var(--bg-1) !important; border: 0 !important; box-shadow: none !important; padding: var(--space-3) var(--space-3) 0 !important; } .compare-plot > div, .compare-plot .plot-container, .compare-plot .plotly, .compare-plot .svg-container, .compare-plot .tabs, .compare-plot .tab-nav, .compare-plot .tab-nav button, .compare-plot .tabitem, .compare-plot .modebar, .compare-plot .modebar-container, .compare-plot .modebar-group { background: transparent !important; border: 0 !important; box-shadow: none !important; } /* --- Submit-tab group labels --- * The Submit tab stacks parameter CheckboxGroups ("Dataset", "Codec", * "Pixel format", "GOP", "CRF", "Access pattern", "Backend") — each one * titles its row of checkboxes. Match the per-chart section titles in * the Compare tab (`.compare-caption h3`): `--fs-md` / semibold / * default text color so the sweep builder reads as a sequence of real * section headings, consistent with the rest of the app. */ .submit-checks > .block-label, .submit-checks > label > span:first-child, .submit-checks span[data-testid="block-info"] { font-size: var(--fs-md); font-weight: var(--fw-semibold); letter-spacing: normal; text-transform: none; color: var(--fg-1); line-height: 1.3; margin: 0 0 4px; } /* --- Submit-tab parameter cards --- * Each parameter group (Datasets, Codecs, Pixel formats, GOP, CRF, * Access patterns, Backends, Run settings) is wrapped in its own * `.submit-section` card so the form reads as a list of distinct * knobs rather than one monolithic slab. The card paints in `--bg-1` * with a 1px border + rounded corners — same surface treatment as * the Compare tab's `.compare-panel` cards — and strips the wrapping * `.block` / `.form` chrome Gradio bakes around every gr.Row / * gr.Column / gr.Group child so the card surface shows through * uniformly between the actual interactive inputs (textboxes, * sliders, checkbox groups), which keep their own surfaces. */ .submit-section { margin-bottom: var(--space-2); background: var(--bg-1) !important; border: 1px solid var(--border-1) !important; border-radius: var(--radius-lg); box-shadow: none !important; padding: var(--space-3) var(--space-4) !important; } /* Strip every wrapping `.block` / `.form` chrome Gradio paints around * the CheckboxGroup / Textbox / Slider children so the card surface * shows through and the children sit flush against the card padding * (no double-padding, no nested borders, no gradio default gap). The * actual interactive controls (checkbox pills, textbox input, slider * track) keep their own surfaces because they're matched by more * specific selectors below. */ .submit-section > div, .submit-section > div > div, .submit-section .block, .submit-section .form { background: transparent !important; border: 0 !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; gap: var(--space-2) !important; } /* The CheckboxGroup's own internal padding + label margin add a chunk * of dead space above the pills; collapse it so the label sits right * above the checkboxes. */ .submit-section .submit-checks { padding: 0 !important; } .submit-section .submit-checks > .block-label, .submit-section .submit-checks > label > span:first-child { margin-bottom: 4px !important; } .submit-section label > .wrap { padding: 0 !important; } /* --- Submit-tab right-column --- * The action rail (total count / estimate / Submit CTA / queue) sits * directly on the page background with no enclosing card so it reads * as a quiet sidebar against the bordered parameter cards on the left. * A bit of left padding pulls it off the gutter between the columns. */ .submit-right { padding-left: var(--space-3); gap: var(--space-2) !important; } /* Total-configs line above the Submit CTA — centered headline that * makes the count the visual anchor of the right column: the number * itself reads as a big HF-yellow display figure, with a small muted * "total configs" caption beneath it so the user always sees exactly * what the yellow button is about to commit. */ .submit-right .submit-summary { text-align: center; margin: 0; line-height: 1.1; } .submit-right .submit-summary p { margin: 0; font-size: var(--fs-xs, 11px); font-weight: var(--fw-semibold); text-transform: uppercase; letter-spacing: 0.08em; color: var(--fg-3); } .submit-right .submit-summary strong { display: block; font-size: 36px; font-weight: 700; color: var(--hf-yellow); letter-spacing: -0.02em; margin-bottom: 2px; font-variant-numeric: tabular-nums; } /* "Recent submissions" label above the queue table — small, muted, * centered uppercase eyebrow so it reads as a discreet section * marker rather than a heading competing with the Submit CTA above. */ .submit-queue-label { font-size: var(--fs-sm, 13px); font-weight: var(--fw-semibold); text-transform: uppercase; letter-spacing: 0.07em; color: var(--fg-3); text-align: center; margin: var(--space-2) 0 0; } /* Pull the dataframe up snug under the label — the gradio dataframe * ships with a toolbar row (copy / fullscreen icons) that already * adds its own top breathing room, so the label's bottom margin + * the column gap stack to a visible gulf if we don't collapse them. */ .submit-right .submit-queue { margin-top: calc(-1 * var(--space-2)) !important; } /* Yellow "Submit sweep" CTA — full-width, HF brand yellow with dark * text, matching the reference Space. Overrides Gradio's default * primary-button gradient. */ .submit-cta { width: 100% !important; background: var(--hf-yellow) !important; border-color: var(--hf-yellow) !important; color: var(--hf-gray-900) !important; font-weight: var(--fw-semibold) !important; margin: 0 0 var(--space-4) !important; } .submit-cta:hover { background: var(--hf-yellow-deep) !important; border-color: var(--hf-yellow-deep) !important; } /* --- Gradio component tweaks to tighten the HF look --- */ /* Slightly softer tabs bar — default Gradio tabs ship a heavy underline. */ .tab-nav button, .tabs > .tab-nav button, button[role="tab"] { font-size: 16px !important; } .tab-nav button.selected { border-bottom-color: var(--hf-yellow) !important; color: var(--hf-blue-deep) !important; font-weight: var(--fw-semibold); } /* Give plot cards the same card radius as the param cards. */ .gradio-container .plot-container { border-radius: var(--radius-lg); } /* The whole layout — hero and every tab — shares one wide column that tracks * the window. Using `100%` (not the Gradio default `1440px` cap) means the * hero always occupies most of the window. */ .gradio-container { max-width: 100% !important; width: 100% !important; margin: 0 auto !important; padding: var(--space-6) var(--space-8) !important; box-sizing: border-box; } @media (max-width: 820px) { .hero { padding: var(--space-6); } .hero .hero-mascot, .hero .hero-mascot img { max-width: 140px; } .hero .hero-stats { gap: var(--space-4); } } /* Footer row hosting the "Refresh from Hub" button. Sits flush against * the bottom of the page, right-aligned so the action reads as ambient * tooling rather than a primary CTA, with a soft top border separating * it from the last tab's content. */ .refresh-footer { margin-top: var(--space-6); padding-top: var(--space-4); border-top: 1px solid var(--border-1); align-items: center; justify-content: flex-end; gap: var(--space-4); } .refresh-footer .footer-version { flex: 0 0 auto; color: var(--fg-3); font-size: 13px; } .refresh-footer .refresh-status { flex: 1 1 auto; color: var(--fg-3); font-size: 13px; } .refresh-footer button { flex: 0 0 auto; }