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.
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.
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 (
.orangeand.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.
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.
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).
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.
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 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.
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.
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.
- Transparent backgrounds are the difference between an image and a box.
On any non-white background, a
.jpgor a non-transparent.pngproduces a rectangle. A transparent-background.pngproduces an illustration. Students who understand this make better choices at every stage of design, from choosing clip art to selecting favicon formats. - 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. - A toggle is the simplest complete JavaScript application.
It has state (
isLocal), an event listener (onclick), a DOM update (four.srcswaps), 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 | Status | What 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) |
<h1>The validator reports: “Consider using the <h1> element as a
top-level heading only.” Can you fix it and explain?
The page currently has two <h1> elements:
- The hero’s
<h1 class="hero-title">Trey L’s Monster Mash</h1>— the page’s primary heading. - 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.
h1, Then h2 DownA 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.
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?
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.
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.
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.
Three changes made:
- Unity page hero —
monster.pngadded as an inline<img>atheight:1eminside the<h1>, matching the pattern already used inmonsterMashSong.html. - Chatlog hero — same treatment at
height:0.85emto 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.
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.
Trey’s Monster Mash — Unity Edition