case-forge / shared /ui.py
nextmarte's picture
Case Forge app: authoring UI + ZeroGPU inference (qwen3-4b-v2)
f8d4986 verified
Raw
History Blame Contribute Delete
2.43 kB
"""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>'