Author: Adam

  • Grim Choices Mailing List Is Live

    Grim Choices Mailing List Is Live

    This week has been an interesting one, and it’s only day three! (Monday was a holiday, and it doesn’t count)

    TL;DR:Grim Choices waiting list sign-up is live

    First I got sidetracked and published the CSS library I’ve been working on behind the scenes. I was away for the weekend and realized I couldn’t use it from my laptop while it was still trapped on my desktop computer at home. If you missed it, it dynamically generates themes using oklch and the new CSS relative colors. You can read more about it here: I finally built the CSS library I’ve been wanting.

    Beyond that distraction, I’ve been quietly working on a project I’ve wanted for almost a decade, and have been debating whether it’s in good enough shape to ask NLNet for a grant so I can dedicate some serious time to it. But… I’ve still been referring to it as Federate the Masses, and with a working title that cringe, maybe it’s not ready yet. Or maybe it’s just impostor syndrome; it’s hard to say.

    Meanwhile, I’ve been making steady progress toward the MVP of Grim Choices. Most of the work so far isn’t ready for the spotlight, but I had been meaning to set up a sign-up page for the waiting list. I originally planned to use WordPress for SEO reasons — but man, I really don’t like working with WordPress. Once I realized I could get server-side rendering working in SolidStart after reworking some of the authentication logic, I decided to ditch WordPress entirely. And now the new site is live!

    If you’re curious about Grim Choices, excited to use it when we launch, or just want to follow along, sign up for the mailing list. We’ve got some good stuff coming.

    And keep an eye out for more of Remy — I think he’s got a lot to share.

  • I Finally Built the CSS Framework I Wanted

    I Finally Built the CSS Framework I Wanted

    I’ve been using Pico.css for years on a lot of projects. Liveframe.app is even built with it. But I’ve had to hack on it quite a bit to get adjustable per-user theming, and it ends up being kind of heavy when you include all the colors. I wanted something a little more dynamic, and I’ve finally built it.

    It’s called @sparkstone/css, and it’s built for people like me: folks who want semantic HTML, zero bloat, and a color system that actually makes sense when you start tweaking things.

    This isn’t meant to compete with the big players. It’s not Tailwind. It’s not Bootstrap. It’s what I needed, and maybe you do too.

    Why I Love Pico.css (And What I Needed More Of)

    I’ve used Pico on a dozen projects. I love the simplicity of it, and how you can just start building things and rarely even need to reach for classes to adjust stuff. Honestly, I tried just making a fork of it to start with, Pico has almost everything I want. But over time, I kept running into the same issues:

    • Wanting to use a specific color palette for special cases
    • Wanting to be able to let the user choose their own theming
    • Wishing I could just swap a base color and have everything update beautifully
    • Needing a few more classes… but not that many

    So after I realized that hacking on Pico was going to be harder than starting from a new foundation, I started designing.


    Enter @sparkstone/css

    This project is heavily inspired by Pico, but rebuilt from scratch around oklch(). If you’ve ever struggled to tune your colors across light and dark mode, or wanted a theme system that actually reflects your palette’s structure—you’ll get why this matters. After I got the color system working, I built a page and put it side by side with Pico to get it close—like I said, I still love Pico.

    Here’s how it works:

    /* these are the defaults */
    :root {
      --color: rebeccapurple;
      --primary-color: blue;
      --accent-color: oklch(from var(--color) l c calc(h + 180));
      --error-color: maroon;
    }

    That’s it. The rest cascades from there. Text colors, surface backgrounds, borders, shadows. All tuned based on perceptual lightness and chroma. You don’t need to invent a palette. You just pick a color, and everything adjusts accordingly.


    What You Get

    • ✨ Light/dark mode that works by default (system-aware, but overrideable)
    • ✨ Minimal classes (.card, .secondary, .ghost, etc.) when you need them (largely Pico-compatible)
    • ✨ Fully native HTML elements styled with care: forms, dialogs, buttons, etc.
    • ✨ A Sass layer with functions for color derivation (but you don’t need it)

    There’s no runtime. No JS required for the styles. Just smart CSS.


    Try It Live

    I put together a docs site using the framework itself:

    🧪 sparkstonepdx.github.io/css/docs

    Everything is copyable and live-styled with your chosen theme.


    Install It

    pnpm add @sparkstone/css

    Then import it however you like:

    // scss (for full control)
    import '@sparkstone/css/src/theme.scss';
    
    // or plain css
    import '@sparkstone/css/theme.css';

    I Made This For Me (But It’s for all of us)

    I’ve spent years building local-first, minimal, durable tools, after outgrowing a decade of chasing the new shiny. Always reaching for libraries that almost worked the way I wanted. This one finally does.

    If you’re like me, and you want your CSS to feel like it’s helping, and not just there, I think you might like it too.

    I’d love to know what you make with it.

    — Adam
    Founder @ Sparkstone

  • North Tabor Yard Sale Map

    North Tabor Yard Sale Map

    How we mapped 32 sales, drew over 3 thousand visitors, and helped a community plant sale sell out before noon

    In Spring 2025, my wife and I organized North Tabor’s first-ever neighborhood-wide yard sale. As co-chair of the neighborhood association, I wanted to make it easy for residents to participate and for visitors to explore without friction. Without apps or accounts, just a smooth experience.

    I built a real-time interactive map, integrated directly into the neighborhood website. Residents submitted their sale details through a Google Form, which updated a connected Google Sheet. A frontend built with Leaflet.js used the Google Sheets API to display the data on a live, zoomable map using OpenStreetMap tiles.

    A folding sign that has an owl on it and it says give a hoot to vintage and resell.
    Give a Hoot! The Vintage & Resale sign in front of How Convenient

    On the day of the sale, the response was overwhelming: more than 3,000 people used the map in a single day. Many participants sold out of items by early afternoon, some even before noon.

    While preparing the map, we noticed signs for the Rainbow Garden Plant Sale, an independent event happening the same day. Without formally reaching out, we added their location to the map. They later told us they had a line around the block and sold out of plants within an hour. In hindsight, we probably should have asked permission, but we were happy to help spotlight another local effort.

    In all, 32 homes took part. We distributed over 50 flyers around the neighborhood ahead of the event. The day before, we personally visited each seller to deliver a thank-you note, a QR code sign linking to the live map, and a few basic supplies to help them get set up. These small details helped unify the experience and showed that the event was both coordinated and cared for.

    The project was also mentioned in the Southeast Examiner, which brought broader visibility to the neighborhood and inspired ideas for future events.

    With the event behind us, one clear lesson emerged: we need to better communicate how participants can remove or update their listing in case of emergencies or last-minute cancellations. A few sellers had unexpected conflicts, and clearer instructions would have made it easier to keep the map accurate and avoid visitor confusion.

    This wasn’t about flashy tech. It was about thoughtful coordination and the right tool at the right moment. A live map, a few hundred lines of code, and some walking shoes made a big difference.

    Images shared to the Tabor Neighbor Yard sale Liveframe Event

  • pocketbase-schema

    Type-safe PocketBase development — automatically.

    pocketbase-schema is a utility that generates TypeScript types from your PocketBase collections. It’s built for developers who want safety, clarity, and DX improvements when building apps on top of PocketBase.


    Features

    • Automatic Type Generation: Pull your PocketBase schema and generate complete TypeScript definitions for collections and records.
    • Collections Enum: Access collection names as constants instead of raw strings.
    • Field Type Enums: Automatically generate enums for select field options.
    • Flexible CLI & API: Run it as a script or import it into your toolchain. It supports both approaches cleanly.
    • Local-First Config: Uses cosmiconfig so you can configure it with pocketbase-schema.config.js, package.json, or a custom location.

    Installation

    npm install @sparkstone/pocketbase-schema --save-dev

    or

    pnpm add @sparkstone/pocketbase-schema --save-dev

    Usage

    Once installed, run the CLI to generate types from your schema export:

    pocketbase-schema generate --input=pb_schema.json --output=src/lib/pb-types.ts

    You can also run it programmatically in a Node script:

    import { generate } from '@sparkstone/pocketbase-schema';
    
    generate({
      input: './pb_schema.json',
      output: './src/lib/pb-types.ts',
    });
    

    “We built pocketbase-schema because we love PocketBase — and we wanted full type safety without manual copy-pasting.”
    — The Sparkstone Team

    View source

  • version-json

    Effortless versioning for your JSON payloads.

    version-json is a lightweight utility designed to help developers manage and upgrade long-lived JSON data structures seamlessly. By defining transformation functions for each version, it ensures your data remains consistent and up-to-date across different versions.


    What It Does

    • Version-Aware Transformations: Define a series of transformations that upgrade your JSON payloads from one version to the next, ensuring compatibility and consistency.
    • Flexible Version Detection: Utilize a specific version field or implement a custom function to determine the version of your data, providing adaptability to various data structures.
    • Simple Integration: With an intuitive API, integrating version-json into your project is straightforward, allowing you to focus on building features rather than handling data migrations.

    “We created version-json to simplify the process of managing evolving JSON data structures, making data migrations effortless and reliable.”
    — The Sparkstone Team

    View source

  • Solid Forms

    Solid Forms

    Simple, Shareable Forms Built for Real People

    Sometimes you just need to ask a question and get clear answers — without bloated dashboards, account juggling, or privacy compromises. That’s why we built Solid Forms.

    Whether you’re collecting signups, gathering feedback, or running a workshop, Solid Forms helps you create clean, reliable forms in minutes.

    The Problem: Complex Tools for Simple Tasks

    Most form builders pack in features you don’t need, inject trackers by default, or create a maze of permissions and settings just to get started. If you’re looking for something straightforward, that can feel like overkill.

    The Solution: Solid Forms

    Solid Forms focuses on doing the basics well. You create an account, build your form with a simple, dark-mode editor, and share it using a unique link.

    Add text fields, checkboxes, dropdowns, number inputs, and rich text sections. Whatever you need to get clear responses. When people fill it out, their answers appear instantly in a clean, sortable table you can export at any time.

    There’s no publish step, no complex visibility settings. Just build, share the link, and you’re good to go.

    Who It’s For

    • Builders and small teams who need feedback fast
    • Teachers and coaches gathering input or reflections
    • Workshop hosts managing signups and RSVPs
    • Anyone tired of bloated form tools and overcomplicated platforms

    Privacy First

    Respondents don’t need accounts to reply. Solid Forms doesn’t track them, inject analytics, or set cookies. Responses are stored securely and stay private.

    Try It Now

    Get started at solidforms.app. It’s fast, focused, and designed to respect your time and your audience.

    Have questions or want help setting up your first form? We’re happy to walk you through it.

  • Liveframe

    Liveframe

    Real-Time Engagement That Brings the Room to Life

    When you’re in front of a crowd — whether it’s a classroom, a conference, or a casual meetup — you can feel when the energy is right. You can also tell when it’s drifting. That’s what led to the creation of Liveframe: a tool that helps presenters and organizers stay connected with their audience through real-time participation.

    The Challenge: Passive Audiences

    Many events rely on outdated or clunky engagement tools. App installs, logins, and complex setups slow things down and limit who can join in. The result is a missed opportunity to tap into the energy already present in the room.

    The Response: Liveframe

    Liveframe opens the door to instant interaction. Audience members scan a QR code and start contributing right away.

    They can post messages or photos to a live message wall, giving everyone a voice and turning the screen into a reflection of the crowd. When structure is needed, facilitators can switch into a controlled mode to guide the flow. Polls with timed deadlines keep the audience involved and provide live feedback.

    At one local community event, the tool transformed a 20-minute break into a burst of shared jokes, spontaneous photos, and crowd chatter. When the next speaker stepped up, the audience was already re-engaged and ready to go.

    Who It’s For

    • Event organizers looking for authentic interaction
    • Teachers and workshop leaders who want live participation
    • Meetup hosts hoping to energize the room
    • Conference facilitators managing Q&A and polling

    Why It Works

    Liveframe runs smoothly in any setting. There’s nothing to install, and participants don’t need accounts. It’s designed to be quick, lightweight, and easy to use on the spot.

    Try It Out

    Liveframe is live and free at liveframe.app. You can launch a session right away and see how it works in your space.

    If you’d like help setting it up or want a quick walkthrough, we’re happy to show you around. Just reach out.

  • Arcanetable

    Arcanetable

    The virtual table for paper Magic players who miss the real thing.

    ArcaneTable is a browser-based 3D sandbox for building decks, playtesting ideas, and jamming games — just like you used to around a kitchen table. No accounts. No installs. Just your deck, a friend, and the virtual table.


    Built for the Brew

    • Designed for Playtesting: Run games, test openings, goldfish lines, and swap decks in seconds. It’s everything you need to sharpen your strategy — minus the shuffling.
    • Supports Real Deck Lists: Paste a deck list in any major format — EDH, Modern, Cube, you name it — and ArcaneTable pulls card data directly from Scryfall. No setup required.
    • Real-Time Tabletop Feel: Cards move, stack, rotate, and flip just like they would in person. Built in WebGL with smooth, intuitive controls.
    • Peer-to-Peer Multiplayer: Send a link, and a friend can join instantly. No servers, no accounts — just P2P magic through WebRTC.

    “ArcaneTable was made for those of us who miss the late-night brew sessions — building decks with friends, testing janky combos, and chasing that perfect curve.”
    — The Sparkstone Team

    Play now View source Join the Discord

  • id-order-spacing

    Fast, precise ordering for sortable lists.

    id-order-spacing is a small utility for maintaining a stable order field in databases — built for apps where items need to be manually sorted, rearranged, or ranked. Loosely inspired by Jira’s LexoRank system, it lets you insert items between others without reindexing the entire list.


    What It Does

    • Stable Ordering via Spaced Values: Instead of using integers (1, 2, 3...), id-order-spacing generates order values like 100, 200, 150, etc. — making it easy to insert new items between existing ones without shifting everything.
    • Drop-In Reordering Logic: Handles edge cases like items moving to the start or end, gaps that are too tight, and optional re-spacing when needed.
    • Designed for Real-World UIs: Perfect for drag-and-drop lists, kanban boards, ranked queues, and any interface where users need to control the position of items.
    • Works with Any Backend: Store order as a number or string in your database. Use it in SQL, NoSQL, Firebase, or wherever your data lives.

    “We built this because we wanted simple, robust ordering logic that just works — without needing to constantly reshuffle rows in the database.”
    — The Sparkstone Team

    View source

  • solid-validation

    solid-validation

    Lightweight, flexible form validation for Solid.js.

    solid-validation is a validation library built for Solid.js. It offers a clean, reactive API for handling form input validation, submission state, and error messaging — with support for custom logic and backend integration. It’s fast, ergonomic, and integrates seamlessly with real-world workflows.


    Installation

    npm install @sparkstone/solid-validation

    or

    pnpm add @sparkstone/solid-validation

    Features

    • Simple form handling: Hook into form submission and manage input-level and global errors with built-in helpers.
    • Reactive state: Track isSubmitting, isSubmitted, and live validation errors as part of your UI.
    • Custom validators: Use your own validation functions alongside native input validation.
    • PocketBase support: Includes helpers to integrate with PocketBase forms and handle server-side validation errors cleanly.

    “We made solid-validation to give Solid.js devs a simple, ergonomic way to handle forms — no dependencies, no fuss.”
    — The Sparkstone Team


    View source