Created
March 5, 2026 12:07
-
-
Save brayevalerien/f87c9c8f85299dc2cb6f1d7652fb65e8 to your computer and use it in GitHub Desktop.
A Monokai Pro (Classic Filter) theme for Gradio apps, easy to edit and use.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| Monokai Pro (Classic Filter) Gradio theme. | |
| Usage: | |
| from theme import theme, css | |
| with gr.Blocks() as demo: | |
| ... | |
| demo.launch(theme=theme, css=css) | |
| Exports: | |
| PALETTE raw color dict for programmatic access | |
| theme gr.themes.Base instance | |
| css CSS string for what the theme API cannot reach | |
| """ | |
| import gradio as gr | |
| # edit this if you to tweak the theme colors, don't change the rest. | |
| PALETTE = { | |
| "bg": "#272822", # default background | |
| "panel": "#1e1f1c", # darkest panels | |
| "highlight": "#3e3d32", # elevated surfaces, borders | |
| "input": "#414339", # input fields | |
| "fg": "#f8f8f2", # primary text | |
| "muted": "#75715e", # secondary, disabled text | |
| "primary": "#ae81ff", # magenta. focus, brand, accents | |
| "secondary": "#a6e22e", # green. success, selected text | |
| "cyan": "#66d9ef", # links, informational | |
| "red": "#f92672", # errors, destructive | |
| "orange": "#fd971f", # warnings | |
| "yellow": "#f4bf75", # labels (use sparingly) | |
| } | |
| P = PALETTE # shorthand for the definitions below | |
| def _mix(a: str, b: str, t: float) -> str: | |
| """Linearly interpolate two hex colors. t=0 returns a, t=1 returns b.""" | |
| ar, ag, ab = int(a[1:3], 16), int(a[3:5], 16), int(a[5:7], 16) | |
| br, bg_, bb = int(b[1:3], 16), int(b[3:5], 16), int(b[5:7], 16) | |
| return "#{:02x}{:02x}{:02x}".format( | |
| round(ar + (br - ar) * t), | |
| round(ag + (bg_ - ag) * t), | |
| round(ab + (bb - ab) * t), | |
| ) | |
| def _ramp(base: str, light: str = "#ffffff", dark: str = "#000000") -> gr.themes.Color: | |
| """Build a 12-stop Gradio color ramp centered on `base`.""" | |
| return gr.themes.Color( | |
| c50=_mix(base, light, 0.85), | |
| c100=_mix(base, light, 0.70), | |
| c200=_mix(base, light, 0.50), | |
| c300=_mix(base, light, 0.25), | |
| c400=base, | |
| c500=base, | |
| c600=_mix(base, dark, 0.15), | |
| c700=_mix(base, dark, 0.30), | |
| c800=_mix(base, dark, 0.50), | |
| c900=_mix(base, dark, 0.70), | |
| c950=_mix(base, dark, 0.85), | |
| ) | |
| def _set_kwargs() -> dict[str, str]: | |
| """Assemble all .set() kwargs from the palette. | |
| The helper s(prefix, val) sets both light and dark variants to the same | |
| value because this is a dark-only theme. | |
| """ | |
| kw: dict[str, str] = {} | |
| def s(prefix: str, val: str): | |
| kw[prefix] = val | |
| kw[prefix + "_dark"] = val | |
| # body | |
| s("body_background_fill", P["bg"]) | |
| s("body_text_color", P["fg"]) | |
| s("body_text_color_subdued", P["muted"]) | |
| # surfaces | |
| s("background_fill_primary", P["bg"]) | |
| s("background_fill_secondary", P["panel"]) | |
| # borders | |
| s("border_color_primary", P["highlight"]) | |
| s("border_color_accent", P["primary"]) | |
| # accent | |
| kw["color_accent"] = P["primary"] | |
| s("color_accent_soft", P["highlight"]) | |
| # blocks | |
| s("block_background_fill", P["panel"]) | |
| s("block_border_color", P["highlight"]) | |
| s("block_label_background_fill", P["panel"]) | |
| s("block_label_border_color", P["highlight"]) | |
| s("block_label_text_color", P["muted"]) | |
| s("block_title_text_color", P["muted"]) | |
| s("block_shadow", "none") | |
| # inputs | |
| s("input_background_fill", P["input"]) | |
| s("input_background_fill_focus", P["input"]) | |
| s("input_border_color", P["highlight"]) | |
| s("input_border_color_focus", P["primary"]) | |
| s("input_shadow", "none") | |
| s("input_shadow_focus", "none") | |
| s("input_placeholder_color", P["muted"]) | |
| # primary buttons | |
| s("button_primary_background_fill", P["primary"]) | |
| s("button_primary_background_fill_hover", P["highlight"]) | |
| s("button_primary_border_color", P["primary"]) | |
| s("button_primary_border_color_hover", P["highlight"]) | |
| s("button_primary_text_color", P["panel"]) | |
| s("button_primary_shadow", "none") | |
| # secondary buttons | |
| s("button_secondary_background_fill", P["highlight"]) | |
| s("button_secondary_background_fill_hover", P["input"]) | |
| s("button_secondary_border_color", P["highlight"]) | |
| s("button_secondary_text_color", P["fg"]) | |
| s("button_secondary_shadow", "none") | |
| # cancel buttons | |
| s("button_cancel_background_fill", P["panel"]) | |
| s("button_cancel_background_fill_hover", P["highlight"]) | |
| s("button_cancel_text_color", P["red"]) | |
| # checkboxes and radios | |
| s("checkbox_background_color", P["input"]) | |
| s("checkbox_background_color_selected", P["primary"]) | |
| s("checkbox_border_color", P["highlight"]) | |
| s("checkbox_border_color_focus", P["primary"]) | |
| s("checkbox_border_color_selected", P["primary"]) | |
| s("checkbox_label_background_fill", P["panel"]) | |
| s("checkbox_label_background_fill_hover", P["bg"]) | |
| s("checkbox_label_background_fill_selected", P["highlight"]) | |
| s("checkbox_label_border_color", P["highlight"]) | |
| s("checkbox_label_text_color", P["fg"]) | |
| s("checkbox_label_text_color_selected", P["secondary"]) | |
| # slider | |
| s("slider_color", P["primary"]) | |
| # tables | |
| s("table_border_color", P["highlight"]) | |
| s("table_even_background_fill", P["panel"]) | |
| s("table_odd_background_fill", P["bg"]) | |
| s("table_row_focus", P["highlight"]) | |
| s("table_text_color", P["fg"]) | |
| # misc | |
| kw["loader_color"] = P["primary"] | |
| kw["shadow_drop"] = "none" | |
| kw["shadow_drop_lg"] = "none" | |
| kw["shadow_inset"] = "none" | |
| kw["shadow_spread"] = "0px" | |
| s("accordion_text_color", P["muted"]) | |
| return kw | |
| theme = gr.themes.Base( | |
| primary_hue=_ramp(P["primary"]), | |
| secondary_hue=_ramp(P["secondary"]), | |
| neutral_hue=gr.themes.Color( | |
| c50=P["fg"], | |
| c100="#e8e8e0", | |
| c200=P["muted"], | |
| c300=P["muted"], | |
| c400=P["muted"], | |
| c500=P["muted"], | |
| c600=P["input"], | |
| c700=P["highlight"], | |
| c800=P["bg"], | |
| c900=P["panel"], | |
| c950=P["panel"], | |
| ), | |
| font=["JetBrains Mono", "monospace"], | |
| font_mono=["JetBrains Mono", "monospace"], | |
| radius_size=gr.themes.sizes.radius_none, | |
| ).set( | |
| body_text_size="13px", | |
| block_border_width="1px", | |
| input_border_width="1px", | |
| **_set_kwargs(), | |
| ) | |
| css = ( | |
| "@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono" | |
| ":wght@400;500;600;700&display=swap');\n" | |
| f".tab-nav button.selected {{ border-color: {P['primary']} !important; }}\n" | |
| f"::-webkit-scrollbar {{ width: 8px; height: 8px; }}\n" | |
| f"::-webkit-scrollbar-track {{ background: {P['panel']}; }}\n" | |
| f"::-webkit-scrollbar-thumb {{ background: {P['highlight']}; }}\n" | |
| f"::-webkit-scrollbar-thumb:hover {{ background: {P['muted']}; }}\n" | |
| f".prose a, .markdown a {{ color: {P['cyan']} !important; }}\n" | |
| f".prose code {{ color: {P['cyan']} !important; background: {P['input']} !important; }}\n" | |
| f"footer {{ border-top: 1px solid {P['highlight']} !important; }}\n" | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment