Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Columbia Gadget Works website

Source for <https://columbiagadgetworks.org>. Built with [Hugo](https://gohugo.io) (no external theme; layouts live in `layouts/`), hosted on Cloudflare Pages.
Source for <https://columbiagadgetworks.org>. Built with [Hugo](https://gohugo.io) (no external theme; layouts live in `layouts/`), deployed as a Cloudflare Worker with static assets.

## Editing content

Expand All @@ -9,10 +9,11 @@ Everything a volunteer normally touches is a Markdown or YAML file:
| What | Where |
|---|---|
| Pages (Visit, About, Donate, …) | `content/<page>.md` |
| News posts | `content/news/<slug>.md` — copy an existing one; set `date`, `title`, optional `image` |
| Tool pages | `content/tools/<tool>.md` — front matter holds specs, training flag, wiki link |
| Events calendar | `data/events.yaml` — `recurring` always shows; `upcoming` items disappear after their date |
| Photos | `assets/img/` — drop in a JPG/PNG (long edge ≤ 1600 px is plenty); reference by filename |
| News posts | `content/news/<slug>.md` (copy an existing one; set `date`, `title`, optional `image`) |
| Tool pages | `content/tools/<tool>.md` (front matter holds specs, training flag, wiki link) |
| Events calendar | `data/events.yaml` (`recurring` always shows; `upcoming` items disappear after their date) |
| Photos | `assets/img/` (drop in a JPG/PNG, long edge 1600 px or less; reference by filename) |
| Video | `static/video/` (MP4 muxed with `-movflags +faststart`; embed with the `video` shortcode) |
| Contact info, links, EIN, Givebutter IDs | `hugo.toml` under `[params]` |
| Menu | `hugo.toml` under `[menus]` |

Expand All @@ -39,17 +40,35 @@ The site deploys as a Cloudflare Worker: Hugo's `public/` folder is served as st
- Deploy command: `npx wrangler deploy`
- Hugo comes from the `hugo-extended` npm package pinned in `package.json`, so no `HUGO_VERSION` variable is needed
3. Secrets (Settings → Variables and Secrets, type *Secret*):
- `DISCORD_WEBHOOK_URL` — webhook for the contact form channel (see `src/contact.js`)
- `TURNSTILE_SECRET` (optional) — add only **after** `turnstileSiteKey` in `hugo.toml` has deployed
- `DISCORD_WEBHOOK_URL`, webhook for the contact form channel (see `src/contact.js`)
- `TURNSTILE_SECRET` (optional), add only **after** `turnstileSiteKey` in `hugo.toml` has deployed
4. Custom domain: Settings → Domains & Routes → add `columbiagadgetworks.org` and `www` (the zone must be in the same account).
5. `static/_redirects` maps the old WordPress URLs; `static/_headers` sets caching and security headers. Both are honored by Workers static assets.

Manual deploy from a machine with Wrangler logged in: `npm run deploy`.

## Video

Drop an MP4 in `static/video/` and a poster still in `assets/img/`, then:

```
{{</* video src="/video/thing.mp4" poster="thing.jpg" caption="What is happening." */>}}
```

Nothing loads until the visitor presses play (`preload="none"`), and the poster reserves the
layout box. Re-mux phone footage with `ffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4`.

## Spam protection (Turnstile)

The contact form uses Turnstile when configured. **Set both halves or neither:**
`params.turnstileSiteKey` in `hugo.toml`, and `TURNSTILE_SECRET` as a Worker secret.
If the secret is set but the site key has not deployed, the form renders no widget, sends no
token, and every submission is rejected. Deploy the site key first.

## After launch checklist

- Google Search Console: verify the domain, submit `/sitemap.xml`.
- Givebutter: fix the org profile URL to `https://`, create a **widget** for the donation campaign and paste its ID into `givebutterWidgetId`.
- Givebutter: fix the org profile URL to `https://`. (The donation widget is configured.)
- Update `data/events.yaml` whenever a class is scheduled.

## License
Expand Down
38 changes: 27 additions & 11 deletions assets/css/site.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Columbia Gadget Works — site styles. Brand color comes from hugo.toml. */
/* Columbia Gadget Works site styles. Brand color comes from hugo.toml. */
:root{
--rust:{{ site.Params.brandColor }};
--rust-dark:#983C1E;
Expand All @@ -12,8 +12,10 @@
--line:#E5DED4;
--ok:#2F7A4B;
--warn:#9C6A00;
--font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
--mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
/* Ordinary, ubiquitous faces. Nothing is downloaded, so text paints on the
first frame and there is no layout shift when a webfont arrives. */
--font:Arial,"Helvetica Neue",Helvetica,sans-serif;
--mono:Consolas,"DejaVu Sans Mono","Courier New",monospace;
--wrap:1120px;
--r:10px;
}
Expand All @@ -23,8 +25,8 @@ body{margin:0;font-family:var(--font);font-size:17px;line-height:1.6;color:var(-
img{max-width:100%;height:auto;display:block}
a{color:var(--rust-dark);text-decoration-thickness:1px;text-underline-offset:2px}
a:hover{color:var(--rust)}
h1,h2,h3,h4{line-height:1.15;letter-spacing:-.01em;margin:0 0 .5em;font-weight:800}
h1{font-size:clamp(2rem,4.5vw,3.2rem)}
h1,h2,h3,h4{line-height:1.18;letter-spacing:-.005em;margin:0 0 .5em;font-weight:700}
h1{font-size:clamp(1.9rem,4.2vw,3rem)}
h2{font-size:clamp(1.5rem,2.6vw,2rem)}
h3{font-size:1.2rem}
p{margin:0 0 1em}
Expand All @@ -40,14 +42,15 @@ ul.plain{list-style:none;padding:0;margin:0}
ul.plain li{margin:0 0 .35em}

/* Buttons */
.btn{display:inline-block;padding:.6em 1.15em;border-radius:8px;font-weight:700;text-decoration:none;border:2px solid transparent;line-height:1.2;cursor:pointer;font-family:inherit;font-size:1rem}
.btn{display:inline-block;padding:.62em 1.2em;border-radius:3px;font-weight:700;text-decoration:none;border:2px solid transparent;line-height:1.2;cursor:pointer;font-family:inherit;font-size:1rem;transition:background .12s ease,border-color .12s ease,transform .06s ease}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--rust);color:#fff;border-color:var(--rust)}
.btn-primary:hover{background:var(--rust-dark);border-color:var(--rust-dark);color:#fff}
.btn-light{background:#fff;color:var(--ink);border-color:#fff}
.btn-light:hover{background:var(--paper);color:var(--rust-dark)}
.btn-light{background:#fff;color:var(--ink);border-color:var(--ink)}
.btn-light:hover{background:var(--ink);color:#fff}
.btn-outline{background:transparent;color:var(--rust-dark);border-color:var(--rust)}
.btn-outline:hover{background:var(--rust-tint)}
.btn-lg{padding:.8em 1.4em;font-size:1.08rem}
.btn-lg{padding:.78em 1.5em;font-size:1.06rem}

/* Header */
.site-header{background:#fff;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:50}
Expand Down Expand Up @@ -84,7 +87,7 @@ ul.plain li{margin:0 0 .35em}
.lead{font-size:1.2rem;max-width:62ch;color:inherit}
.hero .lead{color:#E7E3DC}
.hero-cta{display:flex;flex-wrap:wrap;gap:12px;margin:24px 0 20px}
.hack-chip{display:inline-block;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.2);padding:.5em .9em;border-radius:999px;font-size:.95rem;margin:0}
.hack-chip{display:inline-block;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.18);border-left:3px solid var(--rust);padding:.5em .9em;border-radius:2px;font-size:.95rem;margin:0}

/* Cards / grids */
.three-up{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:20px}
Expand Down Expand Up @@ -136,6 +139,10 @@ ul.plain li{margin:0 0 .35em}
.page-hero{margin:0 0 32px}
.page-hero img{border-radius:var(--r);width:100%}
.prose{max-width:72ch}
/* Pages that lay out in columns opt out of the reading measure, so a two-column
block fills the 1120px wrap instead of being squeezed into 72ch. */
.prose-wide{max-width:none}
.prose-wide>.two-col>div>:first-child{margin-top:0}
.prose h2{margin-top:1.6em;padding-top:.2em}
.prose h3{margin-top:1.3em}
.prose ul,.prose ol{padding-left:1.3em}
Expand Down Expand Up @@ -215,5 +222,14 @@ ul.plain li{margin:0 0 .35em}
.site-footer address{font-style:normal;line-height:1.7}
.hack-night{background:rgba(255,255,255,.06);border-radius:8px;padding:10px 12px;display:inline-block}
.footer-bottom{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px;border-top:1px solid rgba(255,255,255,.12);margin-top:36px;padding-top:16px;font-size:.85rem;color:#A9A39B}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
/* Video. Self-hosted, no third-party player, dimensions reserved to avoid layout shift. */
.video-figure{margin:1.6em 0}
.video-figure video{display:block;width:100%;height:auto;aspect-ratio:16/9;background:#14181c;border-radius:var(--r)}
.video-figure figcaption{margin-top:.55em;font-size:.9rem;color:var(--muted)}
.prose .video-figure{margin-left:0;margin-right:0}
.two-col.feature{align-items:center}
.two-col.feature h2{margin-top:0}

@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}
.btn{transition:none}}
@media print{.site-header,.site-footer,.hero-media{display:none}}
Binary file added assets/img/battlebots-arena.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion content/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Columbia Gadget Works is a **membership organization**. Every member in good sta

The shop itself is divided into **zones**: woodworking, metalworking, digital fabrication (laser, CNC, 3D printing), electronics, and casting. Each zone is run by a volunteer "zone lead" who sets it up, keeps it safe, and decides what training its tools require. Other volunteers take on functions like membership, classes, facilities, and communications.

Decisions are written down on our member wiki. If it isn't on the wiki, it isn't policy.
Decisions are written down on our [member wiki](https://wiki.comogadget.casa/). If it isn't on the wiki, it isn't policy.

### Board of directors

Expand Down
18 changes: 8 additions & 10 deletions content/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,28 @@ description: "Free and low-cost maker classes in Columbia, MO: soldering, metal

## Open Hack Night is the first class

Every Thursday from 6 to 8 pm the shop is open to everyone. It isn't a formal class, but it's where most learning at CGW actually happens: a member shows you how the laser works, someone walks you through your first 3D print, a machinist explains what you did wrong on the lathe. If you want to learn something specific, say so when you arrive. [Plan a visit →](/visit/)
Every Thursday from 6 to 8 pm the shop is open to everyone. It isn't a formal class, but it's where most learning at CGW actually happens: a member shows you how the laser works, someone walks you through your first 3D print, a machinist explains what you did wrong on the lathe. If you want to learn something specific, say so when you arrive. [Plan a visit](/visit/)

## Scheduled classes

Members run classes roughly monthly, usually on a Thursday at 6 pm in place of the normal open night. Recent ones:

- **Metal casting** – make a plaster mold from a 3D-printed part and pour it in aluminum, zinc, or pewter with the shop's casting setup. [Recap →](/news/metal-casting-class-recap/)
- **Soldering** – hand soldering and reflow/surface-mount techniques, with kits to take home. [Announcement →](/news/soldering-class-and-art-in-the-park/)
- **Machining** – the manual milling machine and metal lathe, from reading the dials to taking a real cut. [Recap →](/news/metalworking-class/)
- **Field trips** – like our tour of KOPN community radio's studios and transmitter equipment. [Details →](/news/kopn-tour-april-23/)
- **Metal casting:** make a plaster mold from a 3D-printed part and pour it in aluminum with the shop's casting setup. [Recap](/news/metal-casting-class-recap/)
- **Soldering:** hand soldering and reflow/surface-mount techniques, with kits to take home. [Announcement](/news/soldering-class-and-art-in-the-park/)
- **Machining:** the Bridgeport mill and the Clausing lathe, from reading the dials to taking a real cut. [Recap](/news/metalworking-class/)
- **Field trips:** like our tour of KOPN community radio's studios and transmitter equipment. [Details](/news/kopn-tour-april-23/)

Classes on the calendar for the year ahead: laser cutting basics, CNC router basics, 3D printing basics, intro to electronics and Arduino, welding, and woodshop safety. Dates are announced about a month ahead on the [events page](/events/), the [news page](/news/), and Discord.

<!-- TODO: confirm the planned-class list above reflects what the zone leads intend to offer. -->

### City of Columbia grant classes, Nov 2026 – Oct 2027

Thanks to a grant from the City of Columbia, we're running a **free public class on the first Thursday of every month** for a year, starting November 5, 2026. Topics rotate through every zone in the shop. No membership needed; some classes have limited seats, so watch the [calendar](/events/) for sign-up links.

<!-- TODO: confirm grant program name and whether it should be credited by name (e.g. "Office of Cultural Affairs"). -->
Thanks to a grant from the City of Columbia Office of Cultural Affairs, we're running a **free public class on the first Thursday of every month** for a year, starting November 5, 2026. Topics rotate through every zone in the shop. No membership needed; some classes have limited seats, so watch the [calendar](/events/) for sign-up links.

## Cost

Most classes are **free**. Where materials are significant (casting metal, electronics kits) we charge cost, typically $5–$20, and members get a discount. No one is turned away for inability to pay; just tell the instructor.
All classes are **free unless otherwise stated**. Financial assistance for this program has been provided by the City of Columbia Office of Cultural Affairs.

## Upcoming

Expand All @@ -46,7 +44,7 @@ To propose a class:
2. Post in the `#classes` channel on Discord or [send us a note](/contact/) with the topic, what students will make or leave able to do, materials needed, and how many people you can handle.
3. The classes lead will help you find a date, put it on the calendar, and promote it.

Instructors may charge a fee for paid classes, split with the zone that provides the tools. Details are in the membership policy on the wiki.
Instructors may charge a fee for paid classes, split with the zone that provides the tools. Details are in the membership policy on the [member wiki](https://wiki.comogadget.casa/).

## Groups, schools, and scouts

Expand Down
15 changes: 13 additions & 2 deletions content/contact.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title: Contact
subtitle: Say hello, ask a question, or set up a visit.
description: Contact Columbia Gadget Works. 1404 Grand Ave, Columbia, MO 65203. Open to the public every Thursday 6–8 pm. Email mail@columbiagadgetworks.org or call 573-326-9868.
wide: true
---

<div class="two-col">
Expand All @@ -13,18 +14,24 @@ description: Contact Columbia Gadget Works. 1404 Grand Ave, Columbia, MO 65203.

**Open to the public:** every Thursday, 6–8 pm (Open Hack Night)<br>**Members:** 24/7

Park in the gravel lot and ring the bell by the side entrance.
Park in the gravel lot and ring the bell by the side entrance. First time? [What to expect on a visit](/visit/).

## Reach us

- Email: [mail@columbiagadgetworks.org](mailto:mail@columbiagadgetworks.org)
- Phone: [573-326-9868](tel:+15733269868) (voicemail; a volunteer will call back)
- Discord: [join the server](https://discord.gg/F7kM7ardMs) for the fastest answers
- Member wiki: [wiki.comogadget.casa](https://wiki.comogadget.casa/) for policies, tool guides, and meeting minutes
- Social: [Facebook](https://www.facebook.com/columbiagadgetworks/) · [Bluesky](https://bsky.app/profile/comogadgetworks.bsky.social)

We're volunteers, so email replies can take a few days. If it's urgent and it's a Thursday evening, just come by.

{{< map >}}
### Common questions

- **Want a tour?** No appointment needed on a Thursday. Just walk in.
- **Bringing a group, class, or troop?** Use the form and tell us roughly how many people and what you'd like to see, so we can line up enough members.
- **Donating a tool or machine?** [Ask first](/donate/) so we can confirm we have space and a use for it.
- **Interested in joining?** See [membership](/membership/), then come by on a Thursday.

</div>
<div>
Expand All @@ -35,3 +42,7 @@ We're volunteers, so email replies can take a few days. If it's urgent and it's

</div>
</div>

## Find us

{{< map >}}
4 changes: 1 addition & 3 deletions content/membership.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ description: Join Columbia Gadget Works. Membership includes 24/7 shop access, a

## Dues

<!-- TODO: confirm tiers and amounts before launch. Standard $50 and Supporter $100 come from the 2026 management notes; the general membership vote on dues is expected in early 2027. -->

| Level | Monthly | Who it's for |
|---|---|---|
| **Standard** | $50 | Full access for one adult. |
Expand All @@ -38,7 +36,7 @@ Cost should never be the reason someone doesn't join. If the standard rate is ou

## Training

Some tools require training before you use them alone: the laser cutter, CNC router, milling machine, lathe, welders, and table saw. Training is free for members and is run by the zone lead on request or on a scheduled class night. Once you're signed off, it's recorded on the wiki and you're good to go.
Some tools require training before you use them alone: the laser cutter, CNC router, Bridgeport mill, Clausing lathe, welders, and table saw. Training is discounted for members and is run by the zone lead on request or on a scheduled class night. Once you're signed off, it's recorded on the wiki and you're good to go.

## Rules, briefly

Expand Down
30 changes: 30 additions & 0 deletions content/news/battlebots-chamber-of-robotic-aggression.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "Robot combat in the Chamber of Robotic Aggression"
date: 2026-09-20T10:00:00-05:00
description: Members built a polycarbonate battle box and filled it with small combat robots. Video from a recent match night at Columbia Gadget Works.
image: battlebots-arena.jpg
imageAlt: Two small combat robots pushing against each other inside a clear-walled arena labelled Chamber of Robotic Aggression
---

Somebody at this shop decided we needed an arena, so we built one. The **Chamber of Robotic Aggression** is a member-built battle box: a welded steel frame, a plywood floor, polycarbonate walls, expanded metal over the top, and hazard striping along the bottom rail so nobody forgets what it is for.

Here is fourteen seconds of what happens once two bots are in there together.

{{< video src="/video/battlebots-arena.mp4" poster="battlebots-arena.jpg" caption="Two small combat robots in the Chamber of Robotic Aggression at a recent Open Hack Night." >}}

<!-- TODO: confirm the match date and who built which bot, and add names here. -->

## It uses most of the shop

A combat robot is a good excuse to touch nearly every corner of the building, which is part of why we like them:

- The chassis and armor get cut, welded, and machined in the [metal shop](/tools/metal-shop/), on the Bridgeport and the Clausing when a part has to be right.
- Wedges, wheel hubs, and mounts come off the [3D printers](/tools/3d-printers/).
- Drive electronics, radio gear, and battery wiring happen at the [electronics bench](/tools/electronics-bench/).
- The arena itself came out of the [woodshop](/tools/woodshop/) and the welding bay.

## Want to build one?

Start small. An antweight class bot is cheap, fits on a bench, and teaches you the same lessons a heavier one would, just without the shrapnel. Come to [Open Hack Night](/visit/) on a Thursday and say you want to build a battlebot; there are several members who will immediately have opinions about drive trains.

Build notes and arena details go on the [member wiki](https://wiki.comogadget.casa/), and match nights get announced on [Discord](https://discord.gg/F7kM7ardMs) and the [events calendar](/events/).
2 changes: 1 addition & 1 deletion content/news/kopn-tour-april-23.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: KOPN Tour – April 23
title: "KOPN tour: April 23"
date: 2026-04-08T07:05:47-05:00
description: Columbia Gadget Works field trip to KOPN community radio on Thursday, April 23, 2026.
image: kopn.jpg
Expand Down
2 changes: 1 addition & 1 deletion content/news/metal-casting-class-feb-26th.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Metal Casting Class – Feb 26th!
title: "Metal casting class: February 26"
date: 2026-02-20T09:52:15-06:00
description: Free metal casting class Thursday, February 26, 2026 at 6 pm at Columbia Gadget Works.
image: metal-casting-mold.jpg
Expand Down
2 changes: 1 addition & 1 deletion content/news/metal-casting-class-recap.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Metal Casting Class – Recap
title: "Metal casting class: recap"
date: 2026-02-27T09:44:09-06:00
description: Recap of the free metal casting class at Columbia Gadget Works, February 2026.
image: metal-casting-parts.jpg
Expand Down
Loading
Loading