ttm-webapp-hf / theme.py
daniel-wojahn's picture
Upload 19 files
b4c92f5 verified
import gradio as gr
from gradio.themes.utils import colors, sizes, fonts
class TibetanAppTheme(gr.themes.Soft):
def __init__(self):
super().__init__(
primary_hue=colors.blue, # Primary interactive elements (e.g., #2563eb)
secondary_hue=colors.orange, # For accents if needed, or default buttons
neutral_hue=colors.slate, # For backgrounds, borders, and text
font=[
fonts.GoogleFont("Inter"),
"ui-sans-serif",
"system-ui",
"sans-serif",
],
radius_size=sizes.radius_md, # General radius, can be overridden (16px was for cards)
text_size=sizes.text_md, # Base font size (16px)
)
self.theme_vars_for_set = {
# Global & Body Styles
"body_background_fill": "#f0f2f5",
"body_text_color": "#333333",
# Card Styles (.gr-group)
"block_background_fill": "#ffffff",
"block_radius": "16px", # May need to be removed if not a valid settable CSS var
"block_shadow": "0 4px 12px rgba(0, 0, 0, 0.08)",
"block_padding": "24px",
"block_border_width": "0px",
# Markdown Styles
"body_text_color_subdued": "#4b5563",
# Button Styles
"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",
# Primary Button
"button_primary_background_fill": "#2563eb",
"button_primary_text_color": "#ffffff",
"button_primary_border_color": "transparent",
"button_primary_background_fill_hover": "#1d4ed8",
# HR style
"border_color_accent_subdued": "#e5e7eb",
}
super().set(**self.theme_vars_for_set)
# Store CSS overrides; these will be converted to a string and applied via gr.Blocks(css=...)
self.css_overrides = {
".gradio-container, .gr-block, .gr-markdown, label, input, .gr-slider, .gr-radio, .gr-button": {
"font-family": ", ".join(self.font),
"font-size": "16px !important",
"line-height": "1.6 !important",
"color": "#333333 !important",
},
".gr-group": {"margin-bottom": "24px !important"}, # min-height removed
".gr-markdown": {
"background": "transparent !important",
"font-size": "1em !important",
"margin-bottom": "16px !important",
},
".gr-markdown h1": {
"font-size": "28px !important",
"font-weight": "600 !important",
"margin-bottom": "8px !important",
"color": "#111827 !important",
},
".gr-markdown h2": {
"font-size": "26px !important",
"font-weight": "600 !important",
"color": "var(--primary-600, #2563eb) !important",
"margin-top": "32px !important",
"margin-bottom": "16px !important",
},
".gr-markdown h3": {
"font-size": "22px !important",
"font-weight": "600 !important",
"color": "#1f2937 !important",
"margin-top": "24px !important",
"margin-bottom": "12px !important",
},
".gr-markdown p, .gr-markdown span": {
"font-size": "16px !important",
"color": "#4b5563 !important",
},
".gr-button button": {
"border-radius": "8px !important",
"padding": "10px 20px !important",
"font-weight": "500 !important",
"box-shadow": "0 1px 2px 0 rgba(0, 0, 0, 0.05) !important",
"border": "1px solid #d1d5db !important",
"background-color": "#ffffff !important",
"color": "#374151 !important",
},
"#run-btn": {
"background": "var(--button-primary-background-fill) !important",
"color": "var(--button-primary-text-color) !important",
"font-weight": "bold !important",
"font-size": "24px !important",
"border": "none !important",
"box-shadow": "var(--button-primary-shadow) !important",
},
"#run-btn:hover": { # Changed selector
"background": "var(--button-primary-background-fill-hover) !important",
"box-shadow": "0px 4px 12px rgba(0, 0, 0, 0.15) !important",
"transform": "translateY(-1px) !important",
},
".gr-button button:hover": {
"background-color": "#f9fafb !important",
"border-color": "#adb5bd !important",
},
"hr": {
"margin": "32px 0 !important",
"border": "none !important",
"border-top": "1px solid var(--border-color-accent-subdued) !important",
},
".gr-slider, .gr-radio, .gr-file": {"margin-bottom": "20px !important"},
".gr-radio .gr-form button": {
"background-color": "#f3f4f6 !important",
"color": "#374151 !important",
"border": "1px solid #d1d5db !important",
"border-radius": "6px !important",
"padding": "8px 16px !important",
"font-weight": "500 !important",
},
".gr-radio .gr-form button:hover": {
"background-color": "#e5e7eb !important",
"border-color": "#9ca3af !important",
},
".gr-radio .gr-form button.selected": {
"background-color": "var(--primary-500, #3b82f6) !important",
"color": "#ffffff !important",
"border-color": "var(--primary-500, #3b82f6) !important",
},
".gr-radio .gr-form button.selected:hover": {
"background-color": "var(--primary-600, #2563eb) !important",
"border-color": "var(--primary-600, #2563eb) !important",
},
"#semantic-radio-group span": { # General selector, refined size
"font-size": "17px !important",
"font-weight": "500 !important",
},
"#semantic-radio-group div": { # General selector, refined size
"font-size": "14px !important"
},
# Row and Column flex styles for equal height
"#steps-row": {
"display": "flex !important",
"align-items": "stretch !important",
},
".step-column": {
"display": "flex !important",
"flex-direction": "column !important",
},
".step-column > .gr-group": {
"flex-grow": "1 !important",
"display": "flex !important",
"flex-direction": "column !important",
},
".tabs > .tab-nav": {"border-bottom": "1px solid #d1d5db !important"},
".tabs > .tab-nav > button.selected": {
"border-bottom": "2px solid var(--primary-500) !important",
"color": "var(--primary-500) !important",
"background-color": "transparent !important",
},
".tabs > .tab-nav > button": {
"color": "#6b7280 !important",
"background-color": "transparent !important",
"padding": "10px 15px !important",
"border-bottom": "2px solid transparent !important",
},
# Custom styling for metric accordions
".metric-info-accordion": {
"border-left": "4px solid #3B82F6 !important",
"margin-bottom": "1rem !important",
"background-color": "#F8FAFC !important",
"border-radius": "6px !important",
"overflow": "hidden !important",
},
".jaccard-info": {
"border-left-color": "#3B82F6 !important", # Blue
},
".lcs-info": {
"border-left-color": "#10B981 !important", # Green
},
".semantic-info": {
"border-left-color": "#8B5CF6 !important", # Purple
},
".tfidf-info": {
"border-left-color": "#F59E0B !important", # Amber
},
".wordcount-info": {
"border-left-color": "#EC4899 !important", # Pink
},
# Accordion header styling
".metric-info-accordion > .label-wrap": {
"font-weight": "600 !important",
"padding": "12px 16px !important",
"background-color": "#F1F5F9 !important",
"border-bottom": "1px solid #E2E8F0 !important",
},
# Accordion content styling
".metric-info-accordion > .wrap": {
"padding": "16px !important",
},
# Word count plot styling - full width
".tabs > .tab-content > div[data-testid='tabitem'] > .plot": {
"width": "100% !important",
},
# LLM Analysis styling
".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": "24px !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": "20px !important",
"margin-bottom": "12px !important",
},
".llm-analysis p": {
"line-height": "1.7 !important",
"margin-bottom": "12px !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",
},
}
def get_css_string(self) -> str:
"""Converts the self.css_overrides dictionary into a CSS string."""
css_parts = []
for selector, properties in self.css_overrides.items():
props_str = "\n".join(
[f" {prop}: {value};" for prop, value in properties.items()]
)
css_parts.append(f"{selector} {{\n{props_str}\n}}")
return "\n\n".join(css_parts)
# Instantiate the theme for easy import
tibetan_theme = TibetanAppTheme()