Skip to content

Instantly share code, notes, and snippets.

@brayevalerien
Created March 5, 2026 12:07
Show Gist options
  • Select an option

  • Save brayevalerien/f87c9c8f85299dc2cb6f1d7652fb65e8 to your computer and use it in GitHub Desktop.

Select an option

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.
"""
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