Spaces:
Running on Zero
Running on Zero
| /* FrogQuest — 8-bit / NES-RPG pixel-art theme for plain Gradio (gr.Blocks). | |
| Single-page master-detail layout (left = hero/stats/settings, center = selected scene + | |
| actions, right = task list, bottom = Frog Master chat). Palette is the fixed "Eat That Frog" | |
| green / black / red scheme; the cyberpunk/fantasy/space theme only flavors the generated | |
| images, never the UI. */ | |
| :root { | |
| --bg: #0a0f0a; /* near-black green-tinted background */ | |
| --bg2: #10180f; /* raised surfaces / inputs */ | |
| --panel: #16241a; /* panels & cards */ | |
| --ink: #eafbe2; /* primary text */ | |
| --dim: #8fae84; /* muted text */ | |
| --accent: #4ade5b; /* FROG GREEN — primary actions, borders, logo */ | |
| --accent2: #e5484d; /* RED — danger / couldn't */ | |
| --select: #ff8a1f; /* ORANGE — currently-selected task highlight */ | |
| --success: #4ade5b; /* green — done */ | |
| --danger: #e5484d; /* red — couldn't */ | |
| --gold: #ffd23f; /* XP / accents */ | |
| --frog: #4ade5b; /* frog-quest border */ | |
| --shadow: #000; | |
| --border: 4px; | |
| } | |
| /* ================= Gradio chrome neutralization ================= */ | |
| *, *::before, *::after { box-sizing: border-box; } | |
| body, gradio-app, .gradio-container { | |
| background: var(--bg) ; | |
| color: var(--ink) ; | |
| font-family: "Press Start 2P", monospace ; | |
| image-rendering: pixelated; | |
| } | |
| .gradio-container { | |
| max-width: min(1720px, 97vw) ; /* use the screen — was 1240px w/ huge dead margins */ | |
| margin: 0 auto ; | |
| padding: 0 16px 32px ; | |
| font-size: 11px ; | |
| line-height: 1.7 ; | |
| } | |
| /* faint background grid */ | |
| .gradio-container { | |
| background-image: | |
| repeating-linear-gradient(0deg, transparent 0 38px, rgba(120,255,120,0.02) 38px 39px), | |
| repeating-linear-gradient(90deg, transparent 0 38px, rgba(120,255,120,0.02) 38px 39px) ; | |
| } | |
| /* CRT scanlines overlay */ | |
| body::after { | |
| content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 9000; | |
| background: repeating-linear-gradient(0deg, rgba(0,0,0,0.16) 0 2px, transparent 2px 4px); | |
| mix-blend-mode: multiply; | |
| } | |
| /* hide Gradio's footer & progress chrome */ | |
| footer, .gradio-container > .main > .wrap > .contain > div > .built-with, | |
| .show-api, .built-with { display: none ; } | |
| /* strip default block styling so our panels/cards control the look */ | |
| .block, .form, .gr-box, .gr-block, .styler, | |
| .gradio-container .prose { background: transparent ; border: none ; | |
| box-shadow: none ; border-radius: 0 ; } | |
| .gr-padded, .block.padded { padding: 0 ; } | |
| .gap, .gradio-container .gap { gap: 0 ; } | |
| /* ================= top bar ================= */ | |
| .fq-topbar { | |
| display: flex; align-items: center; justify-content: space-between; | |
| padding: 14px 4px; border-bottom: var(--border) solid var(--accent); | |
| background: var(--bg2); margin-bottom: 16px; | |
| } | |
| .fq-logo { margin: 0; font-size: 20px; letter-spacing: 2px; color: var(--accent); | |
| text-shadow: 3px 3px 0 var(--shadow); } | |
| .fq-logo b { color: var(--accent2); font-weight: normal; } | |
| /* ================= master-detail grid ================= */ | |
| /* the wrapping gr.Row becomes a 3-column grid; its child gr.Columns are the cells. | |
| Wider side panels (hero content fits without endless wrapping -> shorter panel); | |
| the center takes everything else. */ | |
| .fq-app-grid { display: grid ; grid-template-columns: 320px minmax(0, 1fr) 320px ; | |
| gap: 16px ; align-items: start ; flex-wrap: nowrap ; } | |
| .fq-app-grid > .fq-left, .fq-app-grid > .fq-center, .fq-app-grid > .fq-right { min-width: 0 ; } | |
| .panel, .fq-left, .fq-center, .fq-right { | |
| background: var(--panel) ; | |
| border: var(--border) solid var(--ink) ; | |
| box-shadow: 6px 6px 0 var(--shadow) ; | |
| padding: 16px ; | |
| } | |
| .panel-title { margin: 0 0 12px; font-size: 12px; color: var(--gold); text-shadow: 2px 2px 0 var(--shadow); } | |
| .panel-subtitle { margin: 16px 0 10px; font-size: 10px; color: var(--accent); } | |
| .hint { color: var(--dim); font-size: 9px; line-height: 1.9; } | |
| /* ================= buttons ================= */ | |
| button.pix-btn, .pix-btn button, .pix-btn { | |
| font-family: "Press Start 2P", monospace ; font-size: 10px ; | |
| color: var(--ink) ; cursor: pointer; | |
| background: var(--bg2) ; border: var(--border) solid var(--ink) ; | |
| box-shadow: 4px 4px 0 var(--shadow) ; padding: 12px 14px ; | |
| text-transform: uppercase; border-radius: 0 ; | |
| transition: transform .05s, box-shadow .05s; min-width: 0 ; | |
| } | |
| button.pix-btn:hover, .pix-btn button:hover { background: var(--accent) ; color: var(--bg) ; } | |
| button.pix-btn:active, .pix-btn button:active { transform: translate(4px, 4px); box-shadow: 0 0 0 var(--shadow) ; } | |
| .pix-btn.primary, .pix-btn.primary button { | |
| background: var(--accent) ; color: var(--bg) ; border-color: #fff ; | |
| width: 100% ; font-size: 11px ; padding: 14px ; | |
| } | |
| .pix-btn.primary:hover, .pix-btn.primary button:hover { background: var(--gold) ; color: var(--bg) ; } | |
| .pix-btn.small, .pix-btn.small button { font-size: 8px ; padding: 9px 10px ; box-shadow: 3px 3px 0 var(--shadow) ; } | |
| /* ================= LEFT: hero photo / stats / settings ================= */ | |
| .fq-photo .image-container, .fq-photo .upload-container, .fq-photo [data-testid="image"] { | |
| min-height: 180px ; background: var(--bg2) ; | |
| border: var(--border) dashed var(--accent) ; border-radius: 0 ; | |
| } | |
| .fq-photo .image-container img { image-rendering: pixelated; object-fit: cover; } | |
| .fq-photo .wrap, .fq-photo .icon-wrap, .fq-photo .upload-text { color: var(--dim) ; | |
| font-family: "Press Start 2P", monospace ; font-size: 8px ; } | |
| .fq-stats { margin: 14px 0; padding: 12px; background: var(--bg2); | |
| border: 2px solid var(--dim); } | |
| .fq-stats h4 { margin: 0 0 8px; font-size: 9px; color: var(--accent); } | |
| .fq-stats .stat-row { display: flex; justify-content: space-between; font-size: 9px; | |
| color: var(--ink); margin: 6px 0; } | |
| .fq-stats .stat-row b { color: var(--gold); } | |
| .fq-settings { margin-top: 12px; } | |
| /* world picker (gr.Radio styled to fit the pixel theme) — one row in the 320px panel */ | |
| .fq-theme, .fq-theme * { color: var(--ink) ; } | |
| .fq-theme .wrap { gap: 6px ; display: flex ; flex-direction: row ; | |
| flex-wrap: nowrap ; } | |
| .fq-theme label, .fq-theme .wrap label { | |
| background: var(--bg2) ; border: 3px solid var(--dim) ; | |
| box-shadow: 3px 3px 0 var(--shadow) ; border-radius: 0 ; | |
| font-family: "Press Start 2P", monospace ; font-size: 8px ; | |
| padding: 8px 6px ; cursor: pointer; text-transform: uppercase; | |
| flex: 1 1 0 ; justify-content: center ; white-space: nowrap; | |
| } | |
| .fq-theme label:hover { border-color: var(--accent) ; } | |
| .fq-theme label.selected, .fq-theme input:checked ~ * { | |
| border-color: var(--select) ; color: var(--select) ; | |
| box-shadow: 3px 3px 0 var(--select) ; | |
| } | |
| .fq-theme input[type="radio"] { accent-color: var(--accent); } | |
| /* theme picker (3 buttons styled as small cards) */ | |
| .theme-card, .theme-card button { | |
| font-family: "Press Start 2P", monospace ; font-size: 8px ; | |
| color: var(--ink) ; cursor: pointer; height: 100%; | |
| display: flex ; flex-direction: column; align-items: center; gap: 6px; | |
| padding: 10px 4px ; background: var(--bg2) ; | |
| border: 3px solid var(--dim) ; box-shadow: 3px 3px 0 var(--shadow) ; | |
| border-radius: 0 ; white-space: pre-line; line-height: 1.5; | |
| } | |
| .theme-card:hover, .theme-card button:hover { border-color: var(--accent) ; } | |
| .theme-card.selected, .theme-card.selected button { | |
| border-color: var(--select) ; background: var(--panel) ; | |
| box-shadow: 3px 3px 0 var(--select) ; | |
| } | |
| /* ================= CENTER: scene / description / actions ================= */ | |
| .fq-scene .image-container, .fq-scene [data-testid="image"] { | |
| min-height: 360px ; background: var(--bg2) ; border-radius: 0 ; | |
| border: var(--border) solid var(--ink) ; | |
| } | |
| .fq-scene img { image-rendering: pixelated; object-fit: contain; width: 100%; } | |
| .fq-detail { display: flex; gap: 14px; align-items: stretch; margin-top: 14px; } | |
| .fq-desc { flex: 1; background: var(--bg2); border: var(--border) solid var(--ink); | |
| box-shadow: 4px 4px 0 var(--shadow); padding: 14px 16px; min-height: 96px; } | |
| .fq-desc .adventure-header h2 { font-size: 13px; color: var(--gold); text-shadow: 2px 2px 0 var(--shadow); margin: 0 0 8px; } | |
| .fq-desc .quest-title { margin: 0 0 8px; font-size: 12px; color: var(--ink); line-height: 1.6; } | |
| .fq-desc .quest-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; } | |
| .fq-desc .quest-narrative { margin: 0 0 10px; font-size: 9px; color: var(--dim); line-height: 1.9; } | |
| .fq-desc .quest-task { margin: 0 0 8px; font-size: 9px; color: var(--accent); line-height: 1.8; } | |
| .fq-desc .quest-task::before { content: "▸ TASK: "; color: var(--dim); } | |
| .fq-desc .xp { font-size: 9px; color: var(--gold); } | |
| .fq-desc .xp::before { content: "★ "; } | |
| .fq-desc.state-success { border-color: var(--success); box-shadow: 4px 4px 0 var(--success); } | |
| .fq-desc.state-failure { border-color: var(--danger); box-shadow: 4px 4px 0 var(--danger); } | |
| .fq-desc .result-msg { font-size: 10px; line-height: 1.9; } | |
| .fq-desc.state-success .result-msg { color: var(--success); } | |
| .fq-desc.state-failure .result-msg { color: var(--danger); } | |
| .fq-empty { color: var(--dim); font-size: 10px; line-height: 1.9; } | |
| .fq-actions { display: flex; flex-direction: column; gap: 12px; justify-content: center; min-width: 132px; } | |
| .btn-done, .btn-done button { | |
| background: var(--success) ; color: var(--bg) ; border-color: #fff ; | |
| font-size: 11px ; | |
| } | |
| .btn-done:hover, .btn-done button:hover { background: var(--gold) ; } | |
| .btn-couldnt, .btn-couldnt button { | |
| background: var(--danger) ; color: #fff ; border-color: #fff ; | |
| font-size: 9px ; | |
| } | |
| .btn-couldnt:hover, .btn-couldnt button:hover { background: #ff7a7e ; color: var(--bg) ; } | |
| /* ================= RIGHT: task list ================= */ | |
| .fq-right .panel-title { margin-bottom: 12px; } | |
| .fq-tasklist { display: flex; flex-direction: column; gap: 10px; } | |
| .fq-task-row { display: flex ; gap: 6px ; align-items: stretch ; | |
| flex-wrap: nowrap ; } | |
| .fq-task-row .fq-task-item { flex: 1 1 auto ; } | |
| .fq-task-clear, .fq-task-clear button { | |
| flex: 0 0 auto ; width: 40px ; min-width: 40px ; | |
| padding: 8px ; color: var(--danger) ; font-size: 11px ; | |
| } | |
| .fq-task-clear:hover, .fq-task-clear button:hover { background: var(--danger) ; color: #fff ; } | |
| .fq-task-item, .fq-task-item button { | |
| font-family: "Press Start 2P", monospace ; font-size: 9px ; | |
| text-align: left ; color: var(--ink) ; cursor: pointer; | |
| background: var(--bg2) ; border: 3px solid var(--ink) ; | |
| box-shadow: 3px 3px 0 var(--shadow) ; padding: 11px 12px ; | |
| border-radius: 0 ; width: 100% ; line-height: 1.6; white-space: normal; | |
| } | |
| .fq-task-item:hover, .fq-task-item button:hover { border-color: var(--accent) ; } | |
| .fq-task-item.selected, .fq-task-item.selected button { | |
| border-color: var(--select) ; box-shadow: 4px 4px 0 var(--select) ; | |
| color: var(--select) ; background: var(--panel) ; | |
| } | |
| .fq-task-item.is-frog, .fq-task-item.is-frog button { border-color: var(--frog) ; } | |
| .fq-task-item.done, .fq-task-item.done button { opacity: 0.7; border-color: var(--success) ; } | |
| .fq-task-item.failed, .fq-task-item.failed button { opacity: 0.6; border-style: dashed ; } | |
| /* badges (reused in the description pane and task items) */ | |
| .badge { font-size: 8px; padding: 4px 6px; border: 2px solid currentColor; display: inline-block; } | |
| .frog-badge { color: var(--frog); } | |
| .bonus-badge { color: var(--accent); } | |
| .group-badge { color: var(--gold); } | |
| /* ================= BOTTOM: Frog Master chat bar ================= */ | |
| .fq-chatbar { display: flex ; gap: 12px ; align-items: stretch ; | |
| margin-top: 16px ; flex-wrap: nowrap ; } | |
| .fq-chatbar .fq-chat-input { flex: 1 ; min-width: 0 ; } | |
| .fq-chatbar .fq-chat-send { width: 150px ; flex: 0 0 auto ; } | |
| .compose textarea { | |
| width: 100%; resize: none; font-family: "Press Start 2P", monospace ; | |
| font-size: 10px ; line-height: 1.8 ; color: var(--ink) ; | |
| background: var(--bg2) ; border: var(--border) solid var(--accent) ; | |
| padding: 14px ; box-shadow: inset 3px 3px 0 var(--shadow); border-radius: 0 ; | |
| } | |
| .compose textarea:focus { outline: none; border-color: var(--gold) ; box-shadow: inset 3px 3px 0 var(--shadow) ; } | |
| .fq-chat-hint { color: var(--dim); font-size: 8px; margin: 8px 2px 0; line-height: 1.8; } | |
| /* ================= responsive: stack on narrow screens ================= */ | |
| @media (max-width: 1100px) { | |
| .fq-app-grid { grid-template-columns: 1fr ; } | |
| .fq-logo { font-size: 16px; } | |
| .fq-detail { flex-direction: column; } | |
| .fq-actions { flex-direction: row; min-width: 0; } | |
| } | |