Spaces:
Running on Zero
Running on Zero
File size: 5,336 Bytes
1a2024f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | """THOX brand v2 Gradio theme -- the single source for every Space in this repo.
CANONICAL COPY. `ci/test_theme_parity.py` asserts every Space's copy is
byte-identical to this file. Edit here, then run `python build.py` (which
re-copies it) -- editing a Space's copy directly will fail CI.
WHY THIS FILE EXISTS
--------------------
Seven Spaces each carried their own inline theme. Two defects were present in
every one of them, measured on the live fleet:
1. The stylesheet forced `.gradio-container { background: #09090B !important }`
while Gradio still rendered its LIGHT palette. Loading `?__theme=light`
produced black body text on the forced near-black canvas:
#000000 on #09090B = 1.06:1
Invisible. Never pin one theme's colour; let the theme drive it.
2. Buttons and links were stock Gradio blue (`--color-accent` #3B82F6,
`--link-text-color` #2563EB), so nothing in the fleet's UI was actually THOX.
Fixing that in seven places would have drifted. It lives here instead.
CONTRAST -- from ttracx/thox-design-system (standards/brand-v2.md, ADR-0001)
---------------------------------------------------------------------------
The reflex pairing is wrong and must not be "fixed" back:
#FFFFFF on #05A451 = 3.26:1 FAILS WCAG AA
#000000 on #05A451 = 6.44:1 PASSES <- primary button, both themes
Light Dark
#03763B on #FFFFFF 5.74 #45e887 on #09090B 12.45 links
#52525B on #FFFFFF 7.73 #A1A1AA on #09090B 7.76 subdued text
#FFFFFF on #03763B 5.74 #000000 on #05A451 6.44 primary hover
Plain #05A451 is only 3.26:1 on white, so light-surface text uses brand.deep
(#03763B). Gradio's own `--body-text-color-subdued` default (#BBBBC2) is about
1.9:1 on white, so it is pinned in both modes here.
#10B981 / #34D399 are DEPRECATED v1 emeralds. Purple #A855F7 is MagStack-only
and neon #00FF88 is device-illumination-only -- neither belongs in UI chrome.
"""
from __future__ import annotations
import gradio as gr
THOX_GREEN = "#05A451" # brand.primary
THOX_ACCENT = "#45e887" # accent on dark
THOX_DEEP = "#03763B" # brand.deep -- accessible green on light surfaces
THOX_FOCUS = "#37C77A" # brand.light -- 9.11:1 on the dark canvas
THOX_HUE = gr.themes.Color(
c50="#E6F7EE", c100="#C2EBD6", c200="#8FDCB6", c300="#5CCB95",
c400=THOX_FOCUS, c500=THOX_GREEN, c600="#048A44", c700=THOX_DEEP,
c800="#026030", c900="#064E2E", c950="#04331E",
)
THOX_THEME = gr.themes.Base(
primary_hue=THOX_HUE,
neutral_hue=gr.themes.colors.zinc,
).set(
# Primary action: brand green with BLACK ink in both themes (6.44:1).
button_primary_background_fill=THOX_GREEN,
button_primary_background_fill_dark=THOX_GREEN,
button_primary_text_color="#000000",
button_primary_text_color_dark="#000000",
button_primary_background_fill_hover=THOX_DEEP,
button_primary_background_fill_hover_dark=THOX_ACCENT,
button_primary_text_color_hover="#FFFFFF", # on #03763B = 5.74:1
button_primary_text_color_hover_dark="#000000",
# Plain green is only 3.26:1 on white, so light links use brand.deep.
link_text_color=THOX_DEEP,
link_text_color_dark=THOX_ACCENT,
link_text_color_hover="#024F27",
link_text_color_hover_dark=THOX_GREEN,
# Gradio's default subdued grey fails AA on white; pin both modes.
body_text_color_subdued="#52525B", # 7.73:1 on white
body_text_color_subdued_dark="#A1A1AA", # 7.76:1 on #09090B
background_fill_primary_dark="#09090B",
background_fill_secondary_dark="#18181B",
border_color_primary_dark="#3F3F46",
)
# Shared chrome. Colour resolves through a Gradio variable or a per-theme
# override, so it follows the active theme instead of pinning one.
# `body.dark` is how Gradio 5 marks dark mode -- not html.dark, not data-theme.
THOX_CSS = f"""
:root {{
--thox-green: {THOX_GREEN}; --thox-accent: {THOX_ACCENT}; --thox-deep: {THOX_DEEP};
--thox-brand-ink: var(--thox-deep);
}}
.dark, body.dark {{ --thox-brand-ink: var(--thox-accent); }}
#thox-header {{
border-left: 3px solid var(--thox-green);
padding: 0.6rem 0 0.6rem 0.9rem; margin-bottom: 0.5rem;
}}
#thox-header h1 {{
color: var(--thox-brand-ink);
font-size: 1.15rem; margin: 0; letter-spacing: .02em;
}}
#thox-header p {{
color: var(--body-text-color-subdued);
font-size: .85rem; margin: .25rem 0 0;
}}
#thox-header code {{ color: var(--thox-brand-ink); }}
/* Amber is semantic, so it is pinned per theme rather than taken from a Gradio
variable -- the dark-mode #FBBF24 is only 1.7:1 on white. */
#thox-caveat {{
border-left: 3px solid #B45309; background: rgba(180,83,9,.07);
padding: .55rem .8rem; margin: .4rem 0 .6rem; border-radius: 4px;
color: #92400E; font-size: .82rem; line-height: 1.45;
}}
.dark #thox-caveat, body.dark #thox-caveat {{
border-left-color: #F59E0B; background: rgba(245,158,11,.08);
color: #FBBF24;
}}
:is(button, a, input, textarea, select):focus-visible {{
outline: 2px solid var(--thox-brand-ink); outline-offset: 2px;
}}
::selection {{ background: var(--thox-green); color: #000000; }}
@media (prefers-reduced-motion: reduce) {{
*, *::before, *::after {{
animation-duration: .01ms !important; transition-duration: .01ms !important;
}}
}}
"""
|