US-aware Capture/Ledger + wire in the reasoning LLM agent (Qwen3-8B via vLLM/Modal) with router fallback
d103096 verified | """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 & small businesses | |
| · <span class="rule">🇲🇽 Mexico & 🇺🇸 USA</span></div> | |
| </div> | |
| """ | |