Inspiration

HackGT 13's theme is Seaside Market, and every good market has one stall with a crowd around it. I wanted to build that stall. The internet already judges everything by "aura," so I asked a dumb question: what if a mirror could look at your outfit and tell you, with total confidence, that it's worth +412,000 aura? Or -88,000?

I came in solo with an in-and-out schedule, so the original goal was simple: make something silly that people would walk up to, laugh at, and post. I'm a mechanical engineering student, so I also wanted it to be a real object you stand in front of, not just a website. That turned it into a smart mirror. Then the Meta challenge (bringing people closer together with AI) pushed it from "rate me" to "rate us," and Aura Battles became the main event.

What it does

AuraOS is a smart mirror kiosk dressed up as a retro operating system. When nobody's around, a white 3D mannequin spins on a turntable behind the glass, cycling procedurally generated outfits like a slot machine. Wave and it locks in an outfit and waves back. Hold up a double peace sign and it counts down 3-2-1, captures you, and runs the scan.

The scan detects each garment and anything you're holding, classifies your style, estimates what the fit costs, and rates cohesion and uniqueness. Two AI judges score you independently, and the mirror calls it out when they disagree. Results print line by line like a terminal, your Aura score counts up somewhere between -1,000,000 and +1,000,000, a verdict lands, and the mannequin either celebrates or collapses.

The social side is where it gets fun:

  • Aura Battles: two people double-peace at the same time and go head to head, with AI commentary on who won and why.
  • Squad mode: bring your whole group.
  • The Tide Chart: a live leaderboard for the whole hackathon, plus a public feed of recent results.
  • Mirror to phone: a QR code on every result hands your card to your phone so you can share it.
  • Mobile companion: scan from your phone, check the leaderboard, or challenge a friend with a link.
  • Extras: a voice roast, and a collectible badge minted as an NFT with no wallet required.

How we built it

Software

The kiosk is a single Next.js app (App Router, TypeScript, Tailwind, Framer Motion). The mirror and a fallback "digital mirror" mode (a flipped camera feed, in case the acrylic didn't arrive in time) share all of the same kiosk logic.

  • Mannequin: built in Three.js from primitives, with states for idle, wave, pose, celebrate, and collapse. Wave at it for more than 15 seconds and it gets tired, then annoyed, then sits down and sulks.
  • Gestures: MediaPipe Tasks Vision runs hand gesture and pose detection in the browser, so the whole experience is hands-free.
  • Scoring pipeline:
    1. A local Hugging Face segmentation model (segformer_b3_clothes) runs on my GPU in a FastAPI sidecar and returns structured garment labels.
    2. Those labels and the photo go to GPT-4o-mini with a strict JSON schema, and to Gemini in parallel as a second judge.
    3. A deterministic curve turns the judges' ratings into the final Aura score.
  • Data: Supabase for persistence and realtime leaderboard updates, with Tiger Data storing leaderboard history.
  • Sponsor integrations: ElevenLabs for the voice roast, Solana compressed NFTs (Metaplex Bubblegum) minted server-side so nobody has to connect a wallet, Vultr for hosting, and a .Tech domain.

The scoring curve was one of my favorite parts. If you ask a language model directly for a number between -1,000,000 and +1,000,000, you have no control over the distribution. So the judges only say how special the fit is and whether that's good or bad, and math picks the number:

$$ A = \sigma \cdot 10^{6} \cdot \left( \frac{s}{100} \right)^{k} $$

Here \(s\) is the specialness rating from 0 to 100, \(\sigma = \pm 1\) comes from the judges' sentiment, and the exponent \(k\) is tuned so most fits land near zero while roughly 1 in 5 swing wildly in one direction.

Hardware

  • Mirror: a 24 x 36 in, 2 mm acrylic one-way mirror, in portrait.
  • Display: a 32 in monitor in portrait on a VESA arm, sitting in the top-left corner behind the glass.
  • Frame: designed parametrically in CadQuery and printed in matte black PLA on my Bambu P1S.

A one-way mirror only lets light through where the screen behind it is bright. Everywhere else, it just reflects. So the mirror UI is pure #000000 with glowing cyan line art, and the monitor's black bezel disappears into the reflection. That meant the frame didn't need a pocket for the monitor's chin at all.

The frame is 637.6 x 942.4 mm and the P1S bed is 256 mm, so it's split into 12 pieces. Every seam gets a jigsaw dovetail plus a splice plate with 2 alignment pegs and 2 screws, and 8 of those plates also clamp the mirror. Two bars on slotted posts hold the display in place. Almost every screw threads straight into a printed pilot hole, so the whole frame only needed 4 heat-set inserts.

Challenges we ran into

Print time vs. a 34-hour hackathon. My second frame design needed 30.7 hours of printing, which is basically the entire event. I redesigned it around print speed: a slim 34 mm face only 10 mm deep, 12 parts packed onto 4 pre-arranged plates, and 0.28 mm draft layers. Version 3 came in at about 12.5 hours and 464 g of filament, around 59% less print time. I also didn't trust a single slicer's estimate, so I compared PrusaSlicer against what Bambu reported for one v2 corner (2 h 38 min) and scaled every part by the result:

$$ t_{\text{Bambu}} \approx 1.17 \times t_{\text{PrusaSlicer}} $$

Keeping a 2 mm sheet flat. A 24 x 36 in sheet of thin acrylic wants to bow, and a wavy mirror turns into a funhouse mirror. Using the splice plates as clamps holds the sheet at 8 points around the frame instead of letting it just rest in the lip.

Latency with a crowd watching. Segmentation plus two LLM judges plus commentary isn't instant, and any wait feels long when someone is standing in front of the mirror. I hid it inside the experience: the countdown, the terminal-style reveal, and the battle VS animation all play while the models work, commentary streams in token by token, battles use a single judge, and the kiosk warms up its API connections on boot.

Scope creep as a team of one. This started as "one silly app" and turned into a platform with battles, squads, a feed, a phone companion, and sponsor integrations. With an unpredictable schedule, I kept a staged build list with a cut order, committed after every stage so there was always a working demo, and made every extra fail safely. For example, if the NFT mint fails, your share card still works.

Localhost isn't shareable. Result cards were useless to anyone else while the kiosk ran on localhost, which is what pushed hosting and the mobile companion up the priority list.

Two machines, two GPUs. I developed on a desktop and ran the kiosk on a laptop with a different NVIDIA GPU. Git moves the code, but not the Python environment, the API keys, or the downloaded model weights, so setting up the kiosk laptop was its own checklist.

Accomplishments that we're proud of

  • Building all of it solo. CAD, printing, a 3D kiosk, an ML pipeline, social features, and sponsor integrations, by one person with an in-and-out weekend schedule.
  • The mirror illusion works. A glowing mannequin and terminal text floating inside your own reflection is exactly the effect I was going for, and it only works because the software and the hardware were designed around each other.
  • Cutting the frame's print time by more than half so a 24 x 36 in frame could come off a 256 mm printer bed within the event, without giving up the dovetail joints.
  • A completely hands-free kiosk. Visitors never touch a keyboard or a screen. Every interaction is a wave, a peace sign, or a thumbs up.
  • A hybrid local and cloud ML pipeline, with a GPU model grounding two LLM judges and a scoring curve that I control instead of the model.
  • Nothing takes the demo down. Between the digital mirror fallback, staged commits, and extras that fail silently, there was always a working version on the table.

What we learned

  • One-way mirrors are a contrast problem. Design for black first, because anything that isn't bright disappears.
  • Specialized and general models work best together. The segmentation model grounds the judges in what's actually in the photo, and the LLMs bring the judgment and the jokes.
  • Let the model judge and let math decide the number. LLMs are great at vibes and bad at distributions.
  • Print time is a design constraint, just like strength or fit. The deadline changed nearly every dimension of the frame, and checking one slicer's estimate against another before trusting it kept my schedule honest.
  • Local GPU inference: installing CUDA builds of PyTorch, running a model as a FastAPI sidecar, and keeping it all in sync across two machines.
  • Working with AI coding agents: I planned in detail and delegated a lot of implementation to Claude Code. The prompts that worked best made the agent read the repo, report back, and ask me questions before changing anything.

What's next for AuraOS

  • Pose scoring in battles: a lightweight classifier on MediaPipe body landmarks, so your pose counts alongside your fit.
  • Event mode: let any hackathon, club, or party spin up its own mirror with its own leaderboard and feed.
  • Open-sourcing the frame: the CadQuery model is parametric, so anyone could regenerate it for their own mirror and monitor sizes and print it on a standard bed.
  • Faster scans: move more of the pipeline onto the local GPU to shrink the wait between the peace sign and the verdict.
  • Sharper detection: better handling of accessories, shoes, and layered outfits, so the judges have even more to roast. ## How we built it

Built With

  • claude
Share this project:

Updates

Submission history