PocketAccountant / src /ui /theme.py
eldinosaur's picture
US-aware Capture/Ledger + wire in the reasoning LLM agent (Qwen3-8B via vLLM/Modal) with router fallback
d103096 verified
Raw
History Blame Contribute Delete
3.84 kB
"""Custom 'ledger book' look — pushes past the default Gradio skin (🎨 Off-Brand).
A warm accountant's-ledger aesthetic: cream paper, ledger-green ink, ruled lines,
monospaced numerals (numbers should look like numbers), and a serif display face.
"""
import gradio as gr
# Ledger palette
INK = "#1f3d2b" # dark ledger green
GREEN = "#2f7d4f" # accent green
GREEN_SOFT = "#e7f1e9"
PAPER = "#fbf7ef" # cream paper
PAPER2 = "#f4eee1"
LINE = "#d8cdb6" # ruled line
RED = "#b23a48" # debit red (for negatives)
GOLD = "#b8860b"
theme = gr.themes.Base(
primary_hue=gr.themes.colors.green,
secondary_hue=gr.themes.colors.emerald,
neutral_hue=gr.themes.colors.stone,
font=[gr.themes.GoogleFont("Source Serif 4"), "Georgia", "serif"],
font_mono=[gr.themes.GoogleFont("JetBrains Mono"), "Consolas", "monospace"],
).set(
body_background_fill="#f7f2e7",
block_background_fill="#fffdf8",
block_border_width="1px",
block_border_color="#d8cdb6",
block_radius="10px",
block_shadow="0 1px 0 #ece3cf, 0 4px 14px rgba(31,61,43,0.06)",
button_primary_background_fill="#2f7d4f",
button_primary_background_fill_hover="#27693f",
button_primary_text_color="#ffffff",
input_background_fill="#fffdf8",
input_border_color="#cdbf9f",
)
CSS = """
:root { --ink:#1f3d2b; --green:#2f7d4f; --line:#d8cdb6; --red:#b23a48; --gold:#b8860b; }
/* NOTE: do NOT set max-width on .gradio-container — in Gradio 6 it triggers an
infinite ResizeObserver "measuring" loop that hangs the whole app on the loading
spinner. Width is left at Gradio's default. */
/* Masthead */
#pa-masthead {
text-align: center; padding: 18px 12px 6px;
border-bottom: 2px solid var(--ink);
background:
repeating-linear-gradient(0deg, transparent, transparent 27px, #efe7d3 27px, #efe7d3 28px);
border-radius: 10px 10px 0 0;
}
#pa-masthead h1 {
font-family: "Source Serif 4", Georgia, serif; letter-spacing: .5px;
color: var(--ink); margin: 0; font-size: 2.1rem;
}
#pa-masthead .sub { color: #5b6b5e; font-style: italic; margin-top: 2px; }
#pa-masthead .rule { color: var(--green); font-weight: 700; }
/* Numbers look like numbers */
.pa-num, .pa-figure, table td, .pa-amount {
font-family: "JetBrains Mono", Consolas, monospace !important;
font-variant-numeric: tabular-nums;
}
.pa-amount { font-size: 1.6rem; font-weight: 700; color: var(--ink); }
.pa-neg { color: var(--red) !important; }
/* Stat cards */
.pa-cards { display:flex; gap:12px; flex-wrap:wrap; }
.pa-card {
flex:1; min-width:150px; background:#fffdf8; border:1px solid var(--line);
border-left:4px solid var(--green); border-radius:8px; padding:12px 14px;
}
.pa-card .k { font-size:.78rem; text-transform:uppercase; letter-spacing:.06em; color:#7b6f56; }
.pa-card .v { font-family:"JetBrains Mono",monospace; font-size:1.35rem; font-weight:700; color:var(--ink); }
.pa-card .src { font-size:.72rem; color:#9a8e74; margin-top:4px; }
/* Tabs as ledger tabs */
.tab-nav button { font-family:"Source Serif 4",serif !important; font-size:1rem !important; }
.tab-nav button.selected { color:var(--green) !important; border-bottom:3px solid var(--green) !important; }
/* Breakdown / citation blocks */
.pa-note {
background:#f3efe2; border-left:3px solid var(--gold); padding:8px 12px;
border-radius:6px; font-size:.9rem; color:#4a4636;
}
.pa-cite { border-left:3px solid var(--green); background:#eef5ef; }
footer { display:none !important; }
.pa-foot { text-align:center; color:#8a7f66; font-size:.8rem; padding:10px; font-style:italic; }
"""
MASTHEAD = """
<div id="pa-masthead">
<h1>🧮 PocketAccountant</h1>
<div class="sub">Your pocket accountant agent for freelancers &amp; small businesses
· <span class="rule">🇲🇽 Mexico &amp; 🇺🇸 USA</span></div>
</div>
"""