File size: 2,425 Bytes
f8d4986
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""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>'