custom_css = """ /* Info icon for column tooltips */ .info-icon { color: #b0b0b0; font-size: 15px; margin-left: 4px; vertical-align: middle; font-family: Arial, sans-serif; font-style: normal; font-weight: bold; user-select: none; } .info-icon:hover { color: #888; } /* Model Name link hover effect */ .pretty-leaderboard-table a:hover { text-decoration: underline; color: #1098F7; cursor: pointer; } /* INTRO FEATURE CARDS (for about page) */ .intro-feature-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 24px; margin: 18px 0 !important; } .intro-feature-box { background: linear-gradient(135deg, #f8fafc 60%, #e3e6f3 100%); border-radius: 18px; box-shadow: 0 4px 16px rgba(44,62,80,0.08); padding: 32px 28px; width: 380px; min-width: 260px; max-width: 420px; text-align: left; display: flex; flex-direction: column; align-items: flex-start; transition: box-shadow 0.2s; } .intro-feature-title { font-weight: 900; font-size: 1.45em; margin-bottom: 12px; color: #23244a; } .intro-feature-desc { font-size: 1.18em; color: #444; margin-bottom: 7px; } .intro-feature-icon { font-size: 2.3em; margin-bottom: 16px; color: #1098F7; } .intro-feature-box:hover { box-shadow: 0 0 24px #a5a1ff55, 0 4px 16px rgba(0,0,0,0.18); transform: translateY(-4px) scale(1.025); transition: box-shadow 0.2s, transform 0.2s; cursor: default; } @media (prefers-color-scheme: dark) { .intro-feature-box { background: linear-gradient(135deg, #23244a 0%, #2a1859 100%) !important; color: #f5f6f7 !important; } .intro-feature-title, .intro-feature-desc { color: #f5f6f7 !important; } } /* Dataset Sample Button (below feature cards) */ .intro-dataset-btn { display: inline-block; background: #1098F7; color: #fff !important; border: none; border-radius: 12px; font-weight: 700; font-size: 1.18em; padding: 16px 36px; margin: 32px auto 0 auto; text-align: center; text-decoration: none; box-shadow: 0 2px 8px #1098f733; transition: background 0.18s, color 0.18s, box-shadow 0.18s; cursor: pointer; outline: none; } .intro-dataset-btn:hover, .intro-dataset-btn:focus { background: #0a6dc2; color: #fff !important; box-shadow: 0 4px 16px #1098f755; text-decoration: none; } @media (prefers-color-scheme: dark) { .intro-dataset-btn { background: #1a4b7a; color: #fff !important; } .intro-dataset-btn:hover, .intro-dataset-btn:focus { background: #1098F7; color: #fff !important; } } .radar-chart, .plot-container { display: block; margin-left: auto; margin-right: auto; width: fit-content; max-width: 100%; } /* Ensure injected HTML/Markdown blocks are transparent and text is visible in all color schemes */ .gr-html, .gr-markdown, .gr-html * { background: transparent !important; color: inherit !important; } .gr-html div, .gr-html body, .gr-markdown div, .gr-markdown body { background: transparent !important; color: inherit !important; } @media (prefers-color-scheme: dark) { .gr-html, .gr-markdown, .gr-html *, .gr-markdown * { color: #f5f6f7 !important; } } @media (prefers-color-scheme: light) { .gr-html, .gr-markdown, .gr-html *, .gr-markdown * { color: #23244a !important; } } /* Custom radio styles for category selector */ .cat-btn-radio label { border-radius: 18px !important; border: 1.5px solid #d1d5db !important; background: #f8fafc !important; color: #222 !important; font-weight: 600 !important; cursor: pointer !important; padding: 8px 20px !important; box-shadow: 0 2px 8px #e5e7eb88 !important; margin: 0 !important; font-size: 1.08rem !important; transition: background 0.2s, color 0.2s, box-shadow 0.2s, border 0.2s !important; display: inline-block !important; } .cat-btn-radio input[type="radio"] { display: none !important; } .cat-btn-radio input[type="radio"]:checked + label, .cat-btn-radio label.selected { background: #1098F7 !important; color: #fff !important; border: 1.5px solid #1098F7 !important; box-shadow: 0 4px 16px #1098f755, 0 2px 8px #e5e7eb88 !important; } .cat-btn-radio label:hover { border: 1.5px solid #1098F7 !important; box-shadow: 0 4px 16px #1098f733, 0 2px 8px #e5e7eb88 !important; } /* Gradio tab content: Space-themed background */ .gr-tabitem { background: linear-gradient(135deg, #e3e6f3 60%, #f5f6fa 100%); background-image: radial-gradient(rgba(255,255,255,0.10) 1.2px, transparent 1.2px), radial-gradient(rgba(255,255,255,0.06) 1px, transparent 1px); background-size: 40px 40px, 80px 80px; background-position: 0 0, 20px 20px; } @media (prefers-color-scheme: dark) { .gr-tabitem { background: linear-gradient(135deg, #181c3a 0%, #2a1859 100%) !important; background-image: radial-gradient(rgba(255,255,255,0.10) 1.2px, transparent 1.2px), radial-gradient(rgba(255,255,255,0.06) 1px, transparent 1px); background-size: 40px 40px, 80px 80px; background-position: 0 0, 20px 20px; } } @media (prefers-color-scheme: light) { .gr-tabitem { background: linear-gradient(135deg, #e3e6f3 60%, #f5f6fa 100%) !important; background-image: radial-gradient(rgba(255,255,255,0.10) 1.2px, transparent 1.2px), radial-gradient(rgba(255,255,255,0.06) 1px, transparent 1px); background-size: 40px 40px, 80px 80px; background-position: 0 0, 20px 20px; } h3 a, h3 a:visited { color: #222 !important; } } /* Sort arrow/button styles */ .sort-arrow, .sort-btn { display: inline-flex; align-items: center; justify-content: center; background: #23244a; color: #ffd700 !important; /* Always yellow */ border: 1.5px solid #ffd700; /* Gold border */ border-radius: 6px; font-size: 15px; font-weight: 700; margin-left: 6px; margin-right: 2px; padding: 2px 8px 2px 6px; cursor: pointer; transition: background 0.2s, color 0.2s, border 0.2s; min-width: 28px; min-height: 28px; outline: none; } .sort-arrow.active, .sort-btn.active { color: #ffd700 !important; /* Gold */ border-color: #ffd700; background: #1a237e; } .sort-arrow:hover, .sort-btn:hover { background: #ffd700; color: #23244a !important; border-color: #ffd700; } .sort-arrow svg, .sort-btn svg { margin-left: 2px; margin-right: 0; width: 1em; height: 1em; vertical-align: middle; } /* Enhanced leaderboard table styles */ .pretty-leaderboard-table { width: 100%; border-collapse: separate; border-spacing: 0; background: rgba(30, 34, 54, 0.98); /* border-radius: 16px; 테이블 자체에는 radius 제거 */ box-shadow: 0 4px 24px 0 rgba(16, 152, 247, 0.10), 0 1.5px 6px 0 rgba(227, 84, 84, 0.08); margin-bottom: 24px; } .pretty-leaderboard-table thead { border-radius: 16px 16px 0 0; overflow: hidden; background: #23244a; } /* Sticky first and second columns */ /* Sticky first and second columns - header(th) */ .pretty-leaderboard-table th:nth-child(1) { position: sticky; left: 0; top: 0; z-index: 5; background: #23244a; min-width: 60px; max-width: 60px; width: 60px; } .pretty-leaderboard-table th:nth-child(2) { position: sticky; left: 60px; top: 0; z-index: 5; background: #23244a; min-width: 220px; max-width: 400px; width: 220px; } /* Sticky first and second columns - body(td) with CSS variable for background */ .pretty-leaderboard-table td:nth-child(1) { position: sticky; left: 0; z-index: 4; background: var(--row-bg) !important; min-width: 60px; max-width: 60px; width: 60px; } .pretty-leaderboard-table td:nth-child(2) { position: sticky; left: 60px; z-index: 4; background: var(--row-bg) !important; min-width: 220px; max-width: 400px; width: 220px; } /* Set --row-bg variable for each row type */ .pretty-leaderboard-table tr { --row-bg: #1e2236; } .pretty-leaderboard-table tr:nth-child(even) { --row-bg: #23253a; } .pretty-leaderboard-table tr:hover { --row-bg: #2066a0; } .pretty-leaderboard-table th { z-index: 4; } .pretty-leaderboard-table th, .pretty-leaderboard-table td { padding: 12px 16px; text-align: left; border-bottom: 1px solid #23244a; font-size: 16px; } .pretty-leaderboard-table th { background: #23244a; color: #fff; font-weight: 800; letter-spacing: 0.5px; border-bottom: 2px solid #1098F7; text-shadow: 0 1px 8px #0006; transition: background 0.2s, color 0.2s; position: sticky; top: 0; z-index: 2; border-radius: 0 !important; } .pretty-leaderboard-table th:hover, .pretty-leaderboard-table th:focus { background: #273a8a; color: #fff; } .pretty-leaderboard-table td { color: #F5F6F7; vertical-align: middle; background: var(--row-bg); } .pretty-leaderboard-table tr:last-child td { border-bottom: none; } /* th/td의 border-radius는 모두 제거, 둥근 효과는 thead에만 */ /* Enhanced score bar styles */ .score-bar { display: flex; align-items: center; gap: 12px; width: 100%; } .score-bar-track { flex-grow: 1; height: 10px; background: rgba(245, 246, 247, 0.12); border-radius: 5px; overflow: hidden; max-width: 220px; box-shadow: 0 1px 4px 0 rgba(16, 152, 247, 0.10); } .score-bar-fill { height: 100%; background: linear-gradient(90deg, #a259f7 0%, #6d28d9 100%); border-radius: 5px; transition: width 0.3s cubic-bezier(0.4,0,0.2,1); } .score-bar-value { font-family: 'SF Mono', monospace; font-weight: 600; color: #F5F6F7; min-width: 60px; font-size: 14px; } body { min-height: 100vh; } /* 전체 배경색은 브라우저 기본값을 따름. gradio-container도 마찬가지로 별도 배경 없음 */ .markdown-text { font-size: 16px !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-container { margin-top: 15px; /* Space-themed background */ background: linear-gradient(135deg, #e3e6f3 60%, #f5f6fa 100%); position: relative; background-image: radial-gradient(rgba(255,255,255,0.15) 1.2px, transparent 1.2px), radial-gradient(rgba(255,255,255,0.10) 1px, transparent 1px); background-size: 40px 40px, 80px 80px; background-position: 0 0, 20px 20px; } @media (prefers-color-scheme: dark) { .leaderboard-table-container { background: linear-gradient(135deg, #1a237e 0%, #311b92 100%) !important; background-image: radial-gradient(rgba(255,255,255,0.15) 1.2px, transparent 1.2px), radial-gradient(rgba(255,255,255,0.10) 1px, transparent 1px); background-size: 40px 40px, 80px 80px; background-position: 0 0, 20px 20px; } } @media (prefers-color-scheme: light) { .leaderboard-table-container { background: linear-gradient(135deg, #e3e6f3 60%, #f5f6fa 100%) !important; background-image: radial-gradient(rgba(255,255,255,0.15) 1.2px, transparent 1.2px), radial-gradient(rgba(255,255,255,0.10) 1px, transparent 1px); background-size: 40px 40px, 80px 80px; background-position: 0 0, 20px 20px; } } /* Limit the width of the first column so that names don't expand too much */ .leaderboard-table-container td:nth-child(2), .leaderboard-table-container th:nth-child(2) { max-width: 400px; overflow: auto; white-space: nowrap; } .tab-buttons button { font-size: 20px; } /* Model type and think badge styles */ .badge { display: inline-block; border-radius: 12px; padding: 2px 10px; font-size: 0.85em; font-weight: 700; margin-left: 6px; box-shadow: 0 1px 4px rgba(0,0,0,0.10); vertical-align: middle; } .badge-think-on { background: #A7C7E7; color: #234567; border: 1.5px solid #A7C7E7; } .badge-think-off { background: #E0E0E0; color: #555; border: 1.5px solid #E0E0E0; } /* Model Type badge styles */ .badge-modeltype-instruct { background: #B2F2E9; color: #22796A; border: 1.5px solid #B2F2E9; } .badge-modeltype-think { background: #D6C8F7; color: #5B4B8A; border: 1.5px solid #D6C8F7; } .badge-modeltype-hybrid { background: #FFE0B2; color: #A67C52; border: 1.5px solid #FFE0B2; } /* Type badge Open/Proprietary styles */ .badge-type-open { background: #A8E6A3; color: #225522; border: 1.5px solid #A8E6A3; } .badge-type-proprietary { background: #F7B2B7; color: #7A2F34; border: 1.5px solid #F7B2B7; } /* Sort button styles */ .sort-btn { background: #23244a; color: #F5F6F7; border: 1px solid #1098F7; border-radius: 6px; font-size: 13px; font-weight: 700; margin-left: 4px; margin-right: 2px; padding: 2px 7px; cursor: pointer; transition: background 0.2s, color 0.2s; } .sort-btn:hover { background: #1098F7; color: #fff; } /* Custom CheckboxGroup and Dropdown styles for table theme */ .gr-checkbox-group, .gr-checkbox, .gr-checkbox-group label, .gr-checkbox input[type="checkbox"] { background: #23244a !important; color: #F5F6F7 !important; border: 1.5px solid #1098F7 !important; border-radius: 6px !important; } .gr-checkbox input[type="checkbox"]:checked { background: #1a237e !important; border-color: #ffd700 !important; } .gr-dropdown, .gr-input, select { background: #23244a !important; color: #F5F6F7 !important; border: 1.5px solid #1098F7 !important; border-radius: 6px !important; } /* Custom style for radar chart model selector's selected tags (only the tag area, not the dropdown list) */ .custom-dropdown .multiselect__tag { background: #1098F7 !important; color: #fff !important; border: 1.5px solid #1098F7 !important; box-shadow: 0 4px 16px #1098f755, 0 2px 8px #e5e7eb88 !important; border-radius: 18px !important; font-weight: 600 !important; padding: 8px 20px !important; margin: 2px 4px !important; font-size: 1.08rem !important; display: inline-block !important; transition: background 0.2s, color 0.2s, box-shadow 0.2s, border 0.2s !important; } .gr-dropdown:focus, .gr-input:focus, select:focus { border-color: #ffd700 !important; outline: none !important; } @media (prefers-color-scheme: dark) { .category-box, .space-info-box, .pretty-leaderboard-table, .dark-container { background: linear-gradient(135deg, #23244a 0%, #2a1859 100%) !important; color: #f5f6f7 !important; } .space-info-box, .space-info-box * { color: #f5f6f7 !important; } h3 a, h3 a:visited { color: #f5f6f7 !important; } } """ # requirements_textbox and adaptor_class_textbox scroll/height control custom_css += """ #requirements-textbox textarea { overflow-y: auto !important; resize: vertical; height: 480px; max-height: 480px; } #yml-textbox textarea { overflow-y: auto !important; resize: vertical; height: 240px; max-height: 240px; } /* No border textbox style for file upload status */ .no-border-textbox textarea { border: none !important; box-shadow: none !important; background: transparent !important; padding: 0 !important; margin: 0 !important; outline: none !important; resize: none !important; overflow: hidden !important; } .no-border-textbox .wrap { background: transparent !important; border: none !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; outline: none !important; } .no-border-textbox .prose { background: transparent !important; border: none !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; } .no-border-textbox label { display: none !important; } .no-border-textbox .gr-textbox { border: none !important; box-shadow: none !important; background: transparent !important; padding: 0 !important; margin: 0 !important; } .no-border-textbox .gr-textbox > div { border: none !important; box-shadow: none !important; background: transparent !important; padding: 0 !important; margin: 0 !important; } .no-border-textbox .gr-textbox > div > div { border: none !important; box-shadow: none !important; background: transparent !important; padding: 0 !important; margin: 0 !important; } /* Ensure model name tooltips are hoverable */ .pretty-leaderboard-table td span[title] { pointer-events: auto; } /* Tall file upload container to match lines=25 textbox height */ .tall-file-upload .file-upload-container { min-height: 283px !important; height: 283px !important; } .tall-file-upload .gr-file { min-height: 283px !important; height: 283px !important; } """ def get_rank_badge(rank: int) -> str: """ Returns emoji for 1st, 2nd, 3rd, otherwise just the number. """ if rank == 1: return '🥇' elif rank == 2: return '🥈' elif rank == 3: return '🥉' else: return f'{rank}' def get_score_gauge(score: float) -> str: """ Returns HTML for an overall score gauge (progress bar style). Robustly normalizes score to 0~100% regardless of input range (0~1 or 0~100). """ # Handle None/NaN try: score = float(score) except (TypeError, ValueError): score = 0.0 # Normalize: if score is 0~1, treat as normalized and scale to 0~100 if score is None or score != score: # NaN check percent = 0.0 display_score = 0.0 elif score <= 1.0: percent = score * 100 display_score = percent else: percent = score display_score = score # For scores above 95, adjust to 98~100% so the bar appears almost full if percent >= 95: percent = 98 + (min(percent, 100) - 95) * 0.4 # 95=98%, 100=100% # Clip to 0~100 percent = min(max(percent, 0), 100) display_score = min(max(display_score, 0), 100) return f'''
''' from src.display.formatting import get_score_stars def get_leaderboard_table_html(df, key="Category") -> str: """ Returns HTML for a pretty leaderboard table using badge and gauge. Displays all columns in df, applying format_leaderboard_cell to each cell as needed. key: "Category" or "Language" (default: "Category") """ import pandas as pd from src.display.formatting import get_score_stars, get_type_badge, get_model_type_badge, get_output_badge, format_leaderboard_cell, get_display_model_name # Build table header html = ['{col} | ") html.append("||||||
---|---|---|---|---|---|---|
{badge} | ") elif col == "Model Name": # Highlight top 1~3 rank = row.get("Rank", None) highlight_style = "" if rank == 1 or rank == "1": highlight_style = "color: #ffd700; font-weight: bold; text-shadow: 0 0 4px #fff2;" elif rank == 2 or rank == "2": highlight_style = "color: #b0b0b0; font-weight: bold;" elif rank == 3 or rank == "3": highlight_style = "color: #cd7f32; font-weight: bold;" else: highlight_style = "color: #fff; font-weight: 600;" display_name = get_display_model_name(str(cell)) link_value = row["Link"] if "Link" in row and pd.notna(row["Link"]) and str(row["Link"]).strip() != "" else None if link_value: clickable_name = f'{display_name}' else: clickable_name = display_name html.append(f'{clickable_name} | ') elif col == "Model Type": html.append(f"{get_model_type_badge(row.get('Model Type', ''))} | ") elif col == "Type": html.append(f"{get_type_badge(row.get('Type', ''))} | ") elif col == "Think": html.append(f"{get_output_badge(row.get('Think', ''))} | ") elif col == "Overall": # 별점 try: unique_id = row.get("Model Name", None) unique_id = unique_id.replace(" ", "_").replace("-", "_").replace("(", "_").replace(")", "_") cell_html = get_score_stars(float(cell), unique_id=unique_id) except Exception: cell_html = str(cell) html.append(f"{cell_html} | ") else: html.append(f"{format_leaderboard_cell(cell, col, key)} | ") html.append("