Spaces:
Running on Zero
Running on Zero
| """Camada de aparência compartilhada — tema + CSS. | |
| Polimento do Gradio é critério de julgamento DIRETO nas duas tracks, e UI custom | |
| além do default é caminho pro badge Off-Brand. Todos os apps herdam daqui pra ter | |
| um look consistente e caprichado desde a primeira fatia, não no fim. | |
| from shared import ui | |
| with gr.Blocks(theme=ui.theme(), css=ui.CSS, title="…") as demo: | |
| ... | |
| """ | |
| def theme(): | |
| """Tema base do monorepo. `gr.themes` com paleta noturna suave.""" | |
| import gradio as gr | |
| return gr.themes.Soft( | |
| primary_hue=gr.themes.colors.indigo, | |
| secondary_hue=gr.themes.colors.purple, | |
| neutral_hue=gr.themes.colors.slate, | |
| font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"], | |
| ).set( | |
| body_background_fill="linear-gradient(160deg, #0f1020 0%, #1a1530 100%)", | |
| body_background_fill_dark="linear-gradient(160deg, #0f1020 0%, #1a1530 100%)", | |
| block_background_fill="rgba(255,255,255,0.04)", | |
| block_border_width="1px", | |
| block_border_color="rgba(255,255,255,0.08)", | |
| block_radius="16px", | |
| button_primary_background_fill="linear-gradient(90deg, #6d5dfc 0%, #b16cea 100%)", | |
| button_primary_text_color="#ffffff", | |
| ) | |
| # CSS compartilhado: cartões, chips de símbolo, cabeçalho, estados de loading. | |
| CSS = """ | |
| :root { --dream-fg: #ede9ff; } | |
| .gradio-container { color: var(--dream-fg); } | |
| #app-header { text-align: center; padding: 8px 0 2px; } | |
| #app-header h1 { | |
| font-size: 2rem; margin: 0; | |
| background: linear-gradient(90deg, #8e7bff, #d39bff); | |
| -webkit-background-clip: text; -webkit-text-fill-color: transparent; | |
| } | |
| #app-header p { opacity: .8; margin: 4px 0 0; } | |
| .symbol-chips { display: flex; flex-wrap: wrap; gap: 6px; } | |
| .symbol-chip { | |
| padding: 4px 12px; border-radius: 999px; font-size: .85rem; | |
| background: rgba(141,123,255,.18); border: 1px solid rgba(141,123,255,.4); | |
| } | |
| .dream-status { font-style: italic; opacity: .85; } | |
| """ | |
| def header(title: str, tagline: str) -> str: | |
| """HTML do cabeçalho padronizado (usar em gr.HTML).""" | |
| return f'<div id="app-header"><h1>{title}</h1><p>{tagline}</p></div>' | |
| def chips(labels) -> str: | |
| """Renderiza rótulos como chips (símbolos do sonho).""" | |
| if not labels: | |
| return "" | |
| items = "".join(f'<span class="symbol-chip">{l}</span>' for l in labels) | |
| return f'<div class="symbol-chips">{items}</div>' | |