4M MAYHEMDate: January 30 2027Venue: Conference Center at Curtiss Hall — Saginaw Valley State University, 7400 Bay Road, University Center, MI 48710Entry Deadline: January 22, 2027
Registration 8am–Noon · Judging Noon–3pm · Awards 4pm
🔒 Online Registration is Closed
Pre-registration for has ended.
The deadline was .
Walk-up registration may be available on show day — contact the show organizer for details.
Registration Fees: Adults (18+) $15.00 flat · Juniors (under 18) $5.00 flat · Both include unlimited entries. Fees increase to $20.00 after January 15, 2027. General Admission (spectators): $5.00 at the door.
1
Your Info
2
Entries
3
Review
4
Payment
Registrant Information
Tell us about yourself. All fields marked * are required.
First name is required
Last name is required
Valid email is required
City/State is required
— Select your level —
Novice (0–2 years)
Intermediate (3–7 years)
Advanced (8+ years)
Master / Professional
Please select your experience level
— Select registration type —
Adult (age 18+) — $15.00 flat, unlimited entries
Junior (age 17 and under) — $5.00 flat, unlimited entries
Please select a registration type
Your email will receive a confirmation with your registration number, entry table location, and show-day instructions.
Model Entries
Add each model you wish to enter. Your flat registration fee covers unlimited entries. Add as many as you like!
Review Your Registration
Please confirm your entries and fees before proceeding to payment.
Registrant
Edit
Model Entries
Edit
Payment
Choose your preferred payment method to complete registration.
Select Payment Method
💳Credit / Debit Card
🅿️PayPal
📬Mail Check
🏷️Pay at Door
🔒
Card processing powered by Stripe. Your card details are encrypted and never stored on our servers. Connect your Stripe account in the admin settings to activate live payments.
🅿️
You’ll be redirected to PayPal to complete payment securely. Configure your PayPal Business email in admin settings.
📬
Make check payable to: [Your Organization Name] Mail to: [Your Mailing Address] Include your registration number on the memo line. Registration is held for 10 days pending receipt of payment.
🏷️
You may pay cash or card at the registration desk on show day. Note: Pay-at-door registrations are not guaranteed a table spot until payment is received. Pre-registration fee applies.
✓
You’re Registered!
Your entry has been received. Print your tag sheet below and bring it on show day.
Your Confirmation Number
—
📱 Your Check-In QR Code
Volunteers will scan this at the door — instant check-in, no waiting
Registration Summary
🏷️
Next step: Click “Print My Tag Sheet” below. Cut out the individual model tags and attach one to each model you bring on show day. Present the full sheet at the door for instant check-in.
Model Entry Tags
Print this sheet, cut along the dotted lines, and place each tag with your model on show day.
Bring your full confirmation sheet to the door for check-in.
Scan at Door for Check-In
Print this sheet and cut out each model tag. Tape or place on your model’s display base.
Keep the top section intact — present it at the door for instant check-in.
// ═══════════════════════════════════════════════════════════════════════════════
// SHOW CONFIG — Update these values each year. Everything else runs automatically.
// ═══════════════════════════════════════════════════════════════════════════════
const SHOW_CONFIG = {
name: “4-M Mayhem”,
fullName: “4-M Mayhem — Mid-Michigan Model Makers”,
date: “January 30, 2027”,
location: “Conference Center at Curtiss Hall — Saginaw Valley State University, 7400 Bay Road, University Center, MI 48710”,
scheduleNote: “Registration 8am–Noon · Judging Noon–3pm · Awards 4pm”,
// ── Registration deadline ────────────────────────────────────────────────────
// Format: “Month DD, YYYY” e.g. “January 15, 2027”
// After this date the form closes automatically and shows the closed banner.
// Change to your actual cutoff date — committee recommended ~1 week before show.
deadline: “January 22, 2027”,
// ── Late fee cutoff ──────────────────────────────────────────────────────────
// After this date (but before deadline), the late fee kicks in automatically.
// Set to a few days before deadline, or same as deadline if no late period.
lateDeadline: “January 15, 2027”,
// ── Fees ────────────────────────────────────────────────────────────────────
generalAdmission: 5.00, // door admission (info display only — not charged here)
adultFee: 15.00, // Adults 18+ — unlimited entries
juniorFee: 5.00, // Juniors 17 and under — unlimited entries
lateFee: 20.00, // Late registration fee (after lateDeadline) — adults
lateJuniorFee: 5.00, // Juniors always $5 — change if needed
maxEntries: 99, // Unlimited — set to 99 as a practical cap
adminEmail: “midmichiganmodelmakers.ipms@gmail.com”,
website: “www.midmichiganmodelmakers.org”,
// ── Theme Awards ─────────────────────────────────────────────────────────────
// Set enabled: true/false per theme. Rename freely each year.
themes: [
{
id: “theme1”,
enabled: true,
name: “\”A Galaxy Far, Far Away\” — Star Wars 50th Anniversary”,
description: “Celebrating 50 years of Star Wars! Any model depicting a Star Wars spacecraft, vehicle, character, figure, or diorama from any film, series, or expanded universe. All scales and manufacturers welcome.”,
icon: “⭐”,
},
{
id: “theme2”,
enabled: true,
name: “\”Spirit of St. Louis\” — Best Lindberg Kit”,
description: “In memory of Charles Lindbergh’s historic 1927 transatlantic flight. Any model kit manufactured by Lindberg (any era). Best overall build of a Lindberg-brand kit wins — any subject, any scale.”,
icon: “✈️”,
},
],
};
// ═══════════════════════════════════════════════════════════════════════════════
// CATEGORIES — Your official 2027 category list with codes.
// Format: “Class Name (CODE)”: [“Sub-category 1”, “Sub-category 2”, …]
// The code prints on entry tags so judges can sort quickly.
// ═══════════════════════════════════════════════════════════════════════════════
const CATEGORIES = {
“Aircraft”: [
“AC1A — 1/72 scale and smaller, all types”,
“AC2A — 1/71 to 1/33 scale, all types (primarily 1/48)”,
“AC3A — 1/32 scale and larger, all types”,
],
“Space”: [
“SP1A — Real spacecraft, missiles, and vehicles, all scales”,
“SP2A — Sci-Fi TV, movies, and print subjects, all scales”,
“SP3A — Mecha, Gunpla, and Anime subjects, all scales”,
],
“Military Vehicles”: [
“MV1A — 1/48 and smaller”,
“MV2A — 1/47 and larger, 1945 and earlier”,
“MV3A — 1/47 and larger, 1946 and later”,
“MV4A — Non-armored with or without weapons, all types and scales”,
“MV5A — Artillery, weaponized rockets, missiles, rocket artillery”,
],
“Figures”: [
“FG1A — Busts, all types and scales”,
“FG2A — 54mm and smaller”,
“FG3A — 55mm and larger”,
“FG4A — Fantasy and gaming figures”,
“FG5A — Animals, past and present”,
],
“Diorama”: [
“DR1A — 1/72 and smaller”,
“DR2A — 1/48 (1/71 to 1/34)”,
“DR3A — 1/35 and larger”,
],
“Ships”: [
“SH1A — 1/500 and smaller, all types”,
“SH2A — 1/499 and larger, all types”,
],
“Automotive”: [
“AT1A — Replica or factory stock, all types”,
“AT2A — Curbside and slammers”,
“AT3A — Automotive to 1960 (hot rods, customs, stock, non-commercial pickups)”,
“AT4A — Automotive 1961 and newer (street machines, stock, non-commercial pickups)”,
“AT5A — Competition, all”,
“AT6A — Light commercial (family car/truck in commercial use)”,
“AT7A — Heavy commercial and farm implements”,
],
“Box Build”: [
“BB1A — Box build, all types and scales”,
],
“Juniors”: [
“JR1A — Age 12 and under, all scales and types”,
“JR2A — Age 13 to 17, all scales and types”,
],
“4ME — Special Needs”: [
“4MEA — Special needs modelers, all types”,
],
“Miscellaneous”: [
“MS1A — Any model that does not fit into any other category”,
],
};
// ─── Pricing helpers ──────────────────────────────────────────────────────────
function isLateRegistration() {
if (!SHOW_CONFIG.lateDeadline) return false;
const late = new Date(SHOW_CONFIG.lateDeadline);
if (isNaN(late)) return false;
late.setHours(23, 59, 59, 999);
return new Date() > late;
}
function getFeeForLevel(level) {
const late = isLateRegistration();
if (level === ‘Junior (age 17 and under)’) return late ? SHOW_CONFIG.lateJuniorFee : SHOW_CONFIG.juniorFee;
return late ? SHOW_CONFIG.lateFee : SHOW_CONFIG.adultFee;
}
function getFeeLabel() {
return isLateRegistration() ? ‘ (late registration)’ : ”;
}
// ─── State ────────────────────────────────────────────────────────────────────
let entries = [];
let currentStep = 1;
let payMethod = ‘card’;
let registrations = JSON.parse(localStorage.getItem(‘hsm_registrations’) || ‘[]’);
// ─── Init ─────────────────────────────────────────────────────────────────────
document.getElementById(‘show-name’).textContent = SHOW_CONFIG.name;
document.getElementById(‘show-date’).textContent = “📅 ” + SHOW_CONFIG.date;
document.getElementById(‘show-location’).textContent = “📍 ” + SHOW_CONFIG.location;
document.getElementById(‘show-deadline’).textContent = “⏰ Pre-registration Deadline: ” + SHOW_CONFIG.deadline;
if (SHOW_CONFIG.scheduleNote) {
const sched = document.createElement(‘span’);
sched.textContent = ‘🕗 ‘ + SHOW_CONFIG.scheduleNote;
document.getElementById(‘show-deadline’).after(sched);
}
// Fee info line
(function showFeeInfo() {
const late = isLateRegistration();
const feeEl = document.getElementById(‘show-fee-info’);
if (!feeEl) return;
if (late) {
feeEl.innerHTML = `⚠️ Late Registration Fees Apply: Adults $${SHOW_CONFIG.lateFee.toFixed(2)} · Juniors $${SHOW_CONFIG.lateJuniorFee.toFixed(2)} · Unlimited entries. General Admission (spectators): $${SHOW_CONFIG.generalAdmission.toFixed(2)} at the door.`;
} else {
feeEl.innerHTML = `Registration Fees: Adults (18+) $${SHOW_CONFIG.adultFee.toFixed(2)} flat · Juniors (under 18) $${SHOW_CONFIG.juniorFee.toFixed(2)} flat · Both include unlimited entries. Fees increase to $${SHOW_CONFIG.lateFee.toFixed(2)} after ${SHOW_CONFIG.lateDeadline}. General Admission (spectators): $${SHOW_CONFIG.generalAdmission.toFixed(2)} at the door.`;
}
})();
// ── Check if registration is closed ──────────────────────────────────────────
(function checkDeadline() {
if (!SHOW_CONFIG.deadline || SHOW_CONFIG.deadline === ‘TBD’) return;
const deadlineDate = new Date(SHOW_CONFIG.deadline);
if (isNaN(deadlineDate)) return;
// Close at end of deadline day
deadlineDate.setHours(23, 59, 59, 999);
if (new Date() > deadlineDate) {
document.getElementById(‘reg-closed-banner’).style.display = ‘block’;
document.getElementById(‘reg-form-wrapper’).style.display = ‘none’;
document.getElementById(‘closed-show-name’).textContent = SHOW_CONFIG.name;
document.getElementById(‘closed-deadline’).textContent = SHOW_CONFIG.deadline;
const emailEl = document.getElementById(‘closed-email’);
emailEl.href = ‘mailto:’ + SHOW_CONFIG.adminEmail;
emailEl.textContent = SHOW_CONFIG.adminEmail;
}
})();
// Add first entry automatically
addEntry();
// ─── Navigation ───────────────────────────────────────────────────────────────
function goToStep(n) {
if (n > currentStep) {
if (!validateStep(currentStep)) return;
}
if (n === 3) buildReview();
if (n === 4) buildPaymentSummary();
document.getElementById(‘panel-‘ + currentStep).classList.remove(‘active’);
document.getElementById(‘tab-‘ + currentStep).classList.remove(‘active’);
if (n > currentStep) document.getElementById(‘tab-‘ + currentStep).classList.add(‘done’);
currentStep = n;
document.getElementById(‘panel-‘ + n).classList.add(‘active’);
document.getElementById(‘tab-‘ + n).classList.add(‘active’);
window.scrollTo({ top: 0, behavior: ‘smooth’ });
}
// ─── Validation ───────────────────────────────────────────────────────────────
function validateStep(step) {
if (step === 1) {
let ok = true;
const checks = [
{ id: ‘f-fname’, el: ‘fname’, test: v => v.trim().length > 0 },
{ id: ‘f-lname’, el: ‘lname’, test: v => v.trim().length > 0 },
{ id: ‘f-email’, el: ’email’, test: v => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v) },
{ id: ‘f-city’, el: ‘city’, test: v => v.trim().length > 0 },
{ id: ‘f-experience’, el: ‘experience’, test: v => v !== ” },
{ id: ‘f-reglevel’, el: ‘reglevel’, test: v => v !== ” },
];
checks.forEach(c => {
const el = document.getElementById(c.el);
const fld = document.getElementById(c.id);
if (!c.test(el.value)) { fld.classList.add(‘has-error’); ok = false; }
else fld.classList.remove(‘has-error’);
});
return ok;
}
if (step === 2) {
if (entries.length === 0) { alert(‘Please add at least one model entry.’); return false; }
let ok = true;
entries.forEach((e, i) => {
if (!e.name || !e.category || !e.scale) ok = false;
});
if (!ok) { alert(‘Please fill in the Name, Category, and Scale for all entries.’); }
return ok;
}
if (step === 3) {
if (!document.getElementById(‘agree-rules’).checked) {
alert(‘Please read and agree to the Show Rules before continuing.’);
return false;
}
return true;
}
return true;
}
// ─── Entries ──────────────────────────────────────────────────────────────────
function addEntry() {
if (entries.length >= SHOW_CONFIG.maxEntries) {
alert(`Maximum ${SHOW_CONFIG.maxEntries} entries allowed.`); return;
}
const id = Date.now();
const themeDefaults = {};
SHOW_CONFIG.themes.filter(t => t.enabled).forEach(t => { themeDefaults[t.id] = false; });
entries.push({ id, name: ”, category: ”, subcategory: ”, scale: ”, notes: ”, …themeDefaults });
renderEntries();
}
function removeEntry(id) {
if (entries.length e.id !== id);
renderEntries();
}
function renderEntries() {
const list = document.getElementById(‘entries-list’);
list.innerHTML = ”;
entries.forEach((entry, idx) => {
const catOpts = Object.keys(CATEGORIES).map(c => `${c}`).join(”);
const subCats = entry.category ? CATEGORIES[entry.category] : [];
const subOpts = subCats.map(s => `${s}`).join(”);
list.innerHTML += `