ugly // tool

// sample readme

See what ships with every purchase.

This is the README — the same file you get inside the download zip. We've filled in placeholder values (PlantSpotter, After Hours) so it reads concretely. Yours arrives with your tool's name and the look you bought in those same spots.

After Hours

A custom theme for PlantSpotter, from uglytool.dev.

Three files in this zip:

  • plantspotter-afterhours/custom.css — the drop-in theme for Gradio and Streamlit. Path A. Same file ships to every After Hours buyer; nothing specific to your tool is in it.
  • plantspotter-afterhours/index.html — the full standalone wrapper, with your tool's name and field labels already baked in. Path B. Your tool is in this file; it's ready to host.
  • plantspotter-afterhours/README.md — this file.

You own both artifacts. Use them on as many tools as you want, forever.


Before you drop this in

Back up the project you're dropping this into. A clean commit, a zipped copy — whatever gets you an unambiguous way back if something breaks mid-integration.

Look. We don't know what level of ninja coding skills you have, and we don't want to. Your tool runs your tool's code. These files are visual layers, not new apps. How you drop either one in is yours to decide. If your tool breaks after you integrate, that's yours to untangle. The If you get stuck section at the bottom is our best shot at helping from here.


What you bought, really

A look. A look is a visual grammar: color tokens, typography, button style, spacing, component treatment — After Hours, in this case. What it doesn't include: any code that runs your model, any backend, any logic. That stays yours.

We gave you two ways to apply the look:

  • Path A — drop our CSS into your existing Gradio or Streamlit app. Your tool stays where it is, just wearing our clothes. Three lines of Python, five minutes.
  • Path B — use our full HTML as a standalone branded frontend. More setup, more polished result. Good when you want a landing page, not just a restyled Space.

A is the quick fix. B is the full thing. You can do both — A on your HF Space, B as a separate landing page that links to it.


Two things this isn't

  • Not a new app. Your model, your backend, your logic — all stays yours. These files sit in front.
  • Not a framework. No SDK, no build step, no dependency. Two files.
  • Not a contract. The button says "Run" because that's After Hours's voice. Your tool's name, description, and labels come through verbatim; the ornamental copy comes from us. Want to change a word? Open the file and change it. You own it.

Path A — drop our CSS into your Gradio or Streamlit app

Fastest path. Your existing tool stays put; it just looks like After Hours from now on. No coding required — just copy, paste, commit.

If you're on Hugging Face Spaces (Gradio)

Step 1 — Upload the CSS file to your Space.

On your Space's page on Hugging Face, click the Files tab near the top. Use the upload interface (there's a + or Upload button depending on your UI) to drag custom.css in. Write any commit message ("Add theme" works). Commit it to the main branch.

Step 2 — Open your Python file for editing.

Still in the Files tab, click on app.py (most Gradio Spaces use that filename). Then click the pencil icon in the top-right corner to edit it.

Step 3 — Find the gr.Blocks line.

Scroll through your file — you're looking for a line that looks roughly like this:

with gr.Blocks() as app:

It's usually near the bottom of the file. Your version might say demo, interface, or some other word instead of app — that doesn't matter. The part we care about is gr.Blocks(...).

Step 4 — Paste in two things.

A few lines above your with gr.Blocks(...) line, paste this:

with open("custom.css") as f:
    custom_css = f.read()

(Plain English: this tells Python to open your custom.css file and remember what's inside it.)

Then, on your existing gr.Blocks(...) line, add css=custom_css inside the parentheses:

# before
with gr.Blocks() as app:

# after
with gr.Blocks(css=custom_css) as app:

If the parentheses already have other things in them (like theme=gr.themes.Base()), leave those alone. Just add css=custom_css alongside them, separated by a comma.

Step 5 — Commit and wait.

Scroll down past the code. Write a commit message ("Apply After Hours theme" works). Click Commit changes directly to the main branch. Your Space will rebuild on its own — usually under a minute. Refresh the page and it wears After Hours.

What to expect:

Gradio renders its own frontend. Our CSS overrides how that frontend looks — background, fonts, colors, buttons, input fields. You'll see most of the visual transformation, but not a 100% pixel-perfect match with the preview you saw on our site, because Gradio's layout stays Gradio's. If you want the full visual match, use Path B.


If you're on Streamlit

Streamlit doesn't run on Hugging Face by default — most Streamlit apps live on Streamlit Community Cloud, Render, or your own server. Wherever yours lives:

Step 1 — Put custom.css in the same folder as your Streamlit Python file.

Step 2 — Add three lines at the top of your Streamlit file (usually called streamlit_app.py or app.py), right below wherever you import streamlit as st:

from pathlib import Path

with open(Path(__file__).parent / "custom.css") as f:
    st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)

(Plain English: the Path(__file__).parent / "custom.css" part reads as: "the folder where this script lives, then custom.css inside that folder." It tells Python to look right next to your script — which works no matter where Streamlit was launched from. The unsafe_allow_html=True bit looks alarming but it just tells Streamlit to actually render the style tag instead of showing it as text.)

Step 3 — Save and reload your app. Done.


If you have something else (Flask, FastAPI, a plain website)

The CSS file is just a CSS file. Drop it wherever you keep your stylesheets. Add <link rel="stylesheet" href="/custom.css"> to your HTML. Done.


Making it yours

Open custom.css in any text editor — it's just a text file, you can open it in Notepad, TextEdit, VS Code, anything. The top has a short comment. Below that, every style is yours to tweak — change the accent color, swap the font, remove the external fonts import if you want something else. No magic, no compilation, no tools required.


Path B — the full standalone wrapper

A branded landing page for your tool, not just a restyled Space. The HTML is yours to host wherever; it's what your users see before they interact with your tool.

Where to host it

Any static host works. These three have generous free tiers:

  • GitHub Pages — simplest. New repo, upload index.html at the root, enable Pages in repo settings. Live at yourname.github.io/reponame in five minutes.
  • Vercel — drag-and-drop. *.vercel.app URL instantly.
  • Netlify — same shape as Vercel, drag-and-drop.

Connecting it to your backend

The HTML has buttons and fields, but clicking them doesn't send anything yet — we don't know where your model lives, so we left that empty. Inside index.html, the <script> block at the bottom has comments showing where to wire in your backend. Common patterns:

  • Gradio Space backend: your HTML calls your Space's public API. The <script> block has a Gradio JS client example.
  • Streamlit: Streamlit doesn't expose a native API, so you typically bolt on a small FastAPI endpoint alongside it, then call that.
  • Flask / FastAPI / Node / anything else: serve the HTML as a template or static page, handle form submissions with your existing backend code.

If you get stuck

Throw this README plus one of the files at whichever LLM you're already talking to. They know your framework better than we do — we just stop things from being ugly. Try:

"I have this HTML template and this CSS file. How do I use them as the frontend for my Gradio / Streamlit / Flask app?"

That prompt usually unsticks things in one turn.

If the LLM can't help and you think it's our bug (malformed file, missing field label, CSS not applying at all): hi@uglytool.dev.


License & no warranty

Both files are yours. Use them however. Embed them, rebrand them, rewrite them, hand them to a friend. No attribution required — the small "built with uglytool.dev" footer credit on the HTML is optional and removable.

Provided as-is, without warranty of any kind. How you integrate these files into your project is your decision. uglytool is not responsible for breakage, data loss, downtime, or any other consequence of how you use them.

Ready to see your tool?

Preview your tool in all three finished looks. Buy the one that fits.

Preview my tool →