Spaces:
Sleeping
Sleeping
| """ | |
| Tibetan Text Metrics Theme - Gradio 6 Compatible | |
| This theme provides a clean, professional look for the TTM application. | |
| Updated for Gradio 6.x compatibility where theme/css are passed to launch(). | |
| """ | |
| import gradio as gr | |
| from gradio.themes.utils import colors, sizes, fonts | |
| class TibetanAppTheme(gr.themes.Soft): | |
| """ | |
| Custom theme for Tibetan Text Metrics application. | |
| Gradio 6 Migration Notes: | |
| - Theme is now passed to demo.launch(theme=...) instead of gr.Blocks(theme=...) | |
| - CSS is now passed to demo.launch(css=...) instead of gr.Blocks(css=...) | |
| - Use elem_id and elem_classes for stable CSS targeting | |
| """ | |
| def __init__(self): | |
| super().__init__( | |
| primary_hue=colors.blue, | |
| secondary_hue=colors.orange, | |
| neutral_hue=colors.slate, | |
| font=[ | |
| fonts.GoogleFont("Inter"), | |
| "ui-sans-serif", | |
| "system-ui", | |
| "sans-serif", | |
| ], | |
| radius_size=sizes.radius_md, | |
| text_size=sizes.text_md, | |
| ) | |
| # Theme variable overrides using Gradio's theming system | |
| self.theme_vars_for_set = { | |
| # Global & Body Styles | |
| "body_background_fill": "#f0f2f5", | |
| "body_text_color": "#333333", | |
| "body_text_color_subdued": "#4b5563", | |
| # Block/Card Styles | |
| "block_background_fill": "#ffffff", | |
| "block_radius": "16px", | |
| "block_shadow": "0 4px 12px rgba(0, 0, 0, 0.08)", | |
| "block_padding": "24px", | |
| "block_border_width": "0px", | |
| # Button Styles - Secondary | |
| "button_secondary_background_fill": "#ffffff", | |
| "button_secondary_text_color": "#374151", | |
| "button_secondary_border_color": "#d1d5db", | |
| "button_secondary_border_color_hover": "#adb5bd", | |
| "button_secondary_background_fill_hover": "#f9fafb", | |
| # Button Styles - Primary | |
| "button_primary_background_fill": "#2563eb", | |
| "button_primary_text_color": "#ffffff", | |
| "button_primary_border_color": "transparent", | |
| "button_primary_background_fill_hover": "#1d4ed8", | |
| # Border colors | |
| "border_color_accent_subdued": "#e5e7eb", | |
| "border_color_primary": "#d1d5db", | |
| # Input styles | |
| "input_background_fill": "#ffffff", | |
| "input_border_color": "#d1d5db", | |
| "input_border_color_focus": "#2563eb", | |
| } | |
| super().set(**self.theme_vars_for_set) | |
| def get_css_string(self) -> str: | |
| """ | |
| Returns custom CSS string for additional styling. | |
| Gradio 6 uses different class naming conventions. This CSS uses: | |
| - elem_id selectors (#id) for specific components | |
| - elem_classes selectors (.class) for groups of components | |
| - Gradio 6 native classes where stable | |
| """ | |
| return """ | |
| /* ============================================ | |
| GLOBAL STYLES | |
| ============================================ */ | |
| .gradio-container { | |
| font-family: 'Inter', ui-sans-serif, system-ui, sans-serif !important; | |
| max-width: 1600px !important; | |
| margin: 0 auto !important; | |
| font-size: 16px !important; | |
| } | |
| /* Base font size for all text */ | |
| body, .gradio-container * { | |
| font-size: 16px; | |
| } | |
| /* ============================================ | |
| TYPOGRAPHY | |
| ============================================ */ | |
| h1 { | |
| font-size: 32px !important; | |
| font-weight: 600 !important; | |
| color: #111827 !important; | |
| margin-bottom: 12px !important; | |
| } | |
| h2 { | |
| font-size: 26px !important; | |
| font-weight: 600 !important; | |
| color: var(--primary-600, #2563eb) !important; | |
| margin-top: 24px !important; | |
| margin-bottom: 16px !important; | |
| } | |
| h3 { | |
| font-size: 22px !important; | |
| font-weight: 600 !important; | |
| color: #1f2937 !important; | |
| margin-top: 20px !important; | |
| margin-bottom: 12px !important; | |
| } | |
| /* Labels and form text */ | |
| label, .label-wrap, span.svelte-1gfkn6j { | |
| font-size: 16px !important; | |
| } | |
| /* Info text under inputs */ | |
| .info { | |
| font-size: 14px !important; | |
| } | |
| /* ============================================ | |
| LAYOUT - Steps Row | |
| ============================================ */ | |
| #steps-row { | |
| display: flex !important; | |
| align-items: stretch !important; | |
| gap: 24px !important; | |
| } | |
| .step-column { | |
| display: flex !important; | |
| flex-direction: column !important; | |
| flex: 1 !important; | |
| } | |
| .step-box { | |
| padding: 1.5rem !important; | |
| flex-grow: 1 !important; | |
| display: flex !important; | |
| flex-direction: column !important; | |
| } | |
| /* ============================================ | |
| BUTTONS | |
| ============================================ */ | |
| /* Primary action buttons */ | |
| #run-btn-quick, #run-btn-custom { | |
| background: var(--button-primary-background-fill, #2563eb) !important; | |
| color: var(--button-primary-text-color, #ffffff) !important; | |
| font-weight: 600 !important; | |
| font-size: 18px !important; | |
| padding: 12px 24px !important; | |
| border: none !important; | |
| border-radius: 8px !important; | |
| box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2) !important; | |
| transition: all 0.2s ease !important; | |
| margin-top: 16px !important; | |
| } | |
| #run-btn-quick:hover, #run-btn-custom:hover { | |
| background: var(--button-primary-background-fill-hover, #1d4ed8) !important; | |
| box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3) !important; | |
| transform: translateY(-1px) !important; | |
| } | |
| /* Secondary buttons */ | |
| button.secondary { | |
| background-color: #ffffff !important; | |
| color: #374151 !important; | |
| border: 1px solid #d1d5db !important; | |
| border-radius: 8px !important; | |
| padding: 10px 20px !important; | |
| font-weight: 500 !important; | |
| } | |
| button.secondary:hover { | |
| background-color: #f9fafb !important; | |
| border-color: #adb5bd !important; | |
| } | |
| /* ============================================ | |
| TABS | |
| ============================================ */ | |
| .tabs { | |
| margin-top: 8px !important; | |
| } | |
| .tab-nav { | |
| border-bottom: 1px solid #e5e7eb !important; | |
| margin-bottom: 16px !important; | |
| } | |
| .tab-nav button { | |
| color: #6b7280 !important; | |
| background-color: transparent !important; | |
| padding: 12px 20px !important; | |
| border: none !important; | |
| border-bottom: 2px solid transparent !important; | |
| font-weight: 500 !important; | |
| transition: all 0.2s ease !important; | |
| } | |
| .tab-nav button:hover { | |
| color: #374151 !important; | |
| } | |
| .tab-nav button.selected { | |
| border-bottom: 2px solid var(--primary-500, #3b82f6) !important; | |
| color: var(--primary-600, #2563eb) !important; | |
| background-color: transparent !important; | |
| } | |
| /* ============================================ | |
| ACCORDIONS | |
| ============================================ */ | |
| .accordion { | |
| border: 1px solid #e5e7eb !important; | |
| border-radius: 8px !important; | |
| margin-bottom: 12px !important; | |
| overflow: hidden !important; | |
| } | |
| /* Metric info accordions with colored borders */ | |
| .metric-info-accordion { | |
| border-left: 4px solid #3B82F6 !important; | |
| margin-bottom: 1rem !important; | |
| background-color: #F8FAFC !important; | |
| border-radius: 6px !important; | |
| } | |
| .jaccard-info { border-left-color: #3B82F6 !important; } | |
| .lcs-info { border-left-color: #10B981 !important; } | |
| .fuzzy-info { border-left-color: #F59E0B !important; } | |
| .semantic-info { border-left-color: #8B5CF6 !important; } | |
| .wordcount-info { border-left-color: #EC4899 !important; } | |
| /* ============================================ | |
| FORM ELEMENTS | |
| ============================================ */ | |
| /* Radio buttons */ | |
| .radio-group label { | |
| display: flex !important; | |
| align-items: center !important; | |
| padding: 10px 16px !important; | |
| border: 1px solid #e5e7eb !important; | |
| border-radius: 8px !important; | |
| margin-bottom: 8px !important; | |
| cursor: pointer !important; | |
| transition: all 0.2s ease !important; | |
| } | |
| .radio-group label:hover { | |
| background-color: #f9fafb !important; | |
| border-color: #d1d5db !important; | |
| } | |
| .radio-group input:checked + label, | |
| .radio-group label.selected { | |
| background-color: var(--primary-50, #eff6ff) !important; | |
| border-color: var(--primary-500, #3b82f6) !important; | |
| } | |
| /* Dropdowns */ | |
| select, .dropdown { | |
| border: 1px solid #d1d5db !important; | |
| border-radius: 8px !important; | |
| padding: 10px 12px !important; | |
| background-color: #ffffff !important; | |
| } | |
| /* Checkboxes */ | |
| input[type="checkbox"] { | |
| width: 18px !important; | |
| height: 18px !important; | |
| accent-color: var(--primary-500, #3b82f6) !important; | |
| } | |
| /* ============================================ | |
| PRESET TABLE | |
| ============================================ */ | |
| .preset-table table { | |
| font-size: 15px !important; | |
| margin-top: 16px !important; | |
| width: 100% !important; | |
| border-collapse: collapse !important; | |
| } | |
| .preset-table th, .preset-table td { | |
| padding: 12px 16px !important; | |
| text-align: center !important; | |
| border-bottom: 1px solid #e5e7eb !important; | |
| } | |
| .preset-table th { | |
| background-color: #f9fafb !important; | |
| font-weight: 600 !important; | |
| color: #374151 !important; | |
| font-size: 15px !important; | |
| } | |
| .preset-table tr:hover { | |
| background-color: #f9fafb !important; | |
| } | |
| /* Radio button options - larger text */ | |
| .gr-radio label, .gr-radio span { | |
| font-size: 16px !important; | |
| } | |
| /* Dropdown options */ | |
| .gr-dropdown, select { | |
| font-size: 16px !important; | |
| } | |
| /* ============================================ | |
| RESULTS SECTION | |
| ============================================ */ | |
| /* Heatmaps and plots - full width */ | |
| .plot-container, .plotly, .js-plotly-plot { | |
| width: 100% !important; | |
| max-width: 100% !important; | |
| } | |
| /* Remove extra padding/margin from plot containers */ | |
| .gr-plot, [data-testid="plot"] { | |
| width: 100% !important; | |
| padding: 0 !important; | |
| } | |
| /* Tab content should use full width */ | |
| .tabitem, [data-testid="tabitem"] { | |
| width: 100% !important; | |
| padding: 16px 0 !important; | |
| } | |
| /* Remove dead space after plots */ | |
| .tabs .tabitem > div { | |
| margin-bottom: 0 !important; | |
| } | |
| .metric-heatmap { | |
| max-width: 100% !important; | |
| width: 100% !important; | |
| } | |
| /* ============================================ | |
| LLM ANALYSIS OUTPUT | |
| ============================================ */ | |
| #llm-analysis { | |
| background-color: #f8f9fa !important; | |
| border-left: 4px solid #3B82F6 !important; | |
| border-radius: 8px !important; | |
| padding: 20px 24px !important; | |
| margin: 16px 0 !important; | |
| box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05) !important; | |
| } | |
| #llm-analysis h2 { | |
| color: #1e40af !important; | |
| font-size: 22px !important; | |
| margin-bottom: 16px !important; | |
| border-bottom: 1px solid #e5e7eb !important; | |
| padding-bottom: 8px !important; | |
| } | |
| #llm-analysis h3, #llm-analysis h4 { | |
| color: #1e3a8a !important; | |
| margin-top: 18px !important; | |
| margin-bottom: 10px !important; | |
| } | |
| #llm-analysis p { | |
| line-height: 1.7 !important; | |
| margin-bottom: 12px !important; | |
| color: #374151 !important; | |
| } | |
| #llm-analysis ul, #llm-analysis ol { | |
| margin-left: 24px !important; | |
| margin-bottom: 16px !important; | |
| } | |
| #llm-analysis li { | |
| margin-bottom: 6px !important; | |
| } | |
| #llm-analysis strong, #llm-analysis b { | |
| color: #1f2937 !important; | |
| font-weight: 600 !important; | |
| } | |
| /* ============================================ | |
| RESPONSIVE ADJUSTMENTS | |
| ============================================ */ | |
| @media (max-width: 768px) { | |
| #steps-row { | |
| flex-direction: column !important; | |
| } | |
| .step-column { | |
| width: 100% !important; | |
| } | |
| #run-btn-quick, #run-btn-custom { | |
| font-size: 16px !important; | |
| padding: 10px 20px !important; | |
| } | |
| } | |
| /* ============================================ | |
| UTILITY CLASSES | |
| ============================================ */ | |
| .custom-header { | |
| margin-bottom: 12px !important; | |
| color: #374151 !important; | |
| } | |
| .info-text { | |
| font-size: 14px !important; | |
| color: #6b7280 !important; | |
| margin-top: 4px !important; | |
| } | |
| """ | |
| # Instantiate the theme for easy import | |
| tibetan_theme = TibetanAppTheme() | |