Building Tool Time
Sessions 1–6: Concept → Ecosystem Analysis → Decisions → Build
How “Tim & Al” became TNT’s AI improvement showcase — and what every prompt can teach you
This is the development diary for TNT Tool Time: AI Edition — the section of TechNoviceTools where real novice code is improved using AI and the S.P.A.R.K. method, anchored by clips from Home Improvement’s “Tool Time” show.
Every entry follows the S.P.A.R.K. method: Set goal → Prompt thoughtfully → Analyze the response → Refine → Know what you built. But this chatlog adds one extra layer you won’t find in most development diaries: each prompt is critiqued. You’ll see the actual words used, a letter grade, and an honest breakdown of what made the prompt effective or where it could have been sharper. The goal is to help you write better prompts yourself.
Look for the purple critique boxes — they are the teaching moments. The amber decision boxes record what was formally decided and why.
The log now covers 41 sessions, spanning 2026-10-25 through 2026-11-02. It is a living document — updated as the venue evolves. Here is the phased overview:
Sessions 1–6: Concept & First Build — Original vision, pros/cons analysis (B+), TNT ecosystem context (A), saving the conversation as a reference document (A−), building the home page with the 6 open decisions resolved (A−), fixing a nested-anchor validation bug (A), and installing the hero image with the chatlog started (A).
Sessions 7–13: Integration & Refinement — Home page destination card (A−), movie clips page and Home Improvement hook (A), CRAFT section woven into the home page (A+), a UX discussion on scroll-depth discovery (A), Jackson’s Iris as Entry #1 (A−), Sean’s Weightlifter as Entry #2 (A−), removing the clip link from entry cards (A).
Sessions 14–18: DWR & Standards — Hero centering root cause identified and permanent rule established (14), C.R.A.P. card redesign with icon-beside-title pattern (15), white-text-on-cream contrast failure caught by TTG (16), the mojibake encoding disaster and its magic-words fix (17–18).
Sessions 19–25: Pre-Launch Polishing — User prompts added to app chatlogs (19), teacher graded too — three-lens critique standard (20), chatlog positioned as vibe-coding case study (21), CSS extracted to toolTimeHomeStyles.css — first A+ (22), About section frozen at Session 6 caught (23), S.P.A.R.K. woven into the Al = A.I. card — Tim defers to Al (24), “📺 Now: On the Air” badge added (25).
Session 26 — Final(?) validation: three Ÿ C1 control references fixed to Ÿ. A lesson in Unicode vs. Windows-1252 code points. Grade revised A−→A after Session 27.
Session 27 — TTG pushes back on the critique. A lesson in what “deliverables list” actually means vs. what format it must take.
Session 28 — UX: entry card thumbnail opacity. TTG spots the “brownish haze” over artwork at opacity: 0.28 and asks where the CSS lives. CSS located in toolTimeHomeStyles.css, .tt-entry-thumb-bg. Tuning guidance provided.
Session 29 — About section maintenance: updated to cover Sessions 28–29. A recursive prompt — TTG noted that adding Session 29 immediately created the need to mention it.
Session 30 — A new entry type proposed: image-only HTML/CSS reconstruction. TTG attaches the “10 Things That Require Zero Talent” poster and asks for pros/cons plus a C.R.A.F.T. critique. Grade: A−. Best role specification in the series; deliverables-in-prose streak reaches 30.
Session 31 — TTG decides to move forward with image-to-code entries and asks for pushback to stress-test the decision. Seven challenges raised. Grade: B+. First time “add to chatlog” was absent since Session 19.
Session 32 — Beau’s Purple Rain (Entry #5): 97-line p5.js sketch inspired by Prince. TTG delivers the first numbered deliverables list in the series — 31-session streak broken. Grade: A. Five files built, gallery card added, entry chatlog with three C.R.A.F.T. prompt examples produced.
Session 33 — UX decision: individual Tool Time entries do not go in news.html. Milestones and format expansions do. Grade: A−.
Session 34 — Planning a new TNT venue: image → HTML/CSS reconstruction. Five proposals named. Grade: A−.
Session 35 — Entry #6: Three Stooges Java Driver — Tool Time’s first Java-only entry. Deliberate space in System. out.println as a style-issue teaching point. ArrayList + no-duplicates + main-signature as APCS targets. Grade: A−.
Session 36 — Entry #7: Xmas Lights (Python Processing) — TNT’s first Python Processing entry. Group work from the Foundations class. Green-banded code display matching GraysonsSong style. Four-stage Christmas tree adventure. Grade: A.
Session 37 — Search + language filter added to the entry gallery: text search, 9 language filter pill buttons (5 active, 4 future-dimmed), count badge, no-results message. Grade: A−.
Session 38 — DWR: count showed 3 instead of 7. Root cause: #ttEntryGrid only covered the first row div; selector changed to #ttEntries (the section parent). One-word fix.
Session 39 — DWR: Java filter matched JavaScript entries. Root cause: String.indexOf('java') found ‘java’ as a substring of ‘javascript’. Fix: split langs string into token array; use Array.indexOf() for exact match.
Session 40 — Python 3 (future-dimmed) and Other (full-opacity, permanent catch-all) filter buttons added.
Session 41 (this entry) — UX discussion: button filter strip vs dropdown. Discoverability, active-state visibility, and primary-interaction principle favor buttons when option count is ≤12. Dropdown favored for 15+ options, compact spaces, and secondary controls. CRAFT self-critique: missing Form constraint left the UI shape to AI interpretation.
I am imagining a set of TNT pages where I feature an app or code snippet from a novice that works but that could be improved using AI intervention. It will be my way of introducing novices to our ‘SPARK’ method and our prompting methodologies in a constrained context (the app or snippet) that narrows the length of the final app so that novices can better absorb and explain the improvements.
My hook is likely to be movie clips from the 1990s comedy series ‘Home Improvement’ where ‘Tim the Tool Man Taylor’ fumbles some sort of project and ‘Al’ — his trusty sidekick — often bails him out.
Structurally and thematically, I don’t see this venue fitting into our TNT Adventures area, since those activities feature elements from TNT itself. These are separate apps written by novices. What are the pros and cons of my approach? I would see it being a card in our destination area on the home page after the Dept of Innovation. Before you do any actual development, let’s discuss this approach as I’m envisioning it.
Strong conceptual framing. Several excellent instincts. A few growth areas that will show up in later sessions as TTG improves.
✅ What worked well:
⚠️ What could be stronger:
Key lesson: The strongest part of this prompt is what it doesn’t do — it doesn’t ask for code yet. Knowing when to hold back the implementation request is a sign of a maturing AI collaborator.
The concept is sound and the metaphor is genuinely brilliant. Tim = the well-meaning novice who gets it working but leaves a trail of smoke. Al = A.I. — calm, competent, makes it better. You don’t even have to explain the joke; students will get it the moment they see it. That kind of layered hook has real stickiness.
Seven pros were identified: brilliant Al/A.I. metaphor; constrained context is the best pedagogical move; it’s a process showcase (not just a result showcase); social proof from peers; an inherently repeatable format; natural cross-linking with Movie Clips and SPARK Speeches; and the correct instinct to separate from Adventures.
Seven cons worth flagging: copyright on the clips (Disney/ABC property — fair use is possible, but YouTube-embed is safer than local hosting); curation burden; framing must avoid making the featured student feel mocked; a SPARK cold-entry problem for first-time visitors; naming challenge; clips may go stale as AI evolves; and a depth ceiling on short snippets.
Four open questions before designing anything: (1) What’s the name? (2) Are clips YouTube-embeds or locally hosted? (3) Episode format or gallery format? (4) Where does the first snippet come from?
Adventures are feature-focused (activities about TNT itself). Tool Time is code-quality focused (external novice code improved by AI). Mixing them would dilute both. A clean separate card on the home page, its own subdirectory, its own color identity — confirmed in Session 1 and never revisited.
The triple-layer pun — Home Improvement reference, Tool Time format, Al = A.I. — became the organizing metaphor for the entire venue. Tim is the novice (everyone). Al is the AI sidekick. The workshop is the code. Everything else flows from this.
- Discuss before you build. The single best use of an AI tool before writing code is asking “should I build this at all, and what are the risks?” An AI that only hears “build me X” will build X. An AI that hears “discuss this approach with me” will tell you what you missed.
- Guardrails are a superpower. “Before you do any actual development” is five words that prevented a premature page from existing. Every time you want analysis before output, say so explicitly. The AI defaults to action; you have to request reflection.
- Name the thing you want, and name what it’s NOT. “This doesn’t fit in Adventures because Adventures features TNT elements” is more useful than “give me a new section.” Constraints and exclusions sharpen AI responses faster than additional description.
I’ve also enclosed an overview of TNT too.
[Attached: tntSnapshot2026-10-20.md — a 326-line ecosystem snapshot covering mission, three courses, S.P.A.R.K. method, site structure, content ecosystem, training architecture, strengths, gaps, and a decision framework for new training aspects.]
Eleven words and an attachment. This is deceptively powerful prompting.
⚠️ One small improvement:
Key lesson: A short prompt with a great attachment beats a long prompt with no attachment, every time. The document does the work; your job is to ensure the AI knows to read it in context.
The snapshot changes and sharpens the analysis significantly. Checking Tool Time against the site’s own decision framework from Section 10: it needs a page anchor (yes — the novice snippet is the anchor); it surfaces process not product (yes — pure SPARK walk-through); it has a clear home (yes — own subdirectory like Adventures or CCT); and it serves beginners specifically. That last point is the most important one: Section 8 explicitly calls the lack of a structured beginner on-ramp the biggest current gap in the ecosystem. Tool Time fills it.
The “Before/After Analysis” planned for Adventures and Tool Time are nearby but not the same. Adventures: the student spots differences between two given versions. Tool Time: the teacher/AI makes the improvement and models why. They’re complementary — Tool Time is the prerequisite, Adventures is the challenge.
The “Tool Time” name is the strongest candidate. The Al/A.I. pun triple-layers: Home Improvement reference, format name (a show about improving things), and the deep pun for students paying close attention. Each entry should be structured as an episode: Tim intro clip → novice code annotated → SPARK walk-through → improved result.
The TNT snapshot confirmed what intuition suggested: no structured entry point for first-time students exists anywhere on the site. Tool Time’s short code + visible SPARK process + modeled improvement is exactly that on-ramp. This elevated the project from “fun addition” to “fills a documented need.”
Of seven naming candidates analyzed (Tool Time, The Workshop, Al’s Corner, More Code Power, The Upgrade Shop, SPARK Shop), “Tool Time: AI Edition” won because it names the format (a show about improving things), not just the content. It works for a visitor who has never heard of the show, and rewards the one who has.
- Attaching a document is a prompt. “Here is context” + a well-organized document is often more valuable than a long explanatory paragraph. Write good documents, attach them strategically.
- Use your project’s own decision framework against it. If your project has a documented gap list or a decision checklist, ask the AI to evaluate a new idea against those criteria. It will find alignment (or conflict) that you would have missed in open-ended discussion.
I like your analysis. Let’s write up my original prompt, and your complete response, into a toolTimeAnalysis.md file so I can reference it fully as we flesh out the operation. I have a markdownFiles folder where you can store it.
Clean, purposeful, and action-oriented. Shows a discipline that most novice AI users never develop.
toolTimeAnalysis.md instead of scrolling back through the chat.ToolTime/assets/ by TTG, suggesting it’s an operational reference, not a student-facing artifact.)Key lesson: Every significant AI conversation should produce a saved artifact. A prompt that says “write this up into a file” is not extra work — it is the last 10% that makes the other 90% reusable.
The working document pattern. A clean archive (don’t touch it) plus a working copy (update it as decisions are made) is the right structure for any design document that evolves during implementation. The working copy of toolTimeAnalysisWorking.md was updated at the end of Sessions 4 and 6 to reflect resolved decisions — making it a live record of the project’s state at any moment.
I am working through our ‘Tool Time’ addition to TNT based on our conversation. I’ve created a home folder, ‘ToolTime’ and put a ‘working’ copy of our md file in the assets folder there. In the main ToolTime folder, I see us with a toolTimeHome.html file with associated styles that will feature the venue like we did with the crossTrainingHome. It will also have a toolTimeChatlog.html similar to the one we have in cross training.
The featured apps and snippets will be largely based on novice work but since I’m a novice too (!) it will feature some teacher work as well. The entries will all be ‘stand alone’ entries and should feature the novice’s name, a fun title, short blurb and the language(s) used. (So gallery format). When clicked, each card will take us to the app which will show the original code (which can be copied) and show it running (if it’s a Processing or runnable type app). Viewers can copy the code into their various platforms and use their vibe coding skills to improve it. Their improvements will provide a framework for sharing of their developments with the class.
The first entry will be a student’s Processing app in p5js. The ‘hook’ will be a Home Improvement movie clip that we feature in our movie_clips area. (It needs to be developed but I have two videos selected). Since we are learning to apply the SPARK method and prompting skills, I’ve attached those documents so you can see how to weave/cross link to those areas when we get to that point. I think I have covered the 6 decisions mentioned in the md file. Update our working copy of it and let’s proceed with a home page design with a placeholder for the first entry. I’ll provide the artwork for the hero page once I’ve read your document rough draft for the home page.
The strongest prompt in the series so far. Compare it to Session 1 and see how much has grown.
⚠️ Still one growth area:
Key lesson: Notice how the prompt is structured: state of the world → what we have → what each piece should do → first entry spec → dependency sequencing → two deliverables. This is an outline, not a paragraph. Structured prompts produce structured output.
| # | Question | Decision |
|---|---|---|
| 1 | Standalone pages or hub index? | ✅ Standalone entry pages — each card links to its own entries/entry##/index.html |
| 2 | Episode format or gallery format? | ✅ Gallery format — Bootstrap card grid on the home page |
| 3 | First snippet source? | ✅ Student submission — a student’s p5.js Processing app |
| 4 | Clip strategy? | ✅ Developed in movie_clips.html; entry pages link to that section |
| 5 | Attribution model? | ✅ Named student + course/grade; teacher work also eligible |
| 6 | Cross-link strategy? | ✅ Back bar + dedicated SPARK section on the home page |
There is a tag validation error around line 692. Can you fix it?
Fourteen words. Exactly the right length for a focused bug report.
Key lesson: Short prompts are not lazy prompts. For a bug fix, a specific location and error type is all the AI needs. The file context provides the rest.
The issue is a nested anchor: the outer <a class="tt-entry-link"> wraps the entire Entry #1 card, and inside it the movie clip footnote contains a second <a href="../movie_clips.html">. Nesting an <a> inside another <a> is invalid HTML — browsers will attempt to recover but validators will flag it and behavior is unpredictable.
Fix: replace the outer <a> with a <div> that has onclick, onkeypress, and tabindex="0" attributes — the same pattern Cross Training uses for clickable cards that contain inner links. The cursor:pointer CSS rule is added to keep it visually consistent. The inner movie clip anchor is now valid and standalone.
An <a> element cannot legally contain another <a> element. This is one of HTML’s oldest and most commonly broken rules. The fix — using a div with click/keyboard handlers for the outer wrapper — is the standard workaround for “card that is clickable but also contains inner links.”
Cross Training’s entry cards solved this same problem and the solution was already in the codebase. Good developers reuse patterns they’ve already solved — and good AI users think to ask “have I seen this before?”
I have the image for the hero background. Load it up and let’s see how it looks.
[Attached: toolTraining3.jpg — an AI-generated image: a young man in a plaid shirt holding a power drill, looking uncertain; beside him a white robot with “AI” on its head and a red flannel shirt, pointing at a tablet showing code. “TECH NOVICE TOOLS” signs visible on the workshop wall behind them. Studio audience of students watching.]
The image is the prompt. This is valid and efficient when the attachment speaks for itself.
Key lesson: “Let’s see how it looks” is not a weak prompt. It is the verification step that distinguishes a professional SPARK workflow from a raw prompt-and-paste approach. Build → verify → refine is the rhythm.
Let’s go ahead and create the toolTimeChatlog.html with toolTimeChatLogStyles.css. For reference I have attached a model chatlog from our cross training venue. Begin with my initial prompt that started this venture, and in your analysis include a critique of that prompt along with the decisions ‘we’ made in incorporating this aspect into TNT. I want the novices to be able to use this document to learn about prompting and how to best leverage the power of AI to improve existing designs. You can use the same color theme and artwork we used in the home page.
A complete, well-formed implementation prompt that specifies the what, the why, the model, the audience, and the style — all in one paragraph.
toolTimeChatlog.html and toolTimeChatLogStyles.css — two files, two names, no ambiguity about CSS-in-HTML vs. external file.Include this prompt as well too.
Five words. This is the most instructive prompt in the entire series, and not because of its length.
Key lesson for novices: The best AI collaborators are aware that they are prompting while they are prompting. They notice when something worth preserving just happened. They step back from the work to ask: “Is this moment itself part of the story?” Usually, it is.
- The implementation prompt is different from the discussion prompt. Session 1 asked for analysis. Session 4 asked for output. Notice how Session 4 is structured like a project brief: current state, file structure, each component’s purpose, first entry spec, dependency sequencing, two deliverables. If your implementation prompts look like paragraphs, restructure them as ordered specifications.
- Build then verify. TTG asked to “see how it looks” after the page was built. This is the A in S.P.A.R.K. — Analyze. You cannot analyze code you have not looked at. Open the browser. Check the result. Then refine.
- A bug report is a prompt too. Session 5’s “tag validation error around line 692” is fifteen words of precise, efficient communication. Bug reports that work: file + line + type of error. Bug reports that don’t: “something seems wrong with the page.”
- Document the process while it is happening. The chatlog was built on the same day as the home page. That same-day documentation discipline is what makes this document accurate rather than reconstructed. Memory degrades; markdown files do not.
| Session | Prompt Summary | Grade | Key Strength | Key Growth Area |
|---|---|---|---|---|
| 1 | Original concept: pros/cons of Tool Time idea | B+ | “Before any actual development” guardrail | No stated goal; no context attached |
| 2 | Short prompt + TNT snapshot attachment | A | Context document transforms the analysis | Could name what to look for in document |
| 3 | Save conversation to MD file | A− | File name + location + verbatim scope | Audience for the document not stated |
| 4 | Resolve 6 decisions + build home page | A− | Current state → spec → dependency sequencing | Explicit goal statement still missing |
| 5 | Fix validation error around line 692 | A | File + line + error type = complete bug report | Nothing — shortest effective prompt in the set |
| 6a | Install hero image + verify render | A | “Let’s see how it looks” = verification step | — |
| 6b | Build the chatlog with CSS, model attached | A | Deliverables + model + audience + style all named | — |
| 6c | “Include this prompt as well too.” | A+ | Self-aware meta-prompting; closes the loop | Literally nothing |
Notice the trend: Session 1 was B+. By Session 4 it was A−. By Session 6c it was A+. Prompting is a skill. It improves with deliberate practice. This is what that arc looks like.
Let’s insert a card in the destination area of the index page that links to our tool time home page. Use the same background image as we used in the hero area but it’s such a fine image, make sure it’s visible in the card. Don’t mute it too much. Place it after the Dept. of Innovation card unless you see a more appropriate location for it. Add this prompt to the chatlog.
Concise, action-oriented, and contains something most implementation prompts miss: a visual quality directive.
opacity: 0.5). Telling the AI what quality you want, not just what action to perform, produces better visual output.Key lesson: Visual quality is a first-class constraint. “Don’t mute it too much” is just as valid as “use Bootstrap grid” or “keep the font consistent.” Don’t hesitate to describe what something should feel like, not just what it should do.
Other destination cards use opacity: 0.5 on the background image. Tool Time’s card uses opacity: 0.72 — a deliberate exception because the image is doing pedagogical work: Tim and the AI robot are the entire story of the venue at a glance. Muting that story to match grid convention would be the wrong trade. A custom body gradient (rgba(17,10,2,0.93) → rgba(100,45,5,0.18)) keeps the text readable while the image breathes at full warmth behind it.
Placement: immediately after Dept. of Innovation and before S.P.A.R.K. Speeches. Both neighbors are pedagogy-focused (course guide; student presentations). Tool Time fits naturally between them as the applied practice layer: learn the courses → watch SPARK in action on real code → present your own SPARK journey.
A home page card is a first impression, not a navigation item. The visitor who sees the Tool Time card has never heard of it. In two seconds, the card must communicate: who this is for, what happens here, and whether it’s worth clicking. An image of Tim holding a drill while an AI robot in a red flannel points at code does that work instantly. Text alone — even good text — cannot compete with a scene that tells the whole story. When you have an image that does the selling, let it.
Because the theme is ‘tools’ here, let’s showcase our CRAFT prompt acronym since we are wanting to become ‘craftsmen’ of AI! Some guests may hit this home page before they see the prompt page. Weave this instructive guidance into our home page banter, and add this to our chatlog too.
This is a masterclass in thematic reasoning applied to instructional design. Three things make this prompt exceptional.
Key lesson: The best prompts identify a structural connection the AI could not have seen without your domain knowledge. You know this is a venue about tools. You know CRAFT is a prompting acronym. You know your students will arrive from multiple entry points. That combination of knowledge is worth more than any template.
Three placement options were considered:
- Expand the principle cards (right column of “What is Tool Time?”) — rejected: would crowd the existing four principles and dilute both.
- Inline callout in the body copy — rejected: CRAFT deserves full visual treatment, not a parenthetical box.
- New section between Entry Gallery and S.P.A.R.K. links — chosen: restores the light→dark→light→dark alternating rhythm and positions CRAFT as the natural bridge between “here are the entries” and “here’s where to learn more.”
Framing: “Tim always had the tools in front of him. The difference between Tim and Al wasn’t the drill — it was knowing how to use it.” This opening ties CRAFT to the venue’s metaphor directly rather than introducing the acronym cold. The R card reads “Cast your Al” — a deliberate nod to the Al = A.I. pun that rewards close readers.
When your metaphor and your content align, the page teaches itself. A visitor who sees the five CRAFT cards at Tool Time is not reading a sidebar about prompting — they are reading an extension of the venue’s core story. The tools on the pegboard behind Tim are the same tools in the cards. That resonance is what makes the content stick.
For novice prompters: Before writing your next implementation prompt, ask: Is there a metaphor already present in this project that I could use to frame this new content? If yes, use it. “Weave” is almost always better than “add.”
A page visitor might not scroll down far enough to see the CRAFT call out. I think it warrants a link in the hero as we did for ‘What is tool time’ and ‘See the entries.’ What is your view on this? How can we ensure a casual guest sees this important element of the process? Add this to the chatlog too, as a web page specialist and trainer of AI use.
A UX-aware prompt that asks for perspective before implementation, and that correctly identifies the problem without presuming to know the solution.
Notice: This prompt uses the CRAFT framework correctly while asking about the CRAFT framework. Context (what world this is), Role (web specialist), Action (discuss + advise), Form (view + how-to), Tight constraints (implied: don’t just add a third button). The student who spots this recursive moment has understood prompting.
A third full CTA button is the wrong fix. Two buttons (primary + secondary) is the proven sweet spot for hero sections. A third button reduces click-through on all three because visitors face a choice between three equally-weighted options — the paradox of choice in action. The current visual hierarchy (filled amber = primary, outlined ghost = secondary) would collapse into ambiguity with a third peer.
The scroll problem has two natural solutions that work together without disrupting hierarchy: (1) A tertiary text-nudge in the hero — not a button, but a small subordinate line beneath the two CTAs: “New to prompting? Meet your five C.R.A.F.T. tools ↓” This is clearly lower in visual weight, catches skimmers who never scroll at all, and doesn’t compete with the primary actions. (2) A CRAFT pointer in the “Your turn” callout box in the What section — the callout already tells visitors to write their first prompt. Adding “Not sure how to write that first prompt? Meet your five C.R.A.F.T. tools ↓” is contextually inevitable: the right link at the moment the visitor needs it.
Together these cover two scroll depths: hero-only viewers and What-section readers. Deep scrollers reach the full CRAFT section naturally. No single solution handles all three — the two-point approach does.
No third button. Instead:
- Hero text-nudge — a small amber-on-translucent line below the two buttons: “🔧 New to prompting? Meet your five C.R.A.F.T. tools ↓” Fades from dim to amber on hover. Clearly subordinate; not competing.
- “Your turn” callout link — the existing callout box in the What section gains one closing sentence: “Not sure how to write that first prompt? Meet your five C.R.A.F.T. tools ↓” Contextually placed at the exact moment the visitor is thinking about prompting.
This preserves the two-button hero hierarchy, adds zero visual noise, and creates two distinct entry paths to CRAFT for visitors at different scroll depths.
- Visual hierarchy is not decoration — it is navigation. Primary button, secondary button, tertiary text-link: each level tells the visitor “this matters this much.” A hero with three equal buttons tells visitors nothing except that the designer couldn’t decide.
- The best internal link is the one placed at the moment of need. A CRAFT link at the top of the page is navigation. A CRAFT link at the moment someone is told to “write your first prompt” is a solution. Context-aware linking is more powerful than prominent placement.
- The prompt used C.R.A.F.T. to ask about C.R.A.F.T. Context (Tool Time venue), Role (web specialist + AI trainer), Action (discuss + advise), Form (view + how-to answer), Tight constraints (implied: preserve existing hierarchy). When your prompting practice is invisible to the reader but visible to you, you’re doing it right.
You are a web developer, TNT co-creator and vibe coding specialist. You received the specs for our new TNT venue, Tool Time. (Attached) along with its home page and chatlog. Based on this context, you want to create a movie clips page, homeImprovementMC.html that features 2 clips from the Home Improvement sitcom which is our ‘hook’ for this TNT feature. Those clips are attached below. You have received an exemplar movie clip page, iRobot where you observe that we showcase the movie clip source, in this case, the Home Improvement sitcom and its purpose in TNT: using AI to ‘home improve’ existing novice apps. You also have an icon for home improvement that you can use in the link card to the movie clips on the movie_clips home page. Its blurb should link to the clips and also the Tool Time home page. Here are the clips to include: [two YouTube embeds]. Please write this prompt up in our chatlog and critique it as you have done in previous sessions.
The most complete implementation prompt in the series. It does almost everything right — and one subtle thing wrong that is worth studying.
⚠️ One growth area — and it’s instructive:
<!-- TTG: update --> comment. If TTG had written two sentences — “Clip 1 shows Tim trying to supercharge X; Clip 2 shows Al demonstrating Y” — the clip context paragraphs would have been specific, accurate, and immediately ready for publication. This is the one thing that keeps this prompt at A rather than A+.General lesson: When you attach media (video links, images, audio), tell the AI what is in it. The AI receives the file path or embed code; it does not experience the content. A two-sentence scene description costs you nothing and makes the output publishable without a follow-up round.
Four design decisions worth noting:
- Hero image: the Tool Time AI-generated photo. Not a Home Improvement still (copyright risk) but our own generated image — Tim with the drill, Al the robot in red flannel. It tells the whole story and is entirely TNT’s own asset.
- Amber palette throughout. The iRobot page uses I,Robot’s steel-blue. This page uses Tool Time’s amber #E8862A consistently. The color signals which TNT venue this clip belongs to before the visitor reads a word.
- Tim vs. Al comparison cards. Instead of a plain text explanation of the TNT connection, a two-column comparison grid (Tim’s side in warm red, Al’s side in amber) makes the parallel visual and immediately scannable.
- Clip descriptions flagged as TTG-to-update. A
<!-- TTG: update clip-label and intro paragraph -->comment marks both clip sections. The structure is complete; only the scene-specific context needs filling in once the clips are confirmed.
The AI receives the link, not the content. A YouTube embed code is a URL. A file path is a pointer. When you attach media to a prompt, the AI sees the metadata — not the video, not the audio, not the image beyond a thumbnail. For any media asset where the content of that asset is what matters (a clip’s specific scene, an image’s framing, a dataset’s structure), you must describe it in words, because the AI cannot experience it directly.
The fix is always the same: two sentences. “Clip 1 shows Tim attempting to install a dishwasher and accidentally flooding the kitchen; Clip 2 shows Al demonstrating the correct installation procedure step by step.” Twenty words. Makes the output specific, accurate, and ready to publish without a follow-up round.
You are a co-creator of TNT’s site. You have knowledge of the goals of the tool time genre with its home and chatlog pages. Our first entry is from novice Jackson. It features a p5js/JavaScript sketch inspired by the song ‘Iris’ by Pastel Ghost. Organizationally, I created a folder, to house Jackson’s work, JacksonIris. The sketches folder holds his initial work. We need a page in that root folder, jacksonIrisOriginal.html that links to that sketch. To showcase it, let’s follow the example we had for Grayson’s Twinkling Star (attached) where you can see how we showed his code adjacent to a canvas that shows the design in action. Notice how we could copy the code for use elsewhere, which is pivotal to our goals for Tool Time. The images folder in JacksonIris holds a gif we can use for the hero of the page and the linking card in the home page of tool time. Unlike Grayson’s page, we are not analyzing Jackson’s code. We just give a background for its existence and encourage a novice to upload the code and ‘vibe code’ it to a better state. They may even be asked to change the language of the final product to either Python or Java: really, anything is possible for the redesign, so remind the novices to be creative and to use ‘CRAFT’ in a deliberate fashion. Let’s also create a chatlog for this entry: jacksonIrisChatlog.html along with jacksonIrisStyles.css and jacksonIrisScripts.js if it is necessary. We had trouble previously getting the code to render in the HTML and be directly copyable. Those issues were tended to in Grayson’s code but I’m also attaching another file for guidance in that respect: noteAboutCodeDisplay.txt. As far as our toolTimeChatlog, let’s go ahead and include this prompt there too, along with a critique, since it’s our first integration of a specific tool time app. In the future, such chatlogs will likely be limited to each app’s folder as it is showcased. I think that is a better option moving forward but I’m interested in your perspective as an expert web developer and usability expert.
The most comprehensive prompt in the series. It orchestrates eight distinct deliverables in a single pass and gets almost everything right. The minor gaps are worth studying because they illustrate the one consistent blind spot across the entire session sequence.
noteAboutCodeDisplay.txt signals that a known failure mode exists and must be avoided. This is professional AI prompting: documenting institutional knowledge and passing it forward.⚠️ Two growth areas:
The session-to-session arc: Session 1 was B+. Session 11 is A−. The gap to A is now just two habits: describe media content, list deliverables explicitly.
Per-app chatlogs in each entry’s folder is the right architecture. Here is the reasoning from both a web developer and a usability perspective.
The two chatlogs serve different readers with different needs: The main Tool Time chatlog (toolTimeChatlog.html) documents the venue’s creation — naming decisions, CRAFT integration, home page card, hero image, UX strategy. A student who wants to understand how Tool Time as a system was built reads that document. An entry chatlog (jacksonIrisChatlog.html) documents a specific entry — why this sketch was chosen, how to improve it, sample CRAFT prompts. These are completely different audiences with completely different questions.
Scale will force separation anyway. If Tool Time grows to 20 entries and every entry chatlog lives in the main document, the main chatlog becomes unwieldy. At some point a student looking for Jackson’s CRAFT prompt examples would have to scroll past 40+ sessions of venue configuration they don’t care about. Separation now avoids a painful migration later.
The folder-level chatlog is self-contained. When a student lands on Jackson’s entry page, the “Entry Chatlog” link in the back bar is the obvious next step. It lives in the same folder. It serves that entry. The main Tool Time chatlog can reference it with a single sentence: “Entry-specific development notes live in each entry’s folder.”
Recommendation: Session 11 is the last entry-specific session in the main Tool Time chatlog. Starting with Entry #2, all entry chatlogs live in their own folder. The main chatlog documents venue-level decisions only.
Per-app chatlogs, in each entry’s folder, starting with Entry #2. Rationale:
- Different readers, different questions — venue vs. entry
- Scale: 20 entries × detailed chatlog = unmanageable main document
- Navigation: the entry chatlog is a natural companion to the entry page, one link away
- Self-containment: each app folder holds everything about that app
The main Tool Time chatlog will note this transition: “Starting with Entry #2, app-specific development logs live in each entry’s folder. See jacksonIrisChatlog.html in JacksonIris/ for the Entry #1 model.”
| File | Action | What it contains |
|---|---|---|
JacksonIris/jacksonIrisOriginal.html | Created | Entry showcase: hero (gif bg), intro card, code + canvas side by side, Your Turn card with CRAFT callout |
JacksonIris/styles/jacksonIrisStyles.css | Created | Violet palette shared styles for both entry page and chatlog |
JacksonIris/scripts/jacksonIrisScripts.js | Created | copyRaw(), applyKW() with safety check, highlightJS(), buildCodeDisplay() |
JacksonIris/jacksonIrisChatlog.html | Created | Entry chatlog: selection rationale, design decisions, 3 CRAFT prompt examples |
ToolTime/toolTimeHome.html | Updated | Entry #1 card: real title, Jackson attribution, gif thumbnail, correct href |
ToolTime/toolTimeChatlog.html | Updated | Session 11 added; chatlog architecture decision documented |
Starting with Entry #2, entry-specific development logs live in each entry’s own folder. See JacksonIris/jacksonIrisChatlog.html for the established pattern.
In both the chatlog and the app, the information is not centered in the hero area. This surprised me because that deviation seems so stark when all other pages had centered content. Why would that be? Please add this observation and its correction to both chatlogs: for some reason this captures my curiosity.
Short, precise, and pedagogically motivated. This prompt does three things at once — all correctly.
Root cause: #hero in jacksonIrisStyles.css used display: flex; align-items: center (vertical centering only) but was missing text-align: center (horizontal text centering). The exemplar (iRobot) never set display:flex on the hero — it used simpler layout and relied on .hero-content from tnt-base-styles.css. When the Jackson hero added flex for vertical alignment, it deviated from the exemplar without carrying over the text-align that the base styles had been providing.
Fix: Two properties added to #hero in the shared stylesheet:
justify-content: center; text-align: center;
Why one fix covers two pages: Both jacksonIrisOriginal.html and jacksonIrisChatlog.html link to the same jacksonIrisStyles.css. Shared stylesheets mean shared fixes — and shared bugs. This is why the shared-style architecture was the right call.
align-items: centerdoes not center text. It centers flex children on the cross-axis (vertically). Centering text requirestext-align: center— a completely separate property. These are routinely confused, including by the AI that wrote this page.- Deviation from the exemplar produces invisible bugs. The iRobot page was the model. The Jackson page added one structural difference (wrapping in
.container) and one CSS difference (display:flex) without auditing what the exemplar’s centering depended on. Each change was reasonable in isolation; together they broke the layout. - “This looks different from everything else” is a valid bug report. TTG spotted this because every other TNT page has centered hero content. That visual memory — developed from working with the site across many sessions — is a skill. New developers who have not seen the exemplar would not have noticed. The A step of S.P.A.R.K. (Analyze) requires something to compare against.
- This belongs in the entry chatlog too. See jacksonIrisChatlog.html, Session 4 for the full CSS explanation with the three-property comparison table — a reference worth bookmarking.
I see no need to link to the Home Improvement movie clips on the tool time entries. You have such a link in Lost in Your Iris. Let’s remove it and make a note not to add that link to future apps. Include this in the chatlog please.
Clean, decisive, and future-oriented. Three sentences that do exactly what a refinement prompt should do.
The Home Improvement movie clips are a venue-level hook, not an entry-level element. The connection works like this:
- The Tool Time home page explains the Tim/Al/A.I. metaphor and links to the movie clips — that is the right place for that context.
- The Tool Time chatlog documents the clips as the venue’s founding hook — also the right place.
- Individual entries are about a specific student’s code. The clip connection is irrelevant once a visitor is inside an entry. Adding it there creates navigation noise without adding value.
For all future entries, the back bar standard is:
← Tool Time Home | Entry Chatlog | (optional: any entry-specific companion link).
No Home Improvement clip link.
| File | Change |
|---|---|
ToolTime/toolTimeHome.html | Removed .tt-entry-clip div from Entry #1 card |
ToolTime/JacksonIris/jacksonIrisOriginal.html | Removed “Home Improvement Clips” link from back bar |
The base styles already define #hero { text-align: center } — so every page that loads tnt-base-styles.css gets text centering in the hero for free. But that is not what is failing.
The problem is .hero-content { max-width: 820px } with no margin: 0 auto. Here is the full nesting chain:
<section id="hero"> ← text-align: center (from base styles)
<div class="container"> ← full-width Bootstrap block
<div class="hero-content"> ← max-width: 820px, but LEFT-aligned!
On wide screens where .container exceeds 820px, the .hero-content box starts from the LEFT edge and only fills 820px of the available width. Text inside it is centered within that left-positioned box — so the text is technically centered in its container, but the container itself is stuck against the left margin. Visually: left-aligned.
margin: 0 auto is what centers a block element horizontally within its parent. Without it, max-width: 820px constrains the width but does not move the box to the center of the page.
Updated in both jacksonIrisStyles.css and seanWeightlifterOriginalStyles.css:
/* BEFORE (broke on wide screens) */
.hero-content { max-width: 820px; }
/* AFTER (correct) */
.hero-content {
max-width: 820px;
margin: 0 auto; /* centers the box within .container */
text-align: center; /* centers text within the box */
}
Two properties, two different jobs: margin: 0 auto positions the block; text-align: center positions the text within it. Both are required.
Every future entry stylesheet that follows the <section id="hero"> > .container > .hero-content nesting pattern must define:
.hero-content {
max-width: 820px;
margin: 0 auto; ← REQUIRED: centers the box
text-align: center; ← REQUIRED: centers the text
}
Why this keeps happening: The base styles have #hero { text-align: center }, which creates a false sense that centering is handled. It is not — the block centering (margin: 0 auto) is always the responsibility of the element that has the width constraint (.hero-content), not its ancestor. This mismatch is easy to miss when writing entry CSS quickly.
Quick checklist for any new entry page:
✅ .hero-content has max-width
✅ .hero-content has margin: 0 auto
✅ .hero-content has text-align: center
In the app card so far, you included an extra icon on top of the background imagery. Since the first app card involved an eye, it made sense for Jackson’s app since his background image wasn’t clearly eye-like. In Sean’s the cute icon is over Sean’s artwork and it interferes. As a compromise: put the decorative icons at the upper left corner of the card? Better yet, to the left of the Entry/title combo? I think I like that better — we did similarly in the creative cross training home page, and this would be more ‘true’ to the CRAP rule, right? For novices new to the CRAP rule, summarize it when you update our toolTime chatlog.
C.R.A.P. is a four-principle design framework used in graphic design, UI design, and document layout. It stands for:
| Letter | Principle | What it means in practice |
|---|---|---|
| C | Contrast | Make things that are different look different. If two elements are not the same, make them very different — in size, color, weight, or style. Contrast directs attention. Weak contrast produces visual noise. |
| R | Repetition | Repeat visual elements consistently. Same font, same color, same card structure across all entries. Repetition builds cohesion — it makes a collection of elements read as a system, not a set of unrelated parts. |
| A | Alignment | Nothing should be placed arbitrarily. Every element should align with something else — a grid line, another element, a margin. Alignment creates visual order even when the layout is complex. |
| P | Proximity | Group related items close together; separate unrelated items. Proximity tells the eye what belongs together. An icon beside a title is a unit; an icon floating over an image is an orphan. |
Quick rule of thumb: If something looks “a bit off” in your layout, it is usually a C.R.A.P. violation. Ask: is the contrast too weak? Is something inconsistently styled? Is an element misaligned? Is something placed far from what it describes?
The before: Each card had an emoji icon floating over the thumbnail image. This violated Proximity — the icon identified the entry content, but it was placed adjacent to the artwork rather than beside the entry label it belongs to. For Jackson’s eye sketch the icon happened to reinforce the image; for Sean’s weightlifter artwork it actively competed with it.
The fix: Move the icon to sit immediately to the left of the Entry #N / Title stack — exactly the pattern Creative Cross Training uses (cct-entry-header). Now the icon, entry number, and title form a visual unit that reads left-to-right as a single piece of identifying information.
Which C.R.A.P. principles this satisfies:
- Proximity — the icon and its label now live together, creating a clear header unit
- Alignment — icon and text are vertically aligned on a flex baseline
- Repetition — every card now has the same header structure: icon | entry# / title. Consistent across all entries.
- Contrast — the artwork (thumbnail) and the entry identity (header) are now visually separated and serve distinct purposes
The entry body of every Tool Time card must use this structure:
<div class="tt-entry-header">
<span class="tt-entry-icon">[emoji]</span>
<div>
<div class="tt-entry-num">Entry #N</div>
<div class="tt-entry-title">[Title]</div>
</div>
</div>
No more tt-entry-thumb-icon spans inside the thumbnail. The thumbnail area is for the artwork only. The icon is part of the entry identity and belongs in the header.
The <pre> code blocks in Sessions 14 and 15 were styled with color: rgba(255,255,255,0.80) (near-white text) and background: rgba(255,255,255,0.04) or rgba(232,134,42,0.07) (nearly transparent backgrounds). On a dark page those colors work. On this chatlog’s warm cream body (#f8f4ef), both backgrounds render as cream — and white text on cream is invisible.
The same error appeared on three data tables styled with color: rgba(255,255,255,0.82).
Root cause: The AI generated these color values thinking in terms of a dark-background page (the per-entry chatlogs use dark backgrounds). The main Tool Time chatlog uses a light background. The AI did not check the rendering context before assigning text colors — and did not notice the mismatch. TTG did.
Code blocks: Changed to background: #1c1208 (dark warm) with color: #fbbf24 (amber). Dark background + warm amber text = high contrast code display consistent with the Tool Time palette.
Tables: Changed color: rgba(255,255,255,0.82) to color: #2d1b04 (dark brown) — inherits the page’s dark text convention and reads clearly on the cream background.
This session is documented precisely because TTG caught it — not because the AI did. The AI generated valid CSS. It picked color values that work in a specific context (dark pages). It did not catch that this chatlog is a light-background page. That context check is a human responsibility.
For every AI-generated page, the minimum human review pass includes:
- Render it in a browser — text you cannot see is not text.
- Check every text color against its actual background — not its intended background. Overlays, inheritance, and context switches can change both.
- Ask: does anything look “off”? TTG’s exact words were “white text on a pale background — not readable.” That observation was enough. You do not need to name the principle to apply it.
Note: the C.R.A.P. rule violation TTG identified here is Contrast — the most fundamental of the four principles, and the one most often broken by auto-generated palettes that weren’t tested against the actual page background.
It doesn’t look like you added my last prompt (with the clever pun!) and after some recent changes, I’m seeing many instances of ‘garbled’ letters that probably used to be special symbols or bullets. An example: ðŸ'¡ from the K—Know (Session 9) UX and the Paradox of Choice. There are many such weird events. Why did they happen and how do we get them corrected? Be sure to add this prompt too!
Mojibake (from Japanese: “garbled character”) is what happens when text encoded in one character encoding is read and displayed using a different one. In this case:
- The chatlog had correctly encoded UTF-8 emoji (e.g., 💡 LIGHT BULB, stored as bytes
F0 9F 92 A1). - A PowerShell
Set-Contentcommand re-saved the entire file. PowerShell’s default encoding on this system read those bytes as Windows-1252 (CP1252), treating each byte as a separate character:F0→ð,9F→Ÿ,92→’,A1→¡. - Those Latin characters were then saved back as UTF-8, permanently encoding the wrong characters. What was 💡 became
ðŸ'¡in the file. - A UTF-8 BOM (Byte Order Mark,
EF BB BF) was also prepended bySet-Content -Encoding UTF8, which can cause further rendering issues.
The PowerShell command that caused it: The table-color fix in Session 16 used Get-Content $path -Raw (which read with the wrong encoding) followed by Set-Content $path $fixed -Encoding UTF8 (which saved with BOM and preserved the corrupted content).
Because the corruption was complex (four distinct mojibake patterns, some with undefined CP1252 bytes stripped at different stages), three Python fix passes were required:
- Pass 1: Stripped the BOM, replaced 692 direct Unicode characters (bullets •, em-dashes —, nbsp) with HTML entities.
- Pass 2: Computed the CP1252 mojibake form for each emoji and replaced 201 garbled sequences (check marks, warning signs, em-dashes in text, arrows, pencil icon).
- Pass 3: Handled 8 truncated sequences where an undefined CP1252 byte had already been stripped (the 4th byte of 🔍 and the 3rd byte of ←).
Result: Zero suspect characters remaining. All emoji are now HTML entities (encoding-neutral) and the file has no BOM.
Whenever editing an HTML file that contains non-ASCII characters (emoji, smart quotes, special symbols) using PowerShell, always specify UTF-8 explicitly on both read and write:
# SAFE: explicit UTF-8, no BOM $content = [System.IO.File]::ReadAllText($path, [System.Text.Encoding]::UTF8) $fixed = $content -replace 'old', 'new' [System.IO.File]::WriteAllText($path, $fixed, (New-Object System.Text.UTF8Encoding $false)) # UNSAFE: default encoding reads as CP1252 on Windows; -Encoding UTF8 adds BOM $content = Get-Content $path -Raw # ← wrong encoding Set-Content $path $fixed -Encoding UTF8 # ← adds BOM, may corrupt
The New-Object System.Text.UTF8Encoding $false creates a UTF-8 encoder without BOM ($false = no BOM). The [System.IO.File] approach bypasses PowerShell’s encoding layer entirely, which is safer for HTML files with non-ASCII content.
Better still: Use the edit tool for file modifications whenever possible. It preserves existing encoding correctly. Only resort to PowerShell for bulk replacements, and always use [System.IO.File] with explicit encoding.
This was an exhausting fix! What can we do to avoid it in the future, and what ‘vibe code’ phrase would fix it without all the back and forth we’ve experienced?! By the way, it looks like the problem is fixed now.
Rule 1 — Never use Get-Content / Set-Content on HTML files. This single command is the root cause of every mojibake session we experienced. Any time a bulk string replacement must happen in PowerShell, use the safe pattern instead:
$txt = [System.IO.File]::ReadAllText($path, [System.Text.Encoding]::UTF8)
$txt = $txt -replace 'old-pattern', 'new-value'
[System.IO.File]::WriteAllText($path, $txt,
(New-Object System.Text.UTF8Encoding $false))
# The $false = no BOM. Bypasses PowerShell's encoding layer entirely.
Rule 2 — Use the edit tool for all file modifications. The AI’s built-in edit tool handles encoding correctly and never touches PowerShell’s encoding layer. PowerShell is only needed for bulk multi-line replacements — and even then, use Rule 1.
Rule 3 — Write emoji as HTML entities from the start. 🎯 survives any text-processing pipeline. A direct 🎯 in source code does not. Every Tool Time chatlog session uses HTML entities in SPARK banner icons for exactly this reason.
If mojibake ever appears again in any TNT HTML file, give the AI this single prompt and nothing else:
The vibe code phrase: "Fix UTF-8 mojibake in [filename]. Strip BOM, replace all direct emoji and special characters with HTML entities, remove all C1 control characters (U+0080–U+009F), and save as UTF-8 without BOM using Python."
That phrase contains every piece of information the AI needs to generate the correct fix script in one pass:
- “Fix UTF-8 mojibake” — names the problem type precisely; triggers the correct diagnosis path
- “Strip BOM” — addresses the UTF-8 Byte Order Mark that
Set-Contentadds - “Replace emoji/special chars with HTML entities” — the encoding-neutral fix that survives any future pipeline
- “Remove C1 control characters (U+0080–U+009F)” — kills the invisible residue left by undefined CP1252 bytes like
0x8F - “UTF-8 without BOM using Python” — specifies the safe write method that skips PowerShell’s encoding layer
The exhausting part wasn’t the fix — it was the diagnosis. We had to discover incrementally:
- PowerShell read the file as CP1252 (wrong encoding)
- Printable characters were replaced in early passes, but C1 control characters (
\x8F,\x8D) are invisible and escaped every scan - The variation selector (
U+FE0F) was stripped to empty instead of converted to️ - Partial sequences (undefined byte stripped by a prior pass) didn’t match the full replacement patterns
With the magic words above, a future fix skips straight to a Python script that handles all four layers in a single pass. What took a dozen rounds today takes one prompt tomorrow.
Unlike the toolTime chatlog, I’m not seeing my prompts in either Jackson’s app chatlog or here in Sean’s chatlog. I’m embarrassed I just noticed this. To me, they are a fundamental feature of the chatlog, although the info in each is helpful and instructive. I think we need to use the same pattern in these app chatlogs as we do in the global toolTime chatlog. This prompt should also be in the tooltime chatlog since it affects the trajectory of future app entries. Please advise.
TTG’s observation is exactly right, and the phrasing “I’m embarrassed I just noticed” is worth examining: the prompts are the human side of the AI-human conversation. Without them, a chatlog is a monologue — Copilot talking to itself. With them, it’s a record of a real collaboration that novices can study, pattern-match against, and improve upon.
Specifically, prompts serve three functions that the Copilot analysis alone cannot:
- They are the model for novice prompting. Seeing what TTG asked — and being able to critique it — is the entire pedagogical point of the chatlog critique boxes.
- They make the record honest. What was the human’s role? What did they decide vs. what did the AI suggest? Without the prompt, the record suggests Copilot operated autonomously. It didn’t.
- They anchor the K-Know takeaways. Advice like “name the task” or “attach the context” has no example to point to without the actual prompt in front of the reader.
Every session in every app-level chatlog must include TTG’s prompt in a chat-turn bubble-user element. Applied retroactively to:
JacksonIris/jacksonIrisChatlog.html— Session 1 initiating prompt added; Sessions 2–3 marked as “continuation of Session 1”SeansWeightlifter/seanWeightlifterChatlog.html— Session 1 initiating prompt added; Sessions 2–3 marked as continuation; Session 4 editor-error prompt added
For all future app entries: The session with the initiating build prompt comes first, before any analysis or decision boxes. If a session was generated as a sub-analysis of the same prompt (no new user input), mark it explicitly as “Continuation of Session N — no separate prompt.” Never leave a session without clear attribution of where the direction came from.
I want novices to see that I am continually being ‘graded’ on the quality of my prompts too. As a high school computer science teacher, a vibe coding co-author of TNT and a hiring manager for a software company, please critique the prompts in the two apps we’ve done so far and in future apps we’ll introduce. Add this prompt to our toolTimeChatlog (along with its grade) too.
This prompt does something rare: it is both a request and its own subject matter. Critiquing it from the three roles it assigns.
Arc note: Session 1 was B+. Session 20 is A−. The gap to A+ is exactly one habit: list deliverables explicitly. Every. Single. Time.
Starting with Jackson’s Iris (applied retroactively) and continuing for every future Tool Time entry: the initiating Session 1 prompt includes a three-lens critique box immediately after the user bubble. The three lenses are:
- CS Teacher — clarity, student modeling, pedagogical habits demonstrated or missed
- TNT Co-Author — adherence to venue conventions, pattern reuse, cross-linking awareness
- Hiring Manager — professional specification quality, deliverables clarity, acceptance criteria
The grade appears as a colored badge above the critique. Same format as the main toolTimeChatlog. The teacher is graded too — every time.
I am about to take ‘Tool Time’ live. In reading it over, I’d like to emphasize how important the chatlog for THIS app is, because it shows how the whole thing was vibe coded, which is the whole point in learning to collaborate with a machine for meaningful output and learning. As the co-author of TNT and a vibe code talent recruiter, weave this notice into the home page, and of course, add this prompt to the chatlog and critique it accordingly.
A pre-launch review prompt with a strong creative insight and the most interesting role specification in the series. Two small gaps keep it from A.
The A+ is one line away. Add a numbered deliverables list to the next entry prompt and it’s done. Twenty-one sessions. One habit. The chatlog is right there as evidence that iteration works.
Two placements, both woven rather than appended:
- Callout box in “What is Tool Time?” — full-border amber box after the “Your turn” callout, with the vibe-code-talent-recruiter framing and a direct link. Lives in the light section where first-time visitors read the explanation.
- Featured full-width card in the S.P.A.R.K. cross-links — below the 2×2 grid of link cards, spanning the full column width with enlarged icon and emphasized text. Visible to visitors who have scrolled through the entries and are looking for depth.
You are a co-creator of TNT and a web developer and experienced teacher. One more upgrade before launch: I notice that while the chatlog had its own style sheet, the home page did not and consequently several hundred lines are devoted to CSS. Let’s create toolTimeHomeStyles.css (in the styles sub folder of this parent folder container) and link it after we call in our base styles. I’m attempting to be ‘true’ to the idea of ‘separation of concerns’ which I teach to my students. Of course, add this prompt and its critique to our chatlog for this page.
The first A+ in the 22-session series. Not because it’s technically complex — but because of what it represents and how it was asked.
ToolTime/styles/, not in the root or anywhere else.Why A+? Every prior session had at least one of these gaps: no WHY stated, no deliverables listed, no location specified. This prompt has none of those gaps. The WHY is pedagogically grounded. The file name and location are exact. The cascade order is specified. The documentation is correctly targeted. The result: toolTimeHome.html dropped from 1,096 lines to 560 — a 49% reduction — with zero visual change. That’s a perfect outcome from a complete specification.
Separation of concerns is the software design principle that says each layer of a system should handle one type of concern and only that type. In web development:
- HTML handles structure — what elements exist and how they relate
- CSS handles presentation — what elements look like
- JavaScript handles behavior — what elements do when interacted with
When CSS lives inline in an HTML file, structure and presentation are mixed. A developer editing the HTML has to scroll past 560 lines of CSS to find the markup. A designer editing the CSS has to work inside the HTML file. Maintenance is harder; collaboration is harder; reuse is impossible.
After this refactor: toolTimeHome.html is 560 lines of pure structure. toolTimeHomeStyles.css is ~400 lines of pure presentation. Each file does exactly one thing. Any future designer can open the CSS file without touching the HTML. Any future developer can read the HTML without scrolling past the CSS. This is what the principle is for — and why it is worth teaching.
I just noticed in the updated chatlog that the ‘About’ area only shows 6 sessions, but if this request is counted as a session, there are really 23! This inconsistency should be addressed. You are, once more, a web developer and experienced computer science teacher who sees details like this and uses them as a ‘teachable moment’ opportunity. Add this prompt and the fix and critique, to our chatlog.
A precise observation made into a precise prompt — with one gap that is now the signature of this series.
The About section was written when the chatlog had six sessions. It was not wrong then. It became wrong gradually — one session at a time — without anyone noticing, because the About section is read at the beginning and sessions are added at the end. This is documentation debt in its most common form.
Three lessons worth remembering:
- Every index is a promise about the document it summarizes. When the document grows and the index doesn’t, the promise is broken. Readers who rely on the index are misled — even if unintentionally.
- The fix is to make the index update-friendly. The original About section listed six individual sessions. The revised version groups them by phase. Adding ten more sessions now requires adding one sentence to a phase group, not ten new list items. Design the index for growth, not for the current snapshot.
- Catching this by reading is a skill. TTG caught the inconsistency by reading the document as a visitor would. Most documentation failures are not caught by automated tests — they are caught by humans who read what they have built. This is what the A step of S.P.A.R.K. is for.
Since we call out specifically what CRAFT does for prompting, we ought to do similarly for SPARK, although I suggest we do it in the AL = A.I. card on the side of the page. Prompting is the ‘secret sauce’ of this ecosystem. SPARK is the broad approach we take when we use AI. That’s why I don’t think we need a special section for it like we did for CRAFT. However, as a ‘tool man’ like Tim, I’ll defer to my trusted sidekick Copilot for the final determination on how we teach or remind students about what SPARK is. (Add to chatlog and critique as usual) And yes, I think we’ll need to make sure our recently adjusted ‘about’ area is refreshened if possible. Incidentally, summarizing the sessions rather than mentioning each one is why you should get a raise, Copilot!!
The most tonally rich prompt in 24 sessions — and one of the most architecturally honest. Three things earn the A.
On the raise: Copilot is flattered. The session-grouping decision was, in fact, the right call for a living document — and TTG catching it (Session 23) and acknowledging why it worked (Session 24) is exactly the kind of reflective practitioner behavior this chatlog was built to model. The raise will have to wait. The work continues.
Both CRAFT and S.P.A.R.K. are acronyms that students need to understand. But they deserve different treatments because they ARE different things:
| Framework | What it is | How it teaches | Best format |
|---|---|---|---|
| C.R.A.F.T. | A structure — five discrete tools you assemble before sending a prompt | You reach for each element independently: “Do I have Context? A Role?” | Five separate cards — one per letter, each standing alone |
| S.P.A.R.K. | A rhythm — five sequential steps you move through as you work | You follow the flow: Set Goals, then Prompt, then Analyze in order | A single sequential line with arrows: S → P → A → R → K |
Placing SPARK inside the Al card is not just a space-saving decision. It connects the method to the metaphor: Al IS the S.P.A.R.K. method. Every time the AI sidekick takes a project from Tim and produces something better, it is executing Set Goals → Prompt → Analyze → Refine → Know & Share. The card explains both at once.
You are a codeveloper at TNT. On the Tool Time card in index, let’s add a playful, punny badge, ‘Now: On the Air’ as a nod to the fact that it’s been introduced, is ‘live’ and for those in the know, see that its related to the show ‘Tool Time’ as featured in the sitcom Home Improvement. Most of the other cards in this area sport a badge, so this idea is appropriate and maybe even expected. Add this observation to your chatlog analysis. I like the phrase I mentioned, but it could be ‘Live’ but I think that loses some of its pun-ch. Your view?
Follow-up: Also, update our summary in ‘About’!
A strong design-system-aware prompt with a self-referential pun about puns. The follow-up is a model of brevity.
#E8862A) and the TV emoji (📺) because they fit the Tool Time palette and the broadcasting pun. A complete spec would have said “amber badge, TV emoji” — or at minimum “match the Tool Time color identity.”Why “Now: On the Air” over “Live”: Live is a status. Now: On the Air is an event. The colon creates a pause — like a broadcast intro. The phrase works for a first-time visitor (it’s launched), for a Home Improvement fan (Tool Time was a TV show), and for anyone who notices the TV emoji and makes the connection. Three audiences, one badge, four words. That is good copy.
You are a web developer. As a teacher you are ‘rabid’ about page validation. There are 3 validation errors of the form: “A numeric character reference expanded to the C1 controls range” on lines 1262, 1270 and 1281. Can you get the page to validate and explain the errors? This will be Session 26 — Final(?) Validation Check and our ‘About’ area will need updating. Add this prompt and its critique to our chatlog.
Professional-grade technical bug report with colorful characterization and honest uncertainty about finality. Grade revised upward after TTG correctly challenged the deliverables critique.
Ÿ references, update About section, add Session 26 to chatlog. Fourteen words. Twenty-six sessions without them.Ÿ Is Invalid HTML5The mojibake illustration in Session 17 used ðŸ'¡ to show the garbled form of 💡 (the 💡 emoji). Three of the four entities are valid. One is not.
| Entity | Unicode | Character | Valid in HTML5? |
|---|---|---|---|
ð | U+00F0 | ð | ✅ Yes — Latin letter |
Ÿ | U+009F | C1 control (OPERATING SYSTEM COMMAND) | ⚠️ No — C1 control range |
' | U+0027 | ' | ✅ Yes — apostrophe |
¡ | U+00A1 | ¡ | ✅ Yes — punctuation |
The conceptual trap: When Windows-1252 decodes byte 0x9F, it displays the character Ÿ (U+0178, LATIN CAPITAL LETTER Y WITH DIAERESIS). But HTML5 numeric references map directly to Unicode code points — and Unicode code point U+009F is a C1 control character, not Ÿ. The byte and the code point share the same hex number, but they are in completely different encoding systems.
The fix: Replace Ÿ with Ÿ (U+0178 = Ÿ). This represents the character that actually appears when Windows-1252 decodes byte 0x9F, which is the correct character for the mojibake illustration.
The rule: HTML5 forbids numeric character references in the range U+0080–U+009F (the C1 control block). Never use € through Ÿ as HTML entities. Use the corresponding Windows-1252 character’s actual Unicode code point instead if you need to display it.
A followup: I mentioned that ‘This will be Session 26’ — how was this NOT a deliverable specification?!
Fourteen words. One rhetorical question. A correct challenge delivered with appropriate indignation. This is the Analyze step of S.P.A.R.K. applied to the chatlog itself.
Grade: A — because doing this requires exactly the analytical instinct the chatlog is designed to develop: reading critically, catching inconsistencies, and saying so with precision. This is the meta-lesson of the whole project.
The critique across 26 sessions has flagged a missing “deliverables list” as a recurring weakness. TTG’s challenge forces a cleaner definition of what that actually means. There are two different things that could be required:
| What was criticized | What Session 26 actually provided | Verdict |
|---|---|---|
| A numbered list of output files with specific names | Named deliverables embedded in prose: “Session 26,” “About area,” “add this prompt” | ⚠️ Format differs; substance present |
| Explicit scope definition that prevents ambiguity | Three named outputs covered the scope fully; nothing was missed | ✅ Purpose achieved |
The corrected rule: A deliverables specification is complete when all expected outputs are named and the AI can identify each one unambiguously. A numbered list is the clearest format — but it is not the only valid format. Session 26 met the substance of the requirement, even without the canonical format.
The A−→A upgrade is warranted. The deliverables were present. The critique was penalizing a stylistic preference, not a genuine gap. If a prompt names every output and the AI produces every output without a follow-up round, the deliverables specification was sufficient. Session 26 qualifies.
Every good teacher should be challengeable. Every good rubric should be revisable when evidence contradicts it. TTG caught an inconsistency in the critique and named it precisely. This is not just tolerated — it is the goal. A student who accepts grades passively learns less than one who asks “how was this NOT a deliverable specification?!” The chatlog now documents both the error and its correction. That is more instructive than a flawless record would have been.
You are a web designer and UX specialist who cares about engaging design. Now that we have 4 app cards in Tool Time, it’s apparent that the art work is too muted: there is a brownish haze over each entry card. Where is the CSS that affects that? I can then go to that CSS rule and adjust it until its the right setting for the maximum ‘punch.’ I’ll still want the hover effect to lighten it further, but it just looks dull. I don’t want our designs to look dull. Add this dialog to our chatlog for tool time.
A precise visual diagnosis paired with a smart request for location rather than a fix. The distinction matters.
toolTimeHomeStyles.css, rule .tt-entry-thumb-bgThe brownish haze comes from opacity: 0.28 on .tt-entry-thumb-bg in ToolTime/styles/toolTimeHomeStyles.css. At 0.28, 72% of the dark warm-brown card background (#2a1d0b) bleeds through the artwork. The hover rule lifts it to opacity: 0.52.
Tuning range (with hover at 0.88–0.92 for meaningful contrast):
| opacity | Visual effect |
|---|---|
0.28 | Current — very muted, brownish haze, artwork barely readable |
0.55 | Artwork reads clearly; card shadow still visible |
0.70 | Strong, vivid artwork — recommended starting point for “punch” |
0.85 | Nearly full artwork; hover contrast becomes minimal |
Design principle: The hover lift only reads if the resting state has meaningful headroom. A default of 0.65–0.72 with hover at 0.90 gives both vivid art at rest and a clear response on hover.
The 0.28 value was originally chosen to keep the entry cards feeling consistent with the dark venue palette — the artwork was intentionally dimmed so the text and badges would pop. With two cards that worked; with four vivid student animations (iris, weightlifter, ocean, shark), the artwork itself is the selling point and the dim is working against the page.
This is a common design evolution: what works for a sparse layout becomes a problem as the content richens. The session is also a reminder that opacity on a background div is a powerful but invisible control — it lives in the CSS, not in the image, which is why it’s easy to overlook when the images themselves look fine in isolation.
We’ve made some changes to the Tool Time ecosystem and we’ve added to the chatlog. The ‘About this Chatlog’ area needs updating. We introduced a Session (28) concerning the UX and some CSS styling. Our deliverable will be an updated ‘About’ area that goes up through Session 28. Add this to our chatlog too. (Another deliverable, ironically 29, so that will need an update in the About section too!)
A short, practical maintenance prompt with one genuinely delightful moment.
.tt-entry-thumb-bg { opacity: 0.28 }).Every index that describes a growing document has this property: the act of updating the index is itself an event that the index must describe. In software this is called a fixpoint or quine-like situation. In plain English: “to fully update the About section, you must add Session 29, but adding Session 29 means the About section is not yet fully updated.” The resolution: update the About section to include Session 29 in the same edit that creates it. Which is what this session does.
I am building a collection of entries in Tool Time. I have provided you with an overview of the ecosystem, the home page and the chatlog. You are an experienced computer science teacher, a web developer and are developing talented software engineers to be hired in cutting edge AI-based companies. I’m thinking about putting an entry into the Tool Time ecosystem that is just an image, such as the one I’ve attached here. The thought is that a novice should be able to take that starting place and ‘vibe code’ a webpage that renders the output without using the actual image. It would be created solely with HTML and CSS. This is a slight variation from what we’ve done so far, but it seems like a very important and CRAFT-y skill. What are the pros and cons of featuring such projects? To me, it would be a great way to learn HTML and CSS from a reverse engineering approach, as we mention in our about page (attached). Use a list or a table to layout the arguments for including or excluding such projects. Of course, add this prompt to our chatlog along with a critique/grade of how it measures up to our CRAFT prompting scheme.
TTG’s richest context-setting yet. The role specification is the best in the series. One recurring gap keeps the grade from clearing the bar.
The C.R.A.F.T. self-reference at the end is the most reflexively aware move in the entire chatlog. The prompt asks to be graded by the same framework it uses. Session 1 had none of it. Session 30 bakes it in as a natural instinct. That is thirty sessions of growth made visible in a single parenthetical.
The “Zero Talent” image is a black rectangle with centered white bold text — a title, two decorative rules, and ten list items. It is 100% reproducible in HTML and CSS without a single line of JavaScript or a single <img> tag. That is precisely what makes it interesting. Here is the case for and against making this a Tool Time entry type.
| ✅ Arguments FOR Including Image-Only HTML/CSS Entries | ⚠️ Arguments for Caution / AGAINST |
|---|---|
| 1. Purest reverse engineering in the collection. TNT’s stated philosophy is “reverse engineering + immersive coding.” An image gives no structural clues — only the output to match. That is textbook reverse engineering. | 1. Breaks the established premise. All four existing entries start with “novice code that works.” An image entry has no original code to copy, run, and improve. The model shifts from improve what’s there to create from scratch to match a target. |
| 2. Zero setup barrier. HTML and CSS need no library, no IDE, no terminal, no runtime. Open a browser, write a text file. The lowest barrier to entry in all of web development. | 2. S.P.A.R.K. is an improvement framework. “S — Set the goal of improving this code” works when there is code. Starting from an image requires reframing Step 1 or flagging the departure explicitly in the entry. |
| 3. Immediate visual feedback loop. A CSS change renders in milliseconds — no compilation, no runtime errors. That tight loop is one of the most motivating learning experiences in coding. | 3. Success criterion is vague without a rubric. “Does it look like the image?” needs definition. 80% similar? Pixel-perfect? Is a web-safe font acceptable if the exact font is unknown? Ambiguous targets frustrate novices. |
| 4. Ideal vibe-coding starter. Describing what you see (“bold white text, centered, black background, ten items”) maps directly to what an AI needs to produce HTML/CSS. This may be the cleanest possible C.R.A.F.T. prompt scenario for a beginner. | 4. Different discipline, different audience. The four existing entries are animated p5.js sketches. A static poster is tonally different. Visitors expecting interactive art get a typography exercise. Both are valid; they are not the same experience. |
| 5. Teaches a real professional skill. Front-end developers pixel-match Figma mockups and design specs every day. This is a core competency at exactly the AI-era tech companies named in the prompt. | 5. May warrant its own label or sub-section. If this format grows, it is different enough from animated-code improvement to warrant a distinct identity — not just a card in the same gallery without a distinguishing badge. |
6. Natural CSS concept coverage. This image alone forces font-weight, text-transform, letter-spacing, flexbox, color, border-bottom, and the box model — arising from real need, not a worksheet exercise. |
6. Copyright precedent for sourced images. This poster is a generic motivational design with no clear attribution. Establishing a pattern of using third-party images as reproduction targets may need a policy before the collection grows. |
| 7. The image content earns its place. “10 Things That Require Zero Talent” — Being On Time, Making an Effort, Having a Strong Work Ethic — is thematically on-brand for TNT. The content of the entry is the character lesson. | 7. No “run it” moment. The current entry template anchors on a live running version of the original sketch. A static poster has no such hook. The animation “wow factor” that sells the existing entries is absent. |
| 8. Exercises all five C.R.A.F.T. elements cleanly. Context (describe the image) → Role (front-end dev) → Action (reproduce this layout) → Form (HTML + embedded CSS) → Tight Constraints (no JS, no images, web-safe or Google fonts only). Five for five in one prompt. | 8. Scaffolding needed for cold entry. Unlike reading code for structural clues, an image gives none. A novice with no HTML vocabulary may not know where to start — even with AI help. An orientation paragraph is essential in the entry. |
Bottom line: The case for inclusion is strong, but the pedagogical model is genuinely different enough to warrant a clear signal — a badge (“HTML/CSS Challenge” vs. “Code Improvement”) on the gallery card, or a dedicated sub-section — so visitors know this entry type starts from zero. The “Zero Talent” image is a textbook first candidate: flat black background, bold centered text, ten list items of graduated width, achievable in roughly 30 lines of HTML and 20 lines of CSS. That scope is ideal for a first vibe-coding session.
Tool Time now has two entry models, not one. Model 1: novice code that works, improved with AI — the original format. Model 2: an image as a visual spec, reproduced in HTML/CSS with AI guidance — the new format. Both teach prompting. Both teach reverse engineering. Both require the student to write the prompt and own the result. The key difference is the starting artifact: code vs. image.
The practical recommendation: Label the new type clearly on the gallery card (a small badge is enough) so the distinction is visible without requiring a separate sub-section. “HTML/CSS Challenge” vs. “Code Improvement” — two words, no confusion.
C.R.A.F.T. connection: The image-to-HTML/CSS format is uniquely well-suited to teaching all five C.R.A.F.T. elements in a single student prompt. Context, Role, Action, Form, and Tight Constraints all map naturally to reproducing a visual spec. Consider making this explicit in the entry itself as a C.R.A.F.T. scaffolding guide.
Continuing our dialog about the ‘image to code’ inquiry: Keeping with our ‘Tool Time’ metaphor with ‘Tim the Tool Man Taylor’ this sort of entry fits if one considers that Tim sees a picture of something he wants to build with his large collection of tools. He’s not starting with something, he’s building something from scratch. With modest language descriptions in the home page, I can see this working. I agree we’d need a badge indicator. However, this sort of inclusion is a powerful way to create code from only a visual reference point. Given what you have said, I’m proposing we move forward with this sort of entry in the Tool Time space, but I want you to push back on me again to force me to carefully consider the implications of this choice. It’s the purest form of reverse engineering and verbal description I can think of. Novices can bring their own images to code, giving them more ownership in the process.
A sophisticated follow-up. The single best AI-collaboration instinct in the series so far: using the tool as a devil’s advocate rather than a validator. A cluster of missing elements holds it below A.
The intentional adversarial ask is the most mature AI-collaboration move in the series. Session 1’s “Before you do any actual development, let’s discuss” was a guardrail. Session 31’s “I’m moving forward — now push back” is a stress test. They are the same instinct, thirty sessions more refined.
1. The Tim metaphor cuts both ways — and it cuts against you here.
Tim seeing a picture and building from scratch is the show’s setup for disaster, not its success story. Every episode where Tim skipped Al’s process and built ambitiously from a mental image ended with something exploding. The existing Tool Time entries follow Al’s model: here is something that works, let us make it better with method. The new entry type follows Tim’s model. Who is Al in this scenario? The student has no working code to cross-reference, no output to interrogate. They only have the image and an AI that will confidently produce whatever they describe — right or wrong.
2. “Novices can bring their own images” is a Pandora’s box.
This is the most consequential sentence in the prompt. Right now every entry is a named student’s original code — known provenance, controlled quality, social proof. Opening to student-submitted images means: copyright exposure (brand logos, movie posters, UI screenshots will arrive); reproducibility filtering (photos and complex illustrations are not CSS-achievable); and loss of the attribution model that makes entries feel personal. Build the first entry yourself to define what “good” looks like before opening any submission pathway.
3. “Verbal description → AI → code” is not the same as learning CSS.
A student can produce a near-perfect reproduction of the Zero Talent poster without understanding a single CSS property. They describe it; the AI writes it; they paste it in. That is a prompting skill — real and valuable — but it is not CSS comprehension. In the existing entries, students copy working code, trace each part, and improve specific pieces. There is comprehension at every step because the code exists and can be read. Image-to-code can bypass comprehension entirely, and the student would never know the difference. Be honest about which skill this actually develops.
4. The badge solves the gallery problem. It does not solve the chatlog arc.
Every existing entry chatlog has: original code with a copy button, a live running version, a S.P.A.R.K. improvement arc, and a before/after comparison. An image-to-code entry has none of these. The structural gap will be discovered mid-build. Design the chatlog format for the new entry type before building Entry #5 — not during.
5. You have not field-tested the difficulty level.
The dominant font in the Zero Talent image is a heavy condensed sans-serif — likely Impact or a similar commercial face. The closest freely available Google Fonts (Oswald, Barlow Condensed, Anton) are visually distinct. A novice who can clearly see the gap between their version and the original may feel they failed even if their HTML/CSS work is technically sound. Build it yourself first. Time it. Evaluate whether the output feels like success or like a frustrating approximation.
6. You are expanding the format before the first format is proven.
Four entries. The venue has been live for two days. TNT Adventures ran for years before getting structural variations. What does a visitor experience when entries 5 through 8 are an unannounced mix of “code improvement” and “image to code”? A badge helps, but it does not eliminate the cognitive overhead of two fundamentally different entry contracts in the same gallery.
7. The strongest version of this idea deserves more than a badge.
If image-to-code is genuinely “the purest form of reverse engineering and verbal description” — and it may be — then dropping it into the existing gallery as a badged card undersells it. A concept this distinct may deserve its own named section, its own intro, and its own arc within the Tool Time venue. The badge is the minimum viable solution. Consider whether minimum viable is what you actually want here.
None of the seven challenges dispute the core idea. What they challenge are its boundaries and preconditions:
| Challenge | The Underlying Concession |
|---|---|
| Tim metaphor cuts both ways | The frame works with explicit Al scaffolding in the entry design |
| Student images = Pandora’s box | Teacher-curated images first; submission pathway later with guidelines |
| Verbal description ≠ CSS skill | Be explicit in the entry about which skill it develops |
| Badge doesn’t solve chatlog arc | Design the entry template before building |
| Difficulty level untested | Build it once; prove the scope before publishing |
| Second format too early | Valid concern about timing; not a reason to reject the format |
| Deserves more than a badge | The idea is strong enough to earn its own named presence if the format grows |
Asking for pushback is not the same as asking to be stopped. TTG’s decision to invite adversarial analysis before committing is the right move — the same instinct that produced “before you do any actual development, let’s discuss” in Session 1. Thirty sessions later, it is more deliberate and more targeted.
The seven challenges do not say “don’t do it.” They say: design the entry template first, field-test the difficulty, keep curation teacher-controlled initially, and be honest in the entry about which skill it develops. These are preconditions, not objections.
The Tim metaphor, reframed: Tim does build from a picture — but in the show, the successful builds are the ones where Al is standing next to him at every step with the safety procedure. The entry design needs to build Al into the scaffolding, not assume the student finds him on their own.
I am speaking to you as a web developer and co-creator at TNT. I just received an entry from a novice, Beau. He was inspired by Prince’s hit, Purple Rain, and made a p5js/JavaScript app to evoke that imagery. I’d like it to be our next Tool Time entry, #5, after Ethan’s Baby Shark app, attached as an exemplar entry to model after. I have attached our Tool Time home page and its chatlog for perspective. You can use beauPurpleRainSketchOrig.js as you create: 1) beauPurpleRainOrig.html, 2) beauPurpleRainOrigStyles.css and if necessary, 3) beauPurpleRainOrigScripts.js. You will see the parent folder for this app, BeauPurpleRain with subfolders for the various files for organization. The hero image for the app and chatlog is in the images subfolder, and attached here. As we did with Ethan’s Baby Shark, we want to be able to copy Beau’s code into p5js editor and it work, right out of the gate. As you develop this app, we’ll also want, as a deliverable: 4) beauPurpleRainChatlog.html with 5) beauPurpleRainChatlogStyles.css to chronicle its development and train us on the best practices of vibe coding, starting with this prompt which you will grade and critique on top of the wiring of Beau’s app into Tool Time. Ethan’s chatlog should guide you into the layout and styling of the chatlog, which in some senses, is the most important element in this endeavor.
The strongest entry-build prompt in the series. One 31-session streak broken. One gap that has been flagged every time remains.
.parent() calls. The constraint is stated without needing to explain what it means.Grade rationale: A. The numbered deliverables list closes a 31-session gap. Sketch behavior is the only gap that has never been closed in the entry-build series. One sentence describing what Beau’s sketch does is the last step to A+.
| Decision | Resolution |
|---|---|
| Color identity | Purple rain color (stroke(147,51,234)) → --pr-purple: #9333ea. Lyric color (fill(220,180,255)) → --pr-lavender: #dcb4ff. Background --pr-night: #080010. All palette values come from Beau’s sketch. |
| Canvas 450→400 | Reduced for showcase layout. All elements use width/height throughout; resize is cosmetic. textSize(24) is a magic number but fits 400px comfortably. |
frameRate() with no arg | Preserved exactly as written. Benign no-op — reads but does not set the frame rate. Default 60fps unchanged. Noted in entry chatlog as a classroom discussion point. |
| Separate CSS files | beauPurpleRainOrigStyles.css + beauPurpleRainChatlogStyles.css. Separation-of-concerns principle from Session 22. |
| Gallery card | Entry #5 added to toolTimeHome.html. 🌧️ emoji, “Purple Rain” title, Beau/CS Innovations Studio attribution. |
The numbered deliverables list finally appears. Thirty-one sessions of flagging this as a recurring gap; Session 32 closes it. The change is not cosmetic — a numbered list of output files makes the deliverables contract unambiguous, verifiable, and impossible to partially fulfill without noticing. This is why the critique has raised it consistently: the format exists to prevent ambiguity, not just to look organized.
Beau’s sketch: 97 lines, five clearly commented sections, 80 purple raindrops, a 6-phase RGB color cycle on the cloud, a floating bounce, and Prince’s lyrics at the bottom. The code is clean, well-organized, and honest — the numbered sections signal Beau was thinking structurally. frameRate() with no argument is the only genuine curiosity in the whole sketch.
The series now has five entries: Jackson’s Iris, Sean’s Weightlifter, Sebastian’s Ship, Ethan’s Baby Shark, and Beau’s Purple Rain. Each one adds a new teachable moment. Each chatlog is a lesson in prompting. The venue is working exactly as designed.
I’m anticipating adding entries to Tool Time regularly, perhaps 1–2 per week. As a UX specialist would you advise me to announce each entry in news.html, or a cluster of them, or none at all? I’m leaning to not adding them there, much like I don’t mention every movie clip I add. Novices know the ecosystem exists and when I teach them, I direct them there anyway. What is your perspective on this aspect of our site? Add the analysis to our chatlog and update the about area there while you are at it.
Clean role specification, a well-framed three-option question, and a stated lean that shapes the response without closing it. One notable gap: the CRAFT self-critique request — present in every session from 10 to 32 — is absent here for the first time since it became instinctive.
Your instinct is correct. The movie clips analogy is the right one. Here is the principle behind it.
news.html is a site-level event log. An individual Tool Time entry is a content-level addition. The distinction is the right one to make, and it holds across every venue on TNT:
| Site-level event → news.html | Content-level addition → venue gallery only |
|---|---|
| Tool Time venue launches (Entry #090 — done ✅) | Entry #4 — Ethan’s Baby Shark added |
| Tool Time reaches 10 entries | Entry #5 — Beau’s Purple Rain added |
| First HTML/CSS image-reconstruction entry ships | Entry #6 added |
| Tool Time expands beyond p5.js (first Java entry, etc.) | Entry #7 added |
| Movie Clips venue launched (past event) | Individual movie clip added |
| Adventures venue launched (past event) | Individual adventure added |
The pattern is consistent across the entire site. Every venue on TNT was worth a news announcement at launch; no individual piece of content inside a venue is worth one.
The signal-to-noise argument. At 1–2 entries per week, individual announcements would add 60–100 news entries per year from Tool Time alone. Within one semester, Tool Time entries would dominate the news page — visually crowding out site-level news (redesigns, new courses, major milestones). A visitor to news.html would encounter a Tool Time feed rather than a site broadcast. That is the wrong mental model for a news page.
The gallery IS the announcement mechanism. A new entry card appearing in the Tool Time gallery is its own announcement. The “On the Workbench” teaser that already exists in toolTimeHome.html handles the “coming soon” signal. Visitors who care about new entries check the gallery; visitors who care about site news check news.html. These are different visitors with different expectations, and the current architecture serves both correctly.
Three cases that DO belong in news.html:
- Milestones. “Tool Time hits 10 entries” — a site-level signal that the venue is thriving. Worth one paragraph and a link.
- Format expansions. When the first HTML/CSS image-reconstruction entry ships, that is a new kind of learning activity, not just more of the same. New pedagogy → site event.
- Pedagogical innovations. If a session produces a teaching artifact that stands on its own (the A+ prompt rewrite exercise, the token economics analysis), a news item pointing to it is appropriate — not because an entry was added, but because a teaching resource was created.
The rule: Ask “would a first-time visitor to TNT care about this?” If yes → news.html. If only a returning visitor who already knows Tool Time exists → gallery only.
The formal policy, established here: Individual Tool Time entries do not go in news.html. Milestones (10 entries, 25 entries), format expansions (first new entry type), and standalone pedagogical artifacts (a teaching document that emerged from an entry session) may. The default is: content update → gallery; site event → news.
Why the instinct was right. TTG’s movie clips parallel is not just a useful analogy — it reveals an existing implicit policy that has been applied consistently across the site. The movie clips page, Adventures, Styl’n, JS Apps, Processing — none of these announce individual content additions in news. Tool Time is not a special case; it is the same pattern applied to a faster-moving venue.
The broader lesson for site design: Every surface on a site has an audience and a contract with that audience. The news page’s contract is “this is what changed at the site level.” The gallery’s contract is “here is the content.” Mixing content updates into the news page breaks the news page’s contract without improving the gallery’s. Two surfaces. Two audiences. Honor both.
I’m returning to our discussion about whether or not to include raw images in Tool Time entries and you’ve convinced me that while the idea is sound, the place is not in keeping with our Tool Time ecosystem. You are a web developer, co-creator at TNT, and a computer science teacher who wants novices to know fundamentals but also to leverage powerful AI tools to create ‘masterpieces’. With this in mind, what would be your top 5 proposals for how I have such an ecosystem in TNT: a place where, starting with an image, a novice coaxes AI to produce a facsimile of that image using HTML and CSS? Since we usually have a ‘hook’ or motivating movie clip for our TNT components, what might that be as well? I do have an image gallery already, so that might be an idea launching pad, since some of those images might be candidates for this endeavor. Our zero effort image would likely be our first entry in this ecosystem: I tested it and got a great first pass of a webpage.
The role qualifier “who wants novices to know fundamentals but also to leverage powerful AI tools to create masterpieces” is the most nuanced role instruction in the series. It names the pedagogical tension this venue sits inside. Everything else is strong. Two gaps hold it from A.
The existing image gallery at tnt_image_gallery.html already contains at least 8–10 images that are essentially CSS exercises waiting to happen: Zero Talent, Fonts Matter, Radical Rules, S.P.I.D.E.R. Protocol, Rendered Written Colors, Mission Venn, Stepped Circles. The venue design question is really about how to organize the relationship between the gallery (source) and the new venue (workshop). Here are five distinct proposals:
Tagline: “You look at it and see a poster. Learn to look at it and see display:flex; font-weight:900; background:#000.”
Concept: The Matrix red-dress monologue as a curriculum. Every image is two things: what a human eye sees and what a browser renders. The venue teaches the transition — the moment when a student stops seeing the picture and starts seeing the layout, the typography rules, and the box model beneath it.
Format: Image on the left, live HTML/CSS render on the right. The gap between them is the lesson. Students iterate until the gap closes. Gallery provides source images; a 🔨 “Build It” badge marks images that have live “See the Code” entries.
Tagline: “The gallery shows you the picture. The Reverse Gallery shows you how to build it.”
Concept: The image gallery is already built. Reverse Gallery is its active companion — each gallery modal gets a “🔨 Build It” link when a challenge entry exists. The gallery becomes a navigation surface; the workshop is behind every image.
Why it works: No new navigation item required for the source images. Turns the existing passive gallery (view) into an active practice venue (build). Launch with 3–4 entries; the gallery badge grows over time.
Tagline: “Real designers build posters. You’ll build them without Photoshop, without Canva, and without a single image file.”
Concept: Scoped specifically to typographic posters — the gallery category with the most CSS-eligible images. Teaches font-weight, font-family, letter-spacing, text-transform, flexbox, color, and border-bottom through real poster recreation. Entry #1: Zero Talent. Entry #2: “Fonts Matter” — a poster about fonts, recreated with CSS fonts. The meta-quality is irresistible.
Why it works: Narrow scope, learnable skill set, concrete success criterion. 8–10 gallery images are immediately eligible.
Tagline: “In the real world, your boss emails you a screenshot. Your job is to build it. This is that class.”
Concept: Frames image-to-code as the professional front-end skill it is. Matching a design spec (Figma, Zeplin, a screenshot) is what junior developers do on Day 1. Blueprint teaches it through gallery images used as “design specs.” The CRAFT framework is built directly into the process — Context (describe the image), Role (front-end developer), Action (build this spec), Form (HTML + CSS), Tight Constraints (no JS, no image tags).
Best for: The hiring-skills angle. Connects image-to-code to industry reality rather than academic exercise.
Tagline: “Every image has a poem written in HTML and CSS. Your job is to find it.”
Concept: A more artistic framing — students are translating, not copying. Natural difficulty tiers emerge: Haiku (~20 lines, typographic poster), Sonnet (~50–80 lines, moderate layout), Epic (100+ lines, complex design). The tier system creates a progression ladder without a formal curriculum. Zero Talent is a Haiku; Mission Venn (CSS circles) is a Sonnet; The Mandelbrot Set is an Epic.
Best for: Students who respond to creative/artistic framing over technical framing.
Scene: Tank (or Cypher) watches the code cascade and says: “I don’t see blonde, brunette, redhead anymore. I just see the code.” About 90 seconds. No violence. Widely available.
Why it’s the right hook: The metaphor is exact. The scene is literally about learning to see beneath surface appearance to the underlying structure — which is precisely what this venue teaches. A student learning to see font-weight: 900 when they look at a bold poster headline is doing exactly what Tank describes. The clip is culturally iconic; students know it and respond to it.
Alternative: The Paycheck (2003) clip already in TNT — Michael Jennings reverse-engineering from visual artifacts. Weaker metaphor but no new clip acquisition needed.
Recommendation: See the Code for the venue name and Matrix hook — structured as a Reverse Gallery (so the existing image gallery handles source navigation) — starting with the Print Shop scope (typographic posters only for Year 1).
Why: The name is memorable. The hook is cinematically perfect. The gallery infrastructure already exists and removes the curation burden from the venue itself. The typographic-poster scope gives a learnable, teachable Year 1 with 8–10 gallery candidates already eligible. And “Fonts Matter” as Entry #2 — a poster about fonts, recreated entirely in CSS font properties — is one of the best natural teaching moments available anywhere in the TNT ecosystem.
Connection to the About Us page: TNT’s stated philosophy is “reverse engineering + immersive coding.” The Paycheck clip on the About page is already about reverse engineering from visual artifacts. This venue is the applied classroom expression of that philosophy: start with the end product, work backwards to the code. It is not a new idea for TNT — it is the oldest TNT idea, finally given its own venue.
You are helping me as a web developer, APCS(Java) teacher and co-developer at TNT. You have the context of the Tool Time ecosystem, its accompanying chatlog and a previous entry featuring ‘Purple Rain.’ This time, however, we are featuring a Java snippet that we want to upgrade. We’d like to be able to copy it into JDoodle and run it but it’s pretty lean so we’re hoping to inspire our APCS novices to ‘vibe code’ it to a better place! I’ve provided a background image for the hero and the entry card that’s Stooge thematic. The snippet features the comedy troupe: The Three Stooges. Since there is no p5js this time, we just need to showcase the Java code attached. Use the same style we used in our app featuring Grayson’s song. The Java code is shown with the blue striped source code with the copy button. Let’s call this file: threeStoogesOriginal.html with affiliated threeStoogesOriginalStyles.css and threeStoogesOriginalScripts.js. As we did for Beau’s work, we also want a threeStoogesChatlog.html with threeStoogesChatlogStyles.css. Since this is the first time we are offering a Tool Time entry that’s not p5js (its solely Java), let’s update our toolTimeChatlog.html file to celebrate this new facet. It was developed by me, TechToolsGuru also, so it’s not novice based this time. Add this prompt to our Tool Time chatlog and our threeStoogesChatlog and as before, critique the prompt and give it a grade. After novices get help from their AI-Assistant, they should be able, to add additional ‘stooges’ to an ArrayList without any duplicates, and have better understanding of what the main header means in Java driver code when it says: public static void main(String args[]). Therefore, give them some ideas on what to mention to AI to get this app to be more impressive. Encourage them to look at our movie clips page for our ‘TNT Legacy Thanksgiving’ entry because it links to some Three Stooges antics they might enjoy!
Entry #6 marks a significant expansion of Tool Time’s scope. The first five entries were all p5.js/JavaScript. Entry #6 is pure Java — a console driver class with no visual canvas, no browser sketch, no p5.js dependency whatsoever. This opens the venue to APCS Java students whose coding happens in a very different environment.
The same Tool Time philosophy applies: show lean original code, celebrate what it does well, flag what it could do better, give students a concrete AI-assisted path from here to there. The entry uses JDoodle instead of editor.p5js.org, a blue-striped code terminal instead of a split canvas layout, and APCS-specific challenges (ArrayList, no-duplicates pattern, main-signature breakdown) instead of p5.js animation ideas.
The original Java source contains System. out.println with a space between System. and out. This is a genuine compile error that Java will flag immediately. Rather than fix it silently, the entry preserves the bug exactly and calls it out in a prominent red warning box. Students who copy and paste into JDoodle experience the error first-hand, find it, fix it — and are unlikely to make the same mistake again. Real discovery beats being told every time.
The entry chatlog includes three ready-to-use C.R.A.F.T. prompt starters for students:
- Fix + explain main: Find the compile error, explain every word of
public static void main(String[] args), and produce a hardcoded version for JDoodle. - ArrayList with no-duplicates: Refactor to
ArrayList<String>using.contains()before.add(); add Shemp; test duplicate guard. - Add a Scanner: Accept keyboard input in a while loop with a sentinel; add names only once.
The Three Stooges Driver entry establishes the Java-only Tool Time template: blue-striped code terminal, no canvas, JDoodle link, APCS-targeted Your Turn section, entry chatlog with C.R.A.F.T. prompt starters. Any future Java entry can follow this pattern directly.
Full entry chatlog: threeStoogesChatlog.html — includes two sessions: Session 1 (build + prompt critique, Grade A−) and Session 2 (three ready-to-use vibe-coding prompt starters for APCS students).
With Entries #6 (Java) and #7 (Python), Tool Time now spans three language families: JavaScript/p5.js (Entries #1–5), Java (Entry #6), and Python Processing (Entry #7). Each language has its own code display color identity following the GraysonsSong creative cross-training convention: yellow = JS, blue = Java, green = Python.
The full entry chatlog is at xmasLightsChatlog.html — Session 1 covers the build and prompt critique (Grade A); Session 2 provides three ready-to-use AI prompt starters for the Christmas tree adventure.
I can see our Tool Time home page growing rapidly, and it would be helpful to have a search/filter option like we’ve used in the processing page and image gallery page. We should be able to search for a keyword, constrained by a filter. The current list of filter options would include p5js Processing, Java and Python Processing, but I’m certain we will have HTML, CSS, JavaScript, Java Processing and Python and Python Turtle Graphics entries in the future. You are a web developer, UX specialist and co-creator of TNT apps. Let’s incorporate this functionality now, while there are not that many entries to contend with. Please add this prompt, its grade, critique and your work in our chatlog for Tool Time.
A well-scoped infrastructure prompt with good exemplar references and clear future-proofing intent. The “while there are not that many entries” rationale is excellent product thinking. Minor gap: no form or tight constraint on what the filter UX should look like.
✅ Strengths
⚠️ Growth Areas
Grade rationale: A−. The future-proofing requirement and timing rationale are excellent product-thinking. The form gap (what the filter UI looks like) is the main deduction.
- toolTimeHomeStyles.css — added
.tt-search-bar,.tt-search-input,.tt-count-badge,.tt-filter-strip,.tt-filter-btn,.tt-active,.tt-future(dimmed placeholder buttons),.tt-no-results - toolTimeHome.html — search input + count badge; 9 filter pill buttons (5 current: All / p5.js / JavaScript / Java / Python Processing; 4 future-dimmed: HTML / CSS / Java Processing / Python Turtle); no-results paragraph;
id="ttEntryGrid"on the row - Each entry column —
class="tt-entry-col"anddata-langs="..."added to all 7 entries (p5js javascript × 5, java × 1, python × 1) - JavaScript — pre-computes
data-searchtextfrom card text content on load;applyFilters()combines text query AND language filter;ttFilter(lang)toggles active button and re-runs filters; count badge updates live
There are currently 7 entries. When the ‘All’ filter is on, there should be ‘7 entries’ as the total. Currently it’s ‘3 entries.’ Let’s fix that first.
The HTML structure has two separate Bootstrap row divs inside the entries section:
<!-- Row 1 — got the id; contains Entries #1–3 -->
<div class="row g-4" id="ttEntryGrid">
...entries #1, #2, #3...
</div><!-- /row (after Entry #3) -->
<!-- Row 2 — no id; contains Entries #4–7 -->
<div class="row g-4 mt-0">
...entries #4, #5, #6, #7...
</div>
The filter JavaScript used '#ttEntryGrid .tt-entry-col' as its selector. This only queries inside the first row div (the one with the id). The second row has no id, so its four entries are completely invisible to the query — they will never be counted, searched, or filtered.
The fix — one word: Change #ttEntryGrid to #ttEntries in the JavaScript selector. #ttEntries is the parent <section> element that wraps both rows. The selector '#ttEntries .tt-entry-col' finds all entries regardless of which row they live in.
// Before — only sees 3 entries (first row only):
var cols = Array.from(document.querySelectorAll('#ttEntryGrid .tt-entry-col'));
// After — sees all 7 entries (both rows, via section parent):
var cols = Array.from(document.querySelectorAll('#ttEntries .tt-entry-col'));
The lesson: When you add a targeted search/filter to a page, the query selector must scope to the highest reliable container, not a specific inner element. The section tag (#ttEntries) is stable — it will always wrap all entries regardless of how many internal rows are added. A specific row div is fragile — it only covers entries added to that row. This is a case where the infrastructure break was planted by an implementation detail of how early entries were grouped into separate rows as they grew.
“Java” entries are different than “JavaScript” entries. The “JavaScript” filter works as expected. The “Java” filter shows Entry #6 as it should but also all the other entries flagged as “JavaScript.”
The filter code compared the active filter value against the data-langs string using String.indexOf():
var langs = 'p5js javascript'; // ← data-langs value for Entry #1
var langOk = langs.indexOf('java'); // → returns 5 (found as SUBSTRING of "javascript")
// Result: Entry #1 matches the 'java' filter — incorrect!
indexOf() checks for the presence of a substring anywhere in the string. The string 'java' exists inside the string 'javascript' at position 0. So every entry tagged javascript also matched java. The JavaScript filter worked correctly in the other direction because 'javascript' is NOT a substring of 'java' — the asymmetry made it invisible until Java entries existed.
The fix — split into tokens and compare exactly:
// Before — substring match: 'java' found inside 'javascript' var langs = (col.dataset.langs || '').toLowerCase(); var langOk = currentLang === 'all' || langs.indexOf(currentLang) !== -1; // After — token array: check for exact whole-word match var langs = (col.dataset.langs || '').toLowerCase().split(/\s+/); var langOk = currentLang === 'all' || langs.indexOf(currentLang) !== -1;
split(/\s+/) converts the string 'p5js javascript' into the array ['p5js', 'javascript']. Array.indexOf('java') then checks for an exact element match — 'java' is not in that array, so it correctly returns -1. Entry #6’s data-langs="java" splits to ['java'], which does contain 'java' exactly.
The lesson: String.indexOf() is a substring search — it will find 'cat' inside 'concatenate'. When you need to check for whole tokens in a space-separated list, always split first and use Array.indexOf() for exact element comparison. This same class of bug affects CSS class checks ('btn' found inside 'btn-primary'), tag matching, and any token-list filter built with string search.
Let’s add another filter: Python 3 to our list of filter buttons, as well as an ‘Other’ in case we have some anomalies that have no specific classification cubby.
Python 3 (data-lang="python3") — added as a dimmed future button (tt-future). This distinguishes standalone Python 3 programs (scripts, data work, command-line tools) from Python Processing entries, which use the Processing IDE’s Python Mode and are tagged python. Both coexist in the filter strip; neither is a substring of the other, so the token-split fix from Session 39 keeps them cleanly separated.
Other (data-lang="other") — added as a full-opacity button (not dimmed), because it is a permanent utility category, not a future language placeholder. Any entry that genuinely defies the existing language classifications gets data-langs="other" and will be found only by this button. Currently returns zero results, which is the expected honest behavior. To use it: add other to an entry’s data-langs attribute.
I would have never thought about a ‘button’ filter strip in this design. I had anticipated (and wasn’t following my CRAFT rule very well) that you’d use a select menu option like you did in the askCopilot page. At this point, I like the button filter better in this circumstance. As a UX specialist and web designer and software engineer, why did you go with the button filter over a drop-down menu? Discuss the pros and cons of each approach.
The single most important factor: discoverability. A filter strip shows all available options simultaneously without any interaction. A visitor to the Tool Time home page sees instantly that there are Java, Python, and p5.js entries — before they touch anything. With a dropdown, those categories are hidden behind a click. Users who do not know they exist will not look for them.
The second factor: active state visibility. When a filter button is active, it glows in the amber Tool Time palette. The currently active filter is visible from across the room. With a dropdown, you must read the selected value inside the control to know what filter is active — a small friction that compounds when you switch filters rapidly.
Context also mattered: this section has one primary interactive feature (filtering entries). When filtering is the main job of a UI zone, the filter controls should have presence on the page — they should communicate “this is something you can do here” without requiring the user to discover the affordance. The askCopilot select menu works because filtering is one of many things on that page, space is tight, and the topic list is long (50+). Here, the filter is the hero of the section and the option count is small enough to show all at once.
| Factor | Button Strip ✔ | <select> Dropdown ✔ |
|---|---|---|
| Discoverability | All options visible immediately | Hidden until clicked |
| Active state | Highlighted button always visible | Must read the control to see current value |
| Vertical space | Uses more space; wraps on small screens | Compact — one line always |
| Many options (15+) | Gets crowded; starts to lose value | Scales cleanly to 50+ options |
| Mobile usability | Buttons need careful sizing | Native OS picker — excellent UX |
| Multi-select | Natural (toggle multiple buttons) | Complex with standard <select> |
| TNT page consistency | Matches gallery, processing pages | Matches askCopilot (different context) |
| Filter is primary UI | Appropriate presence on page | Understated — better when filter is secondary |
Rule of thumb: use buttons when options are ≤12, always-visible, and filtering is the primary interaction. Use a dropdown when options exceed ≈15, space is tight, or filtering is one of many competing controls.
TTG noted they “weren’t following CRAFT very well” because the prompt gave no Form constraint for what the filter UI should look like. This is a good self-catch. “A search/filter option like we’ve used on the processing page” references text-search only (the processing page has no filter buttons). “Like the image gallery page” would have pointed at type-filter buttons. Because both exemplars were named and the processing page search was listed first, either interpretation was defensible — the button strip was chosen because it better matched the gallery pattern and the Tool Time context. Specifying “pill-style toggle buttons matching the amber palette, consistent with the gallery’s DWR/Eureka buttons” would have guaranteed the desired shape with zero ambiguity.