Back to Trey’s Monster Mash S.P.A.R.K. Chat Log  •  08/23/2026
S.P.A.R.K. with AI — Development Dialog

Trey’s Monster Mash — Unity Edition

From a 2023 Styl’n assignment to a JS App with a toggling image demonstration.
One page. Two visual states. One button. One principle.

About This Log

This page chronicles the full evolution of Trey L.’s Monster Mash design: from a 2023 web design class assignment through a two-page A/B comparison and finally into the TNT 2026 JS App ecosystem as a single “Unity” page.

The central lesson of the upgrade is visible in the toggle button: two lines of HTML (the src attribute of each image) made the original design look dated. Understanding why — transparent backgrounds, theming, visual integration — is the point of the exercise. The JavaScript that switches between the two states makes that lesson interactive and immediate.

🎯
S — Set Goal Chronicle the evolution of Trey L.’s 2023 Monster Mash Styl’n design into the TNT 2026 ecosystem: upgrade the page structure, combine the A/B design into a single Unity page with a JavaScript image toggle, and document the process.
The Original Design — 2023
💬
P — Background In 2023, TNT web design students were given the Monster Mash lyrics and one brief: style them. Trey L.’s submission stood out immediately for three things.
GitHub Copilot

What Trey got right, immediately:

  • The letterform title. Rather than a plain <h1>, Trey gave each letter of “MONSTER MASH!” its own <span> with an individual ID, color, and rotation. The result is a tumbling, kinetic title that feels like it belongs on a Halloween poster. This is not an accident — it is deliberate CSS animation thinking.
  • The color structure. Two classes (.orange and .purple) alternate through the lyrics, mapping the color structure onto the call-and-response structure of the song. The visual rhythm matches the musical rhythm.
  • The font choices. Sedgwick Ave Display for the title and Metal Mania for the body are genuinely thematic. Neither is a default font; both required looking at Google Fonts and making a decision. That is design, not just CSS.

The original design also had one significant flaw, which became the teachable moment: the images were sourced from Google’s image proxy — external, cached thumbnails with white or colored backgrounds. Against the dark DarkSlateGray main panel, they appeared as floating rectangles rather than integrated illustrations. For the Unity Edition, local copies of these original images were saved into mMashImages/ using an Orig suffix (e.g. ghostOrig.png, pumpkinHatOrig.jpg) so both visual states now load entirely from local files — no network dependency in either version.

Design Principle — Transparent Backgrounds Are Not Optional

An image with a white background does not “float” against a dark background — it produces a white rectangle with a picture inside it. This is one of the most common beginner mistakes in web design, and one of the easiest to fix: find the same artwork as a .png with a transparent background, or use the browser’s CSS mix-blend-mode: multiply to approximate transparency against light backgrounds.

For dark backgrounds, the correct approach is transparent-background PNGs. The local mMashImages/ folder contains four such images — ghost.png, pirateZombie.png, pumpkinHat.png, and bat.png — downloaded specifically for this purpose.

The side-by-side comparison that the Unity toggle makes possible is the most direct way to teach this: students see both versions in the same page, with the same layout, differing only in the src attribute of four images. The flaw is surgical. The fix is surgical. The lesson is precise.

The A/B Teaching Pattern
🔍
A — Analyze Before the Unity edition, the comparison was split across two files. Understanding why that was a reasonable first step — and why Unity is better — is the key insight of this session.
klp

Novice Trey had an app featuring the lyrics to “Monster Mash.” Deliberate flaws in the design were introduced (images without a transparent background) and a linked phrase took users to a better aesthetic page (Version B). I’m envisioning a ‘Unity’ design where a button click changes the images from jpg to png using images in the folder’s image folder. This way, we only need one file, not two. (Hence, Unity).

Prompt Critique — Naming the Concept

The word “Unity” is doing a lot of work in this prompt. It names the goal (one file, not two), communicates the mechanism (JavaScript toggle, not navigation), and implies the pedagogical intent (show both states side-by-side rather than forcing a navigation decision). All three are in that one word.

The phrase “hence, Unity” is a deliberate explanation: the user is aware that naming a technical concept requires justification, and they provide it immediately. This is good prompting practice: when you coin a term, define it. The AI will use the term correctly in all subsequent responses.

The mechanism is also specified precisely: “a button click changes the images from jpg to png using images in the folder’s image folder.” This tells the AI: the action is a click, the target is the images, the mechanism is a src attribute swap, and the source files are already local. No ambiguity about whether to use AJAX, a page reload, or a CSS toggle.

GitHub Copilot

The two-file A/B approach was sensible as a first step: Version A showed the flaw; Version B showed the fix; a link in the lyrics connected them. Students who followed the link saw the improvement but may not have immediately understood why the result looked different.

The Unity approach is superior for three reasons:

  • The comparison is simultaneous, not sequential. Students do not have to remember what Version A looked like while viewing Version B. They see the change in real time on the same layout. The difference is visceral rather than recalled.
  • Maintenance is halved. Any change to the lyrics, fonts, or layout needs to happen in one file, not two. Version A and Version B were already drifting apart in subtle ways (the layout differed slightly, the link wording differed). Unity eliminates drift.
  • The classification changes. Version A was a Styl’n page — HTML and CSS only. Unity uses JavaScript (document.getElementById, element.src, classList.toggle). This moves it into the JS Apps category, which is an accurate reflection of what the page now does.
The Implementation — Three Technical Decisions
🔁
R — Refine The Unity page is built. Three implementation choices shaped how the toggle works and how the page fits into the TNT ecosystem.
Decision 1 — The Toggle Mechanism: Object Map vs. Array

The JavaScript stores the two image source sets as objects (origSrcs and localSrcs), keyed by the element IDs (ghost, zombie, pumpkin, bat). The toggle function then iterates over the IDs with forEach and swaps each image’s src.

This is marginally more code than a flat array of pairs, but it is far more readable: srcs.ghost is self-documenting in a way that srcs[0] is not. When a future developer (or the student) needs to add a fifth image, they add one key to each object and one ID to the forEach array. The structure announces its own pattern.

The brief opacity: 0 fade on each image before the src swap prevents the flash of a missing image (the browser briefly shows a broken-image icon while the new source loads). This is a standard defensive pattern for dynamic image swaps: fade out, swap, fade in.

Decision 2 — CSS Scoping: The Critical Span Rule

Trey’s original CSS had this rule:

span {
    font-size: 60px;
    text-shadow: 2px 2px 5px black;
    display: inline-block;
    letter-spacing: 5px;
}

As a standalone page, this was fine: the only span elements on the page were Trey’s letter spans. In the TNT ecosystem, Bootstrap uses span elements everywhere — in the navbar brand, in badges, in utility classes, in icons. A bare span { font-size: 60px } rule would make the navbar brand unreadable and break every Bootstrap component that uses span.

The fix: scope the rule to #treyZone span. All of Trey’s tag-level selectors (h1, main, div.orange, div.purple, span) were moved inside the #treyZone wrapper. Bootstrap and tnt-base-styles are unaffected. Trey’s design is preserved exactly. This is the standard approach for embedding a standalone page inside a larger ecosystem.

Decision 3 — JS Apps, Not Styl’n

The original design was categorized as Styl’n because it was purely HTML and CSS. The Unity Edition uses JavaScript to manipulate the DOM: it reads element IDs, writes to src attributes, toggles a CSS class on the button, and manages a state variable (isLocal) across clicks. This is a JavaScript application, not a styled document.

The distinction matters beyond taxonomy. When students see this page in the JS Apps collection, they understand that JavaScript’s job is not only to compute and calculate — it is also to respond to user actions and change what the page shows. The toggle is a minimal but complete example of event-driven programming: a user gesture (click) causes a state change (isLocal flips) which causes a DOM update (four src swaps) which causes a visual result (the page looks different).

This is precisely the chain every JavaScript app follows, from a simple toggle to a full single-page application. The Monster Mash toggle is a clean introduction to the pattern.

💡
K — Know Three principles from this session that apply well beyond Monster Mash.
Session Takeaways
  1. Transparent backgrounds are the difference between an image and a box. On any non-white background, a .jpg or a non-transparent .png produces a rectangle. A transparent-background .png produces an illustration. Students who understand this make better choices at every stage of design, from choosing clip art to selecting favicon formats.
  2. Scope tag selectors before embedding a standalone page. Any CSS that uses a bare tag selector (span, h1, main, a) will collide with Bootstrap or any shared stylesheet. Before embedding a novice’s page into the TNT ecosystem, wrap its content in an ID-scoped div and prefix every tag selector with that ID. This is non-negotiable when sharing a stylesheet with Bootstrap.
  3. A toggle is the simplest complete JavaScript application. It has state (isLocal), an event listener (onclick), a DOM update (four .src swaps), and a visual result. Every more complex JavaScript application does exactly the same things at larger scale. The Monster Mash toggle is the clearest single-file introduction to this pattern that a novice can read end-to-end in under 30 seconds.
File Inventory
FileStatusWhat it does
treyLMMashUpdate-A.html Legacy reference Version A — original Trey design with external images (deliberate flaw)
treyLMMashUpdate-B.html Legacy reference Version B — local transparent PNGs (improved); companion to Version A
treyLMMashUpdateUnity.html Current Unity Edition — TNT navbar/hero/footer; JS toggle replaces both A and B
treysMonsterMashChatlog.html New This page — documents the evolution from 2023 to Unity 2026
mMashImages/ Asset folder Version A (Orig — with backgrounds): ghostOrig.png, pirateZombieOrig.png, pumpkinHatOrig.jpg, batOrig.png
Version B (seamless — transparent): ghost.png, pirateZombie.png, pumpkinHat.png, bat.png
transylvania.png (hero background)
Post-Session — One Page, One <h1>
klp

The validator reports: “Consider using the <h1> element as a top-level heading only.” Can you fix it and explain?

GitHub Copilot

The page currently has two <h1> elements:

  1. The hero’s <h1 class="hero-title">Trey L’s Monster Mash</h1> — the page’s primary heading.
  2. The tumbling-letter title inside #treyZone > header — a decorative/thematic heading that ranks below the page title.

Fix: change the second <h1> to <h2> and update the scoped CSS rule from #treyZone h1 {} to #treyZone h2 {}. The visual appearance is identical since all the styling is in CSS, not in the tag name.

Heading Hierarchy — One h1, Then h2 Down

A well-structured HTML document has exactly one <h1>: the page’s primary heading. Subsequent headings use <h2>, <h3>, and so on in order. Screen readers and search engines use this hierarchy to understand the document outline — a second <h1> is ambiguous: which one is actually the title of the page?

The visual appearance of a heading is entirely controlled by CSS. Changing <h1> to <h2> inside #treyZone does not change how the tumbling title looks — it still gets all of Trey’s font, border, and border-radius rules via #treyZone h2 {}. The only thing that changed is the semantic rank.

This is a common issue when embedding a standalone page (which correctly used <h1> as its single heading) inside a larger ecosystem page that already has its own <h1>. The fix is always the same: demote the embedded heading by one level.

Post-Session — The Pumpkin Margin That Wasn’t
klp

I added style="margin-right: 20px;" to the <aside> that wraps the pumpkin image to create space between it and the adjacent div, but it’s not working. Why? Can you fix it?

GitHub Copilot

Two things are wrong, and they compound each other.

Problem 1 — float collapses the parent. img#pumpkin has float: left applied to it. A floated element is removed from normal flow, so its parent (the <aside>) has no in-flow children and collapses to zero height. A zero-height element cannot produce visible margins.

Problem 2 — wrong element. Even if the aside had height, margin-right on a block container only affects the container’s own box edge. It does not push text away from the floated image inside it. To push text away from a float, the margin must be on the floated element itself.

Fix: move margin-right: 20px from the inline style on the aside to the img#pumpkin CSS rule. Remove the now-unnecessary style attribute.

CSS Rule — Style the Float, Not Its Wrapper

When an element is floated, its parent container collapses unless it contains other in-flow content or uses a clearfix. This means:

  • Margins on the parent have no visual effect — the box is zero height.
  • Margins on the float itself do work — the browser reserves space around the float when wrapping content around it.

margin-right on the pumpkin image pushes the wrapped text (the .orange div to the right of the float) away from the image’s right edge. margin-bottom on the image would push content below the float’s bottom edge. Both are valid; both must be on the img, not on the aside.

The general rule: when you want to control the space around a floated element, apply the CSS to the floated element itself — not to a wrapper around it.

Post-Session — A Monster in Every Heading
klp

Let’s put the monster.png image as an icon to the left of the heading in the hero area on the Unity page and the chatlog — as a branding-type way of recognizing that the pages belong together. Let’s also mention the Unity app on the Monster Mash song page where we already reference other TNT uses.

GitHub Copilot

Three changes made:

  • Unity page heromonster.png added as an inline <img> at height:1em inside the <h1>, matching the pattern already used in monsterMashSong.html.
  • Chatlog hero — same treatment at height:0.85em to stay proportional in the slightly different heading context.
  • Monster Mash song page — Unity Edition link added as a third entry in the Section 2 cross-link callout alongside the 2023 Styl’n Index and Legacy Clip Page links.
Branding Decision — Icon as Family Signal

The monster.png icon already appeared in three places: the js_apps.html grid card, the monsterMashSong.html hero heading, and the movie_clips.html card. Adding it to the Unity page and chatlog hero headings completes the visual thread: every Monster Mash page in the TNT collection now shows the same cartoon monster in the same position relative to the title.

This is a minimal but deliberate branding move. A student who arrives at the Unity page from the song clip page will recognise the icon and understand they are in the same family of content without reading any prose. The linking icon says “same universe” at a glance.

The icon is decorative in the accessibility sense — aria-hidden="true" and empty alt — because the heading text already carries the full accessible name. Repeating the description in the alt attribute would cause screen readers to announce “monster Monster Mash”, which is redundant. The icon is a visual signal only; the text is the semantic one.