import gradio as gr from gradio.themes.base import Base from gradio.themes.utils import colors, fonts, sizes def get_cyberpunk_theme(): """Create cyberpunk-themed Gradio theme""" theme = gr.themes.Base( primary_hue=colors.green, secondary_hue=colors.purple, neutral_hue=colors.gray, font=[fonts.GoogleFont("Orbitron"), "monospace", "sans-serif"], radius_size=sizes.Size( xxs="2px", xs="3px", sm="4px", md="6px", lg="8px", xl="10px", xxl="12px" ) ).set( # Background colors body_background_fill="linear-gradient(135deg, #0a0a0a, #1a0033, #001122)", body_background_fill_dark="linear-gradient(135deg, #050505, #0d001a, #000811)", # Text colors body_text_color="#00ff41", body_text_color_dark="#00ff41", body_text_color_subdued="#8A2BE2", body_text_color_subdued_dark="#8A2BE2", # Component colors background_fill_primary="rgba(0, 255, 65, 0.1)", background_fill_primary_dark="rgba(0, 255, 65, 0.05)", background_fill_secondary="rgba(138, 43, 226, 0.1)", background_fill_secondary_dark="rgba(138, 43, 226, 0.05)", # Borders border_color_primary="#00ff41", border_color_primary_dark="#00ff41", border_color_accent="#8A2BE2", border_color_accent_dark="#8A2BE2", # Shadows shadow_drop="0 0 20px rgba(0, 255, 65, 0.5)", shadow_drop_lg="0 0 30px rgba(138, 43, 226, 0.5)", # Buttons button_primary_background_fill="linear-gradient(45deg, #00ff41, #8A2BE2)", button_primary_background_fill_hover="linear-gradient(45deg, #00ff41, #9932CC)", button_primary_background_fill_dark="linear-gradient(45deg, #00cc33, #7B68EE)", button_primary_text_color="#000000", button_primary_text_color_dark="#000000", # Inputs input_background_fill="rgba(0, 0, 0, 0.8)", input_background_fill_dark="rgba(0, 0, 0, 0.9)", input_border_color="#00ff41", input_border_color_dark="#00ff41", input_border_color_focus="#8A2BE2", input_border_color_focus_dark="#8A2BE2", # Other elements block_background_fill="rgba(0, 0, 0, 0.6)", block_background_fill_dark="rgba(0, 0, 0, 0.8)", block_border_color="#00ff41", block_border_color_dark="#00ff41", block_border_width="2px", block_shadow="0 0 15px rgba(0, 255, 65, 0.3)", ) return theme # Custom CSS for additional cyberpunk styling CYBERPUNK_CSS = """ /* Import cyberpunk font */ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&display=swap'); /* Global styles */ * { font-family: 'Orbitron', monospace !important; } /* Animated background */ .gradio-container { background: linear-gradient(135deg, #0a0a0a, #1a0033, #001122); background-size: 400% 400%; animation: gradient-shift 15s ease infinite; } @keyframes gradient-shift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } /* Cyber header */ .cyber-header { background: linear-gradient(135deg, rgba(0,0,0,0.9), rgba(26,0,51,0.9)); border: 2px solid #00ff41; border-radius: 10px; padding: 30px; margin-bottom: 30px; position: relative; overflow: hidden; box-shadow: 0 0 30px rgba(0,255,65,0.5), inset 0 0 30px rgba(0,255,65,0.1); } .cyber-header::before { content: ''; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; background: linear-gradient(45deg, #00ff41, #8A2BE2, #00ff41); z-index: -1; animation: border-glow 3s linear infinite; filter: blur(5px); } @keyframes border-glow { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } /* Glitch text effect */ .glitch-text { position: relative; color: #00ff41; font-size: 3em; font-weight: 900; text-transform: uppercase; text-shadow: 0 0 10px #00ff41, 0 0 20px #00ff41, 0 0 40px #00ff41; animation: text-glow 2s ease-in-out infinite alternate; } @keyframes text-glow { from { text-shadow: 0 0 10px #00ff41, 0 0 20px #00ff41, 0 0 40px #00ff41; } to { text-shadow: 0 0 20px #00ff41, 0 0 30px #00ff41, 0 0 50px #00ff41; } } .glitch-text::before, .glitch-text::after { content: attr(data-text); position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .glitch-text::before { animation: glitch-1 0.5s infinite; color: #8A2BE2; z-index: -1; } .glitch-text::after { animation: glitch-2 0.5s infinite; color: #00ff41; z-index: -2; } @keyframes glitch-1 { 0% { clip: rect(44px, 450px, 56px, 0); transform: translate(0); } 20% { clip: rect(20px, 450px, 30px, 0); transform: translate(-2px, 2px); } 40% { clip: rect(85px, 450px, 95px, 0); transform: translate(2px, -2px); } 60% { clip: rect(10px, 450px, 20px, 0); transform: translate(-1px, 1px); } 80% { clip: rect(60px, 450px, 70px, 0); transform: translate(1px, -1px); } 100% { clip: rect(44px, 450px, 56px, 0); transform: translate(0); } } @keyframes glitch-2 { 0% { clip: rect(65px, 450px, 75px, 0); transform: translate(0); } 20% { clip: rect(30px, 450px, 40px, 0); transform: translate(2px, -2px); } 40% { clip: rect(90px, 450px, 100px, 0); transform: translate(-2px, 2px); } 60% { clip: rect(15px, 450px, 25px, 0); transform: translate(1px, -1px); } 80% { clip: rect(70px, 450px, 80px, 0); transform: translate(-1px, 1px); } 100% { clip: rect(65px, 450px, 75px, 0); transform: translate(0); } } /* Cyber subtitle */ .cyber-subtitle { color: #8A2BE2; font-size: 1.2em; text-transform: uppercase; letter-spacing: 2px; text-shadow: 0 0 10px #8A2BE2; } /* Pulse line */ .pulse-line { height: 2px; background: linear-gradient(90deg, transparent, #00ff41, transparent); margin: 20px 0; animation: pulse-width 2s ease-in-out infinite; } @keyframes pulse-width { 0%, 100% { transform: scaleX(0.5); opacity: 0.5; } 50% { transform: scaleX(1); opacity: 1; } } /* Cyber containers */ .cyber-container { background: rgba(0, 0, 0, 0.8); border: 2px solid #00ff41; border-radius: 8px; padding: 20px; position: relative; box-shadow: 0 0 20px rgba(0, 255, 65, 0.3), inset 0 0 20px rgba(0, 255, 65, 0.1); animation: container-pulse 4s ease-in-out infinite; } @keyframes container-pulse { 0%, 100% { border-color: #00ff41; box-shadow: 0 0 20px rgba(0, 255, 65, 0.3), inset 0 0 20px rgba(0, 255, 65, 0.1); } 50% { border-color: #8A2BE2; box-shadow: 0 0 30px rgba(138, 43, 226, 0.5), inset 0 0 20px rgba(138, 43, 226, 0.1); } } /* Cyber buttons */ .cyber-button { background: linear-gradient(45deg, #00ff41, #8A2BE2); border: none; color: #000; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; padding: 12px 24px; border-radius: 6px; position: relative; overflow: hidden; transition: all 0.3s ease; box-shadow: 0 0 20px rgba(0, 255, 65, 0.5); } .cyber-button::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: rgba(255, 255, 255, 0.3); border-radius: 50%; transform: translate(-50%, -50%); transition: width 0.6s, height 0.6s; } .cyber-button:hover::before { width: 300px; height: 300px; } .cyber-button:hover { transform: translateY(-2px); box-shadow: 0 5px 30px rgba(0, 255, 65, 0.7); } /* Generate button special */ .generate-button { font-size: 1.2em; animation: generate-pulse 2s ease-in-out infinite; } @keyframes generate-pulse { 0%, 100% { box-shadow: 0 0 20px rgba(0, 255, 65, 0.5); } 50% { box-shadow: 0 0 40px rgba(0, 255, 65, 0.8), 0 0 60px rgba(138, 43, 226, 0.5); } } /* Cyber inputs */ .cyber-input input, .cyber-input textarea { background: rgba(0, 0, 0, 0.9) !important; border: 2px solid #00ff41 !important; color: #00ff41 !important; font-family: 'Orbitron', monospace !important; transition: all 0.3s ease; } .cyber-input input:focus, .cyber-input textarea:focus { border-color: #8A2BE2 !important; box-shadow: 0 0 20px rgba(138, 43, 226, 0.5) !important; outline: none !important; } /* Monster display */ .monster-display { background: rgba(0, 0, 0, 0.9); border: 2px solid #00ff41; border-radius: 10px; padding: 20px; position: relative; overflow: hidden; } .monster-display::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(0, 255, 65, 0.2), transparent); animation: scan-line 3s linear infinite; } @keyframes scan-line { 0% { left: -100%; } 100% { left: 100%; } } /* Evolution display */ .evolution-display { background: linear-gradient(135deg, rgba(138, 43, 226, 0.2), rgba(0, 255, 65, 0.2)); border: 2px solid #8A2BE2; border-radius: 8px; padding: 15px; margin: 10px 0; animation: evolution-glow 2s ease-in-out infinite; } @keyframes evolution-glow { 0%, 100% { box-shadow: 0 0 20px rgba(138, 43, 226, 0.5); } 50% { box-shadow: 0 0 40px rgba(138, 43, 226, 0.8); } } /* Cyber dialogue */ .cyber-dialogue { font-size: 1.5em; text-align: center; color: #00ff41; text-shadow: 0 0 10px currentColor; } /* Cyber stats */ .cyber-stats { font-family: 'Orbitron', monospace; color: #00ff41; } .cyber-stats .label { color: #8A2BE2; } /* Tab styling */ .cyber-tabs .tab-nav { background: rgba(0, 0, 0, 0.8); border-bottom: 2px solid #00ff41; } .cyber-tabs .tab-nav button { color: #00ff41 !important; background: transparent !important; border: none !important; transition: all 0.3s ease; } .cyber-tabs .tab-nav button:hover { background: rgba(0, 255, 65, 0.1) !important; text-shadow: 0 0 10px #00ff41; } .cyber-tabs .tab-nav button.selected { background: rgba(0, 255, 65, 0.2) !important; border-bottom: 3px solid #00ff41 !important; } /* Loading animation */ .loading { display: inline-block; width: 20px; height: 20px; border: 3px solid rgba(0, 255, 65, 0.3); border-radius: 50%; border-top-color: #00ff41; animation: spin 1s ease-in-out infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Scrollbar styling */ ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.5); border: 1px solid #00ff41; } ::-webkit-scrollbar-thumb { background: linear-gradient(45deg, #00ff41, #8A2BE2); border-radius: 5px; } ::-webkit-scrollbar-thumb:hover { background: linear-gradient(45deg, #00ff41, #9932CC); } /* Mobile responsiveness */ @media (max-width: 768px) { .glitch-text { font-size: 2em; } .cyber-container { padding: 15px; } .cyber-button { padding: 10px 20px; font-size: 0.9em; } } """