Spaces:
Runtime error
Runtime error
| @import url('https://fonts.googleapis.com/css2?family=Baloo+2:wght@600;700;800&family=Nunito:wght@400;600;700;800&family=Press+Start+2P&display=swap'); | |
| :root { | |
| --sky: #8fd3ef; | |
| --sky-soft: #d9f0fa; | |
| --grass: #74c043; | |
| --grass-mid: #5aa531; | |
| --grass-dark: #3f7c20; | |
| --grass-edge: #2f5e16; | |
| --brick: #d06a44; | |
| --brick-mid: #b4502d; | |
| --brick-dark: #8a3a1f; | |
| --dirt: #7a5230; | |
| --dirt-dark: #5a3a20; | |
| --hud: #141b27; | |
| --hud-2: #1d2736; | |
| --ink: #18222e; | |
| --ink-soft: #4a5a6a; | |
| --paper: #ffffff; | |
| --paper-2: #f3f8fc; | |
| --cyan: #4cc4e6; | |
| } | |
| body { | |
| font-family: 'Nunito', system-ui, sans-serif ; | |
| color: var(--ink) ; | |
| background: | |
| radial-gradient(120% 80% at 50% -10%, #a7e0f4 0%, transparent 55%), | |
| linear-gradient(180deg, #bfe9f8 0%, #d9f1fb 38%, #e6f6ec 72%, #e0f0d6 100%) ; | |
| min-height: 100vh; | |
| } | |
| body::before { | |
| content: ""; | |
| position: fixed; | |
| inset: 0; | |
| pointer-events: none; | |
| z-index: 0; | |
| background-image: | |
| linear-gradient(rgba(60,110,150,.05) 1px, transparent 1px), | |
| linear-gradient(90deg, rgba(60,110,150,.05) 1px, transparent 1px); | |
| background-size: 32px 32px; | |
| } | |
| /* Gradio's <gradio-app> host paints --body-background-fill (white in light, | |
| near-black in dark) over our body gradient β keep it transparent so the | |
| skyβgrass gradient shows through. */ | |
| gradio-app { | |
| background: transparent ; | |
| } | |
| /* Gradio's .styler / .form wrappers carry their own surface fill that sits on | |
| top of our .gs-card β keep them transparent so the card shows through. */ | |
| .gs-card .styler, | |
| .gs-card .form { | |
| background: transparent ; | |
| border: none ; | |
| } | |
| /* ===================== DARK THEME (nighttime world) ===================== | |
| Gradio adds `body.dark` based on the visitor's system preference. Map it to | |
| the design's nighttime voxel palette (mirrors the design's [data-theme="dark"]). | |
| Most rules below just redefine the palette vars; the explicit overrides cover | |
| spots in this file that hard-code light hex, plus Gradio's own theme vars. */ | |
| body.dark { | |
| --grass: #6fb841; | |
| --grass-mid: #4f9a2c; | |
| --grass-dark: #356615; | |
| --brick: #c25f3c; | |
| --brick-dark: #7e3219; | |
| --ink: #e8eef5; | |
| --ink-soft: #9fb0c2; | |
| --paper: #1a2230; | |
| --paper-2: #131a26; | |
| --cyan: #5fd3f2; | |
| /* Gradio component variables β dark surfaces matching the palette */ | |
| --body-text-color: #e8eef5; | |
| --body-text-color-subdued: #9fb0c2; | |
| --background-fill-primary: #1a2230; | |
| --background-fill-secondary: #131a26; | |
| --block-background-fill: #1a2230; | |
| --block-label-background-fill: #1a2230; | |
| --input-background-fill: #0f1623; | |
| --input-background-fill-focus: #101a26; | |
| --border-color-primary: #33415a; | |
| --block-border-color: #33415a; | |
| } | |
| body.dark { | |
| background: | |
| radial-gradient(120% 80% at 50% -10%, #1e3346 0%, transparent 55%), | |
| linear-gradient(180deg, #0c131e 0%, #0f1826 40%, #101d22 74%, #14201a 100%) ; | |
| } | |
| body.dark::before { | |
| background-image: | |
| linear-gradient(rgba(120,170,210,.05) 1px, transparent 1px), | |
| linear-gradient(90deg, rgba(120,170,210,.05) 1px, transparent 1px); | |
| } | |
| /* NB: for descendant rules use the bare `.dark` ancestor (Gradio's dark-mode | |
| class on <body>), NOT `body.dark X`. Gradio's CSS scoper rewrites the latter | |
| to `.dark .gradio-container ... .contain body X`, placing `body` as a | |
| descendant of `.contain`, which never matches. `.dark X` scopes correctly. */ | |
| /* Cards: the base rule borders with var(--ink), which is light text in dark | |
| mode β pin the border/shadow to the design's near-black instead. */ | |
| .dark .gs-card { | |
| border-color: #0a0f17 ; | |
| box-shadow: 0 8px 0 #0a0f17, 0 22px 40px -22px rgba(0,0,0,.7) ; | |
| } | |
| .dark .gs-card-head { border-bottom-color: #0a0f17; } | |
| .dark .gs-card-head.sky { background: #1c2c3a; } | |
| .dark .gs-card-head.brick { background: #33231c; } | |
| .dark .gs-card-head.hud { background: #222d3d; } | |
| /* Inputs (textbox + dropdown). NB: give each `.dark` selector its own rule β do | |
| NOT comma-group them. Gradio's scoper inserts a stray second `.dark` into the | |
| 2nd+ members of a comma group (e.g. `.contain .dark .gs-card ...`), so only the | |
| first member ever matches. */ | |
| .dark .gs-card input { | |
| background: #0f1623 ; | |
| border-color: #33415a ; | |
| color: var(--ink) ; | |
| } | |
| .dark .gs-card textarea { | |
| background: #0f1623 ; | |
| border-color: #33415a ; | |
| color: var(--ink) ; | |
| } | |
| .dark .gs-card .svelte-1xfsv4t input[role="listbox"] { | |
| background: #0f1623 ; | |
| border-color: #33415a ; | |
| color: var(--ink) ; | |
| } | |
| .dark .gs-card input::placeholder { color: #6b7d92 ; } | |
| .dark .gs-card input:focus { | |
| border-color: var(--grass-mid) ; | |
| background: #101a26 ; | |
| box-shadow: 0 0 0 4px rgba(111,184,65,.25) ; | |
| } | |
| .dark .gs-card textarea:focus { | |
| border-color: var(--grass-mid) ; | |
| background: #101a26 ; | |
| box-shadow: 0 0 0 4px rgba(111,184,65,.25) ; | |
| } | |
| .dark .gs-card .svelte-1xfsv4t input[role="listbox"]:focus { | |
| border-color: var(--grass-mid) ; | |
| background: #101a26 ; | |
| box-shadow: 0 0 0 4px rgba(111,184,65,.25) ; | |
| } | |
| /* Voxel tiles: deepen the inner bevel for the night palette */ | |
| .dark .gs-tile { | |
| box-shadow: inset -4px -4px 0 rgba(0,0,0,.3), inset 4px 4px 0 rgba(255,255,255,.18), 0 4px 0 rgba(0,0,0,.4); | |
| } | |
| /* "Check status" (hud) button */ | |
| .dark #gs-btn-status { | |
| background: #2a3a52 ; | |
| border-color: #0a0f17 ; | |
| box-shadow: 0 6px 0 #0a0f17 ; | |
| } | |
| .dark #gs-btn-status:active { box-shadow: 0 0 0 #0a0f17 ; } | |
| /* Dim the ground + footer at night */ | |
| .dark .gs-ground { box-shadow: inset 0 5px 0 rgba(255,255,255,.08); filter: brightness(.82); } | |
| .dark .gs-footer { filter: brightness(.82); } | |
| .gradio-container { | |
| max-width: 1180px ; | |
| margin: 0 auto ; | |
| padding: 40px 26px 0 ; | |
| background: transparent ; | |
| box-shadow: none ; | |
| } | |
| /* Hide Gradio's default footer. The svelte hash changes between versions, so | |
| target the semantic <footer> element β our custom footer is .gs-footer (a div). */ | |
| gradio-app footer, | |
| .gradio-container footer { | |
| display: none ; | |
| } | |
| /* ββ Floating voxel cubes ββ */ | |
| .cube { | |
| position: fixed; | |
| width: var(--s, 64px); | |
| height: var(--s, 64px); | |
| pointer-events: none; | |
| z-index: 0; | |
| filter: drop-shadow(0 10px 0 rgba(20,30,45,.10)); | |
| } | |
| .cube i { position: absolute; inset: 0; display: block; } | |
| .cube .top { clip-path: polygon(50% 0, 100% 25%, 50% 50%, 0 25%); } | |
| .cube .left { clip-path: polygon(0 25%, 50% 50%, 50% 100%, 0 75%); } | |
| .cube .right{ clip-path: polygon(50% 50%, 100% 25%, 100% 75%, 50% 100%); } | |
| .cube.grass .top { background: var(--grass); } | |
| .cube.grass .left { background: var(--grass-mid); } | |
| .cube.grass .right{ background: var(--grass-dark); } | |
| .cube.brick .top { background: var(--brick); } | |
| .cube.brick .left { background: var(--brick-mid); } | |
| .cube.brick .right{ background: var(--brick-dark); } | |
| .cube.dirt .top { background: var(--dirt); } | |
| .cube.dirt .left { background: #6a4828; } | |
| .cube.dirt .right{ background: var(--dirt-dark); } | |
| @keyframes bob { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-12px)} } | |
| .gs-float { animation: bob 5s ease-in-out infinite; } | |
| /* ββ Hero ββ */ | |
| .gs-hero { | |
| position: relative; | |
| border-radius: 18px; | |
| overflow: hidden; | |
| background: linear-gradient(180deg, var(--hud-2) 0%, var(--hud) 100%); | |
| border: 3px solid #0c121c; | |
| box-shadow: 0 12px 0 rgba(12,18,28,.35), 0 26px 50px -18px rgba(12,18,28,.6); | |
| padding: 46px 34px 52px; | |
| text-align: center; | |
| margin-bottom: 26px; | |
| z-index: 1; | |
| } | |
| .gs-hero::before { | |
| content: ""; | |
| position: absolute; | |
| inset: 0; | |
| background-image: | |
| linear-gradient(rgba(255,255,255,.035) 1px, transparent 1px), | |
| linear-gradient(90deg, rgba(255,255,255,.035) 1px, transparent 1px); | |
| background-size: 26px 26px; | |
| pointer-events: none; | |
| } | |
| .gs-hero::after { | |
| content: ""; | |
| position: absolute; | |
| left: 0; right: 0; bottom: 0; height: 16px; | |
| background: | |
| repeating-linear-gradient(90deg, var(--grass) 0 11px, var(--grass-mid) 11px 22px), | |
| var(--grass); | |
| box-shadow: inset 0 4px 0 rgba(255,255,255,.18), inset 0 -16px 0 var(--grass-dark); | |
| } | |
| .gs-badge { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 9px; | |
| font-family: 'Press Start 2P', monospace; | |
| font-size: 9px; | |
| letter-spacing: .5px; | |
| color: #bfe7f6; | |
| background: rgba(76,196,230,.12); | |
| border: 1px solid rgba(76,196,230,.35); | |
| padding: 7px 12px 6px; | |
| border-radius: 6px; | |
| margin-bottom: 22px; | |
| } | |
| .gs-badge .dot { | |
| width: 9px; height: 9px; | |
| background: var(--grass); | |
| box-shadow: 0 0 0 2px var(--grass-dark); | |
| display: inline-block; | |
| } | |
| .gs-title { | |
| font-family: 'Press Start 2P', monospace ; | |
| font-weight: 400; | |
| font-size: clamp(26px, 5.2vw, 52px); | |
| line-height: 1.18; | |
| letter-spacing: 1px; | |
| color: #eaf7ff; | |
| text-shadow: 0 4px 0 #0a1320, 0 5px 0 #0a1320; | |
| margin: 0; | |
| } | |
| .gs-title .g { color: var(--cyan); text-shadow: 0 4px 0 #0e3f4d, 0 5px 0 #0e3f4d; } | |
| .gs-title .orb { | |
| display: inline-block; | |
| width: .62em; height: .62em; | |
| vertical-align: .02em; | |
| margin-right: .18em; | |
| background: linear-gradient(135deg, #8fe0ff, #3aa6cf); | |
| border: 2px solid #0a2a36; | |
| box-shadow: inset -3px -3px 0 rgba(0,0,0,.2), 0 4px 0 #0a2a36; | |
| } | |
| .gs-sub { | |
| max-width: 620px; | |
| margin: 20px auto 0; | |
| font-size: 18px; | |
| line-height: 1.55; | |
| color: #aebccd; | |
| font-weight: 600; | |
| } | |
| .gs-sub b { color: #fff; font-weight: 800; } | |
| /* ββ Card shell (wraps gr.Group) ββ */ | |
| .gs-card { | |
| background: var(--paper) ; | |
| border: 3px solid var(--ink) ; | |
| border-radius: 14px ; | |
| overflow: hidden ; | |
| box-shadow: 0 8px 0 #cdd9e3, 0 22px 40px -22px rgba(20,30,45,.5) ; | |
| padding: 0 ; | |
| gap: 0 ; | |
| } | |
| .gs-card > .wrap { | |
| padding: 0 ; | |
| gap: 0 ; | |
| border: none ; | |
| } | |
| /* Card head injected via gr.HTML */ | |
| .gs-card-head { | |
| padding: 20px 22px 18px; | |
| display: flex; | |
| align-items: center; | |
| gap: 14px; | |
| border-bottom: 3px solid var(--ink); | |
| } | |
| .gs-card-head.sky { background: #e2f3fb; } | |
| .gs-card-head.brick { background: #fbeae2; } | |
| /* NB: avoid the class name `dark` here β Gradio's CSS scoper treats `.dark` as | |
| its reserved dark-mode class and hoists it to an ancestor selector. */ | |
| .gs-card-head.hud { background: #eef3f7; } | |
| .gs-card-head h2 { | |
| margin: 0; | |
| font-family: 'Baloo 2', cursive ; | |
| font-weight: 800 ; | |
| font-size: 25px ; | |
| line-height: 1.1; | |
| color: var(--ink) ; | |
| } | |
| .gs-tile { | |
| flex: 0 0 auto; | |
| width: 52px; height: 52px; | |
| border-radius: 10px; | |
| display: grid; | |
| place-items: center; | |
| font-size: 24px; | |
| border: 3px solid rgba(0,0,0,.22); | |
| box-shadow: inset -4px -4px 0 rgba(0,0,0,.18), inset 4px 4px 0 rgba(255,255,255,.28), 0 4px 0 rgba(0,0,0,.18); | |
| } | |
| .gs-tile.sky { background: var(--sky); } | |
| .gs-tile.brick { background: var(--brick); } | |
| .gs-tile.hud { background: var(--hud-2); border-color: #0c121c; } | |
| /* Card body content injected via gr.HTML */ | |
| .gs-card-body { | |
| padding: 22px 22px 0; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 14px; | |
| } | |
| .gs-lede { | |
| margin: 0; | |
| font-size: 16px; | |
| line-height: 1.55; | |
| color: var(--ink-soft); | |
| font-weight: 600; | |
| } | |
| .gs-feats { | |
| list-style: none; | |
| margin: 0; | |
| padding: 0; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 11px; | |
| } | |
| .gs-feats li { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| font-size: 15.5px; | |
| font-weight: 700; | |
| color: var(--ink); | |
| } | |
| .gs-pip { | |
| width: 14px; height: 14px; | |
| flex: 0 0 auto; | |
| background: var(--grass); | |
| border: 2px solid var(--grass-edge); | |
| box-shadow: inset -2px -2px 0 rgba(0,0,0,.18); | |
| display: inline-block; | |
| } | |
| .gs-tag { | |
| display: inline-flex; | |
| align-items: center; | |
| font-family: 'Press Start 2P', monospace; | |
| font-size: 8.5px; | |
| letter-spacing: .4px; | |
| text-transform: uppercase; | |
| color: #fff; | |
| background: var(--hud); | |
| padding: 6px 9px 5px; | |
| border-radius: 5px; | |
| box-shadow: 0 3px 0 rgba(20,30,45,.25); | |
| } | |
| .gs-tag.sky { color: #bfe7f6; } | |
| .gs-tag.green { color: #bdf09a; } | |
| /* Inner padding for Gradio components inside cards */ | |
| .gs-card-inputs { | |
| padding: 0 22px 22px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 14px; | |
| } | |
| /* Remove the white box Gradio wraps around each form element inside cards */ | |
| .gs-card .block { | |
| background: transparent ; | |
| border: none ; | |
| box-shadow: none ; | |
| padding: 0 ; | |
| } | |
| /* Name / Icon row: gap + align bottoms so different-height wrappers line up */ | |
| .gs-card-inputs .row { | |
| gap: 14px ; | |
| align-items: flex-end ; | |
| } | |
| /* Align token input and Check status button to the same baseline */ | |
| .status-row { | |
| align-items: flex-end ; | |
| gap: 14px ; | |
| } | |
| /* ββ Gradio label β pixel-art tag (applies to both Textbox and Dropdown) ββ */ | |
| .gs-card [data-testid="block-info"] { | |
| font-family: 'Press Start 2P', monospace ; | |
| font-size: 8.5px ; | |
| letter-spacing: .4px ; | |
| text-transform: uppercase ; | |
| color: #fff ; | |
| background: var(--hud) ; | |
| padding: 6px 9px 5px ; | |
| border-radius: 5px ; | |
| box-shadow: 0 3px 0 rgba(20,30,45,.25) ; | |
| display: inline-flex ; | |
| margin-bottom: 6px ; | |
| } | |
| /* ββ Form inputs ββ */ | |
| .gs-card input, | |
| .gs-card textarea { | |
| font-family: 'Nunito', sans-serif ; | |
| font-size: 16px ; | |
| font-weight: 700 ; | |
| color: var(--ink) ; | |
| background: var(--paper-2) ; | |
| border: 3px solid #cdd9e3 ; | |
| border-radius: 9px ; | |
| padding: 13px 14px ; | |
| } | |
| .gs-card input:focus, | |
| .gs-card textarea:focus { | |
| border-color: var(--grass-mid) ; | |
| background: #fff ; | |
| box-shadow: 0 0 0 4px rgba(116,192,67,.22) ; | |
| outline: none ; | |
| } | |
| /* ββ Dropdown (Icon selector) ββ */ | |
| /* The Gradio Dropdown wraps the input in .wrap and .wrap-inner; remove extra bg/padding */ | |
| .gs-card .svelte-1xfsv4t.wrap, | |
| .gs-card .svelte-1xfsv4t.wrap-inner, | |
| .gs-card .svelte-1xfsv4t.secondary-wrap { | |
| background: transparent ; | |
| padding: 0 ; | |
| border: none ; | |
| box-shadow: none ; | |
| } | |
| /* Style the dropdown input itself like other inputs */ | |
| .gs-card .svelte-1xfsv4t input[role="listbox"] { | |
| font-family: 'Nunito', sans-serif ; | |
| font-size: 16px ; | |
| font-weight: 700 ; | |
| color: var(--ink) ; | |
| background: var(--paper-2) ; | |
| border: 3px solid #cdd9e3 ; | |
| border-radius: 9px ; | |
| padding: 13px 14px ; | |
| margin: 0 ; | |
| } | |
| /* Dropdown focus β the base listbox rule above is highly specific, so it needs | |
| its own :focus variant to pick up the grass-green focus ring like text inputs. */ | |
| .gs-card .svelte-1xfsv4t input[role="listbox"]:focus { | |
| border-color: var(--grass-mid) ; | |
| background: #fff ; | |
| box-shadow: 0 0 0 4px rgba(116,192,67,.22) ; | |
| outline: none ; | |
| } | |
| /* ββ Voxel buttons ββ */ | |
| /* Gradio places elem_id directly on the <button> or <a> element */ | |
| #gs-btn-observe { | |
| font-family: 'Baloo 2', cursive ; | |
| font-weight: 800 ; | |
| font-size: 18px ; | |
| color: #fff ; | |
| background: var(--grass) ; | |
| border: 3px solid var(--grass-edge) ; | |
| border-radius: 11px ; | |
| padding: 14px 18px ; | |
| box-shadow: 0 6px 0 var(--grass-dark) ; | |
| text-shadow: 0 2px 0 rgba(0,0,0,.18) ; | |
| transition: transform .07s ease, box-shadow .07s ease, filter .12s ease ; | |
| width: 100% ; | |
| display: inline-flex ; | |
| align-items: center ; | |
| justify-content: center ; | |
| text-decoration: none ; | |
| cursor: pointer ; | |
| } | |
| #gs-btn-observe:hover { filter: brightness(1.05) ; } | |
| #gs-btn-observe:active { transform: translateY(6px) ; box-shadow: 0 0 0 var(--grass-dark) ; } | |
| #gs-btn-create { | |
| font-family: 'Baloo 2', cursive ; | |
| font-weight: 800 ; | |
| font-size: 18px ; | |
| color: #fff ; | |
| background: var(--brick) ; | |
| border: 3px solid #5e2814 ; | |
| border-radius: 11px ; | |
| padding: 14px 18px ; | |
| box-shadow: 0 6px 0 var(--brick-dark) ; | |
| text-shadow: 0 2px 0 rgba(0,0,0,.18) ; | |
| transition: transform .07s ease, box-shadow .07s ease, filter .12s ease ; | |
| width: 100% ; | |
| } | |
| #gs-btn-create:hover { filter: brightness(1.05) ; } | |
| #gs-btn-create:active { transform: translateY(6px) ; box-shadow: 0 0 0 var(--brick-dark) ; } | |
| #gs-btn-status { | |
| font-family: 'Baloo 2', cursive ; | |
| font-weight: 800 ; | |
| font-size: 18px ; | |
| color: #fff ; | |
| background: var(--hud-2) ; | |
| border: 3px solid #0c121c ; | |
| border-radius: 11px ; | |
| padding: 14px 18px ; | |
| box-shadow: 0 6px 0 #0c121c ; | |
| text-shadow: 0 2px 0 rgba(0,0,0,.18) ; | |
| transition: transform .07s ease, box-shadow .07s ease, filter .12s ease ; | |
| } | |
| #gs-btn-status:hover { filter: brightness(1.05) ; } | |
| #gs-btn-status:active { transform: translateY(6px) ; box-shadow: 0 0 0 #0c121c ; } | |
| /* ββ Ground + footer ββ */ | |
| .gs-ground { | |
| position: relative; | |
| margin-top: 54px; | |
| height: 74px; | |
| z-index: 1; | |
| background: | |
| repeating-linear-gradient(90deg, var(--grass) 0 16px, var(--grass-mid) 16px 32px) top/100% 14px no-repeat, | |
| linear-gradient(180deg, var(--grass-dark) 0 12px, var(--dirt) 12px 100%); | |
| box-shadow: inset 0 5px 0 rgba(255,255,255,.16); | |
| } | |
| .gs-footer { | |
| background: var(--dirt); | |
| padding: 18px 26px 26px; | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 8px 18px; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 14px; | |
| font-weight: 700; | |
| color: #e9d8c4; | |
| } | |
| .gs-footer a { color: #f3e6d6; text-decoration: none; opacity: .9; } | |
| .gs-footer a:hover { opacity: 1; text-decoration: underline; } | |
| .gs-footer .sep { opacity: .4; } | |