""" src/ui/styles.py — Custom CSS for the Codevally VLA Demo UI. All visual styling is centralised here so that layout.py stays focused purely on component structure. """ CUSTOM_CSS: str = """ /* ── Google Font ── */ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); /* ── Root & Body ── */ :root { --cv-blue: #1A4BDB; --cv-dark: #0D1B3E; --cv-accent: #00D4FF; --cv-glass: rgba(255,255,255,0.06); --cv-border: rgba(255,255,255,0.1); --cv-success: #22C55E; --cv-warn: #F59E0B; --cv-error: #EF4444; } body, .gradio-container { font-family: 'Inter', system-ui, sans-serif !important; background: linear-gradient(135deg, #0a0f1e 0%, #0d1b3e 50%, #0a0f1e 100%) !important; min-height: 100vh; } /* ── Header Banner ── */ .cv-header { background: linear-gradient(135deg, #0D1B3E 0%, #1A2E5E 60%, #0D1B3E 100%); border: 1px solid var(--cv-border); border-radius: 16px; padding: 28px 36px; margin-bottom: 20px; position: relative; overflow: hidden; } .cv-header::before { content: ''; position: absolute; top: -60px; right: -60px; width: 220px; height: 220px; background: radial-gradient(circle, rgba(0,212,255,0.12) 0%, transparent 70%); border-radius: 50%; } .cv-header::after { content: ''; position: absolute; bottom: -40px; left: 20%; width: 140px; height: 140px; background: radial-gradient(circle, rgba(26,75,219,0.15) 0%, transparent 70%); border-radius: 50%; } /* ── Badges ── */ .cv-badge { display: inline-block; background: rgba(0,212,255,0.12); color: var(--cv-accent); border: 1px solid rgba(0,212,255,0.3); border-radius: 20px; padding: 3px 12px; font-size: 12px; font-weight: 500; margin: 2px 4px 2px 0; letter-spacing: 0.03em; } /* ── Cards ── */ .cv-card { background: var(--cv-glass); backdrop-filter: blur(12px); border: 1px solid var(--cv-border); border-radius: 16px; padding: 20px; transition: border-color 0.2s; } .cv-card:hover { border-color: rgba(0,212,255,0.25); } /* ── Section labels ── */ .cv-section-label { font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--cv-accent); margin-bottom: 8px; } /* ── Run button ── */ button.primary { background: linear-gradient(135deg, var(--cv-blue) 0%, #2563EB 100%) !important; border: none !important; border-radius: 10px !important; font-weight: 600 !important; font-size: 15px !important; letter-spacing: 0.02em !important; box-shadow: 0 4px 20px rgba(26,75,219,0.4) !important; transition: transform 0.15s, box-shadow 0.15s !important; } button.primary:hover { transform: translateY(-1px) !important; box-shadow: 0 6px 28px rgba(26,75,219,0.55) !important; } button.primary:active { transform: translateY(0) !important; } /* ── Tabs ── */ .tabs .tab-nav { border-bottom: 1px solid var(--cv-border) !important; } .tabs .tab-nav button { font-weight: 500 !important; color: rgba(255,255,255,0.55) !important; border-radius: 8px 8px 0 0 !important; } .tabs .tab-nav button.selected { color: var(--cv-accent) !important; border-bottom: 2px solid var(--cv-accent) !important; background: rgba(0,212,255,0.07) !important; } /* ── Inputs ── */ input, textarea, .block { border-radius: 10px !important; } /* ── Footer ── */ .cv-footer { text-align: center; padding: 16px 0 6px; font-size: 13px; color: rgba(255,255,255,0.35); } .cv-footer a { color: var(--cv-accent); text-decoration: none; font-weight: 500; } .cv-footer a:hover { text-decoration: underline; } /* ── Status box ── */ .status-box { background: rgba(255,255,255,0.04); border-radius: 10px; border: 1px solid var(--cv-border); padding: 10px 14px; font-size: 14px; min-height: 40px; } /* ── How it works strip ── */ .how-it-works { display: flex; gap: 0; margin: 18px 0 8px; border-radius: 12px; overflow: hidden; border: 1px solid var(--cv-border); } .hiw-step { flex: 1; padding: 14px 12px; text-align: center; background: rgba(255,255,255,0.03); border-right: 1px solid var(--cv-border); font-size: 12px; color: rgba(255,255,255,0.7); } .hiw-step:last-child { border-right: none; } .hiw-step .hiw-icon { font-size: 20px; display: block; margin-bottom: 4px; } .hiw-step .hiw-label { font-weight: 600; font-size: 11px; letter-spacing: 0.05em; color: var(--cv-accent); display: block; margin-bottom: 2px; text-transform: uppercase; } /* ── Hide default Gradio footer bar ── */ footer { display: none !important; } .gradio-container ~ footer { display: none !important; } /* ── Scrollable Detection JSON box ── */ #result_tabs .code-wrap, #result_tabs .cm-scroller, #result_tabs .codemirror-wrapper { max-height: 380px !important; overflow-y: auto !important; scrollbar-width: thin; scrollbar-color: rgba(0,212,255,0.4) rgba(255,255,255,0.05); } #result_tabs .code-wrap::-webkit-scrollbar { width: 6px; } #result_tabs .code-wrap::-webkit-scrollbar-track { background: rgba(255,255,255,0.05); border-radius: 3px; } #result_tabs .code-wrap::-webkit-scrollbar-thumb { background: rgba(0,212,255,0.4); border-radius: 3px; } #result_tabs .code-wrap::-webkit-scrollbar-thumb:hover { background: rgba(0,212,255,0.65); } """