SahilCodevally/codevally-vision-language-action
0
1"""2src/ui/styles.py — Custom CSS for the Codevally VLA Demo UI.3 4All visual styling is centralised here so that layout.py stays5focused purely on component structure.6"""7 8CUSTOM_CSS: str = """9/* ── Google Font ── */10@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');11 12/* ── Root & Body ── */13:root {14 --cv-blue: #1A4BDB;15 --cv-dark: #0D1B3E;16 --cv-accent: #00D4FF;17 --cv-glass: rgba(255,255,255,0.06);18 --cv-border: rgba(255,255,255,0.1);19 --cv-success: #22C55E;20 --cv-warn: #F59E0B;21 --cv-error: #EF4444;22}23 24body, .gradio-container {25 font-family: 'Inter', system-ui, sans-serif !important;26 background: linear-gradient(135deg, #0a0f1e 0%, #0d1b3e 50%, #0a0f1e 100%) !important;27 min-height: 100vh;28}29 30/* ── Header Banner ── */31.cv-header {32 background: linear-gradient(135deg, #0D1B3E 0%, #1A2E5E 60%, #0D1B3E 100%);33 border: 1px solid var(--cv-border);34 border-radius: 16px;35 padding: 28px 36px;36 margin-bottom: 20px;37 position: relative;38 overflow: hidden;39}40.cv-header::before {41 content: '';42 position: absolute;43 top: -60px; right: -60px;44 width: 220px; height: 220px;45 background: radial-gradient(circle, rgba(0,212,255,0.12) 0%, transparent 70%);46 border-radius: 50%;47}48.cv-header::after {49 content: '';50 position: absolute;51 bottom: -40px; left: 20%;52 width: 140px; height: 140px;53 background: radial-gradient(circle, rgba(26,75,219,0.15) 0%, transparent 70%);54 border-radius: 50%;55}56 57/* ── Badges ── */58.cv-badge {59 display: inline-block;60 background: rgba(0,212,255,0.12);61 color: var(--cv-accent);62 border: 1px solid rgba(0,212,255,0.3);63 border-radius: 20px;64 padding: 3px 12px;65 font-size: 12px;66 font-weight: 500;67 margin: 2px 4px 2px 0;68 letter-spacing: 0.03em;69}70 71/* ── Cards ── */72.cv-card {73 background: var(--cv-glass);74 backdrop-filter: blur(12px);75 border: 1px solid var(--cv-border);76 border-radius: 16px;77 padding: 20px;78 transition: border-color 0.2s;79}80.cv-card:hover { border-color: rgba(0,212,255,0.25); }81 82/* ── Section labels ── */83.cv-section-label {84 font-size: 11px;85 font-weight: 600;86 letter-spacing: 0.08em;87 text-transform: uppercase;88 color: var(--cv-accent);89 margin-bottom: 8px;90}91 92/* ── Run button ── */93button.primary {94 background: linear-gradient(135deg, var(--cv-blue) 0%, #2563EB 100%) !important;95 border: none !important;96 border-radius: 10px !important;97 font-weight: 600 !important;98 font-size: 15px !important;99 letter-spacing: 0.02em !important;100 box-shadow: 0 4px 20px rgba(26,75,219,0.4) !important;101 transition: transform 0.15s, box-shadow 0.15s !important;102}103button.primary:hover {104 transform: translateY(-1px) !important;105 box-shadow: 0 6px 28px rgba(26,75,219,0.55) !important;106}107button.primary:active { transform: translateY(0) !important; }108 109/* ── Tabs ── */110.tabs .tab-nav { border-bottom: 1px solid var(--cv-border) !important; }111.tabs .tab-nav button {112 font-weight: 500 !important;113 color: rgba(255,255,255,0.55) !important;114 border-radius: 8px 8px 0 0 !important;115}116.tabs .tab-nav button.selected {117 color: var(--cv-accent) !important;118 border-bottom: 2px solid var(--cv-accent) !important;119 background: rgba(0,212,255,0.07) !important;120}121 122/* ── Inputs ── */123input, textarea, .block { border-radius: 10px !important; }124 125/* ── Footer ── */126.cv-footer {127 text-align: center;128 padding: 16px 0 6px;129 font-size: 13px;130 color: rgba(255,255,255,0.35);131}132.cv-footer a {133 color: var(--cv-accent);134 text-decoration: none;135 font-weight: 500;136}137.cv-footer a:hover { text-decoration: underline; }138 139/* ── Status box ── */140.status-box {141 background: rgba(255,255,255,0.04);142 border-radius: 10px;143 border: 1px solid var(--cv-border);144 padding: 10px 14px;145 font-size: 14px;146 min-height: 40px;147}148 149/* ── How it works strip ── */150.how-it-works {151 display: flex;152 gap: 0;153 margin: 18px 0 8px;154 border-radius: 12px;155 overflow: hidden;156 border: 1px solid var(--cv-border);157}158.hiw-step {159 flex: 1;160 padding: 14px 12px;161 text-align: center;162 background: rgba(255,255,255,0.03);163 border-right: 1px solid var(--cv-border);164 font-size: 12px;165 color: rgba(255,255,255,0.7);166}167.hiw-step:last-child { border-right: none; }168.hiw-step .hiw-icon { font-size: 20px; display: block; margin-bottom: 4px; }169.hiw-step .hiw-label {170 font-weight: 600; font-size: 11px; letter-spacing: 0.05em;171 color: var(--cv-accent); display: block; margin-bottom: 2px;172 text-transform: uppercase;173}174 175/* ── Hide default Gradio footer bar ── */176footer { display: none !important; }177.gradio-container ~ footer { display: none !important; }178 179/* ── Scrollable Detection JSON box ── */180#result_tabs .code-wrap,181#result_tabs .cm-scroller,182#result_tabs .codemirror-wrapper {183 max-height: 380px !important;184 overflow-y: auto !important;185 scrollbar-width: thin;186 scrollbar-color: rgba(0,212,255,0.4) rgba(255,255,255,0.05);187}188#result_tabs .code-wrap::-webkit-scrollbar { width: 6px; }189#result_tabs .code-wrap::-webkit-scrollbar-track { background: rgba(255,255,255,0.05); border-radius: 3px; }190#result_tabs .code-wrap::-webkit-scrollbar-thumb { background: rgba(0,212,255,0.4); border-radius: 3px; }191#result_tabs .code-wrap::-webkit-scrollbar-thumb:hover { background: rgba(0,212,255,0.65); }192"""193 