<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: John</title>
    <description>The latest articles on DEV Community by John (@asx).</description>
    <link>https://dev.to/asx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3422762%2F59ef83cf-e027-46ce-a59f-b6b771901029.png</url>
      <title>DEV Community: John</title>
      <link>https://dev.to/asx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/asx"/>
    <language>en</language>
    <item>
      <title>Weekend Challenge: Dog Days Edition</title>
      <dc:creator>John</dc:creator>
      <pubDate>Fri, 14 Aug 2026 13:55:04 +0000</pubDate>
      <link>https://dev.to/asx/weekend-challenge-dog-days-edition-bark-gallery-4jo8</link>
      <guid>https://dev.to/asx/weekend-challenge-dog-days-edition-bark-gallery-4jo8</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-08-14"&gt;Weekend Challenge: Dog Days Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built 🐶
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bark Gallery: Speed Sketch Challenge&lt;/strong&gt; is an arcade-style, browser-based community drawing and voting game built to celebrate International Dog Day!&lt;/p&gt;

&lt;p&gt;Players receive a randomized, humorous canine scenario generated using Google AI Studio's &lt;strong&gt;Gemini 3.7 Flash&lt;/strong&gt; model, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🍕 A dog caught stealing a slice of pizza&lt;/li&gt;
&lt;li&gt;🩺 A dog doctor checking a heartbeat with a stethoscope&lt;/li&gt;
&lt;li&gt;🍝 A dog chef cooking spaghetti in a chaotic kitchen&lt;/li&gt;
&lt;li&gt;🔍 A dog detective inspecting clues with a magnifying glass&lt;/li&gt;
&lt;li&gt;🏖️ A dog and a duck playing on the beach (&lt;em&gt;Duckmon&lt;/em&gt; crossover!)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🎮 The Core Loop
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;90-Second Sprint:&lt;/strong&gt; You get 90 seconds to sketch your masterpiece using our MS Paint-style spray tool, custom color palette, undo stack, and canvas controls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Arcade Dog Tag:&lt;/strong&gt; When the timer ends, sign your artwork with a custom arcade dog tag.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Community Voting:&lt;/strong&gt; Your sketch uploads instantly to the live &lt;strong&gt;Community Bark Gallery&lt;/strong&gt;, where visitors can vote in real time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❤️ &lt;strong&gt;Like&lt;/strong&gt; → &lt;code&gt;+1 point&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🦴 &lt;strong&gt;Treat / Super Like&lt;/strong&gt; → &lt;code&gt;+3 points&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Top 10 Leaderboard:&lt;/strong&gt; Scores recalculate on the fly and feed into the dynamic leaderboard!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Demo 🎮
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;strong&gt;Live Playable Game:&lt;/strong&gt; &lt;a href="https://quackworkstudios.com/doggame.html" rel="noopener noreferrer"&gt;https://quackworkstudios.com/doggame.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;Studio Site:&lt;/strong&gt; &lt;a href="https://quackworkstudios.com" rel="noopener noreferrer"&gt;https://quackworkstudios.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx34o2ne11d6x4oyjfpjt.jpg" alt=" " width="800" height="400"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Code 💻
&lt;/h2&gt;

&lt;p&gt;The complete game is architected as a lightweight, single-file client application featuring an HTML5 &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; engine, custom particle spray physics, real-time client-side JPEG compression, voting state persistence, and dynamic leaderboard sorting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Bark Gallery: Community Dog Doodles — Quackwork Studios&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"robots"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"index,follow"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://fonts.googleapis.com/css2?family=Press+Start+2P&amp;amp;family=Inter:wght@400;600;700;900&amp;amp;display=swap"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.game-section&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt; &lt;span class="m"&gt;80px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1120px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.pixel-title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f59e0b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.45rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;letter-spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.rules-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0d121c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#232d3f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#f59e0b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.rules-grid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.rule-item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex-start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.8rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#cbd5e1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.rule-num&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1a2233&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f59e0b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.7rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;flex-shrink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.game-layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;880px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;.game-layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.35&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;0.65&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.game-box&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.leaderboard-box&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.gallery-section&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#121824&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#232d3f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.status-bar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1a2233&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#2e3a50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.prompt-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;220px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.target-title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#8f9ba8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.target-breed&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.8rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fcd34d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.timer-badge&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#38bdf8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0f172a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#1e293b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.timer-badge.warning&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ef4444&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ef4444&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pulse&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;pulse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.canvas-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;480px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#f59e0b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;245&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;158&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;#drawCanvas&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;touch-action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;crosshair&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.overlay&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="py"&gt;backdrop-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.tools-bar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1a2233&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#2e3a50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.tools-subrow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.tool-selector&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.size-selector&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0d121c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#232d3f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.tool-btn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.size-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#94a3b8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="m"&gt;0.15s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.tool-btn.active&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.size-btn.active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f59e0b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0f172a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.color-swatches&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.color-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;0.15s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.color-btn&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.color-btn.active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.25&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.btn-pixel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.6rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="m"&gt;0.15s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.btn-action&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f59e0b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0f172a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;#b45309&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.btn-action&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fbbf24&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-2px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;#b45309&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.btn-action&lt;/span&gt;&lt;span class="nd"&gt;:active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;#b45309&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.btn-secondary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#334155&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e2e8f0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.btn-secondary&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#475569&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;/* Leaderboard Styling */&lt;/span&gt;
    &lt;span class="nc"&gt;.leaderboard-table&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-collapse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;collapse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.85rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.leaderboard-table&lt;/span&gt; &lt;span class="nt"&gt;th&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.6rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#8f9ba8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#232d3f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.leaderboard-table&lt;/span&gt; &lt;span class="nt"&gt;td&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#1a2233&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#cbd5e1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.tag-highlight&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.65rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fcd34d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.score-highlight&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.7rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#10b981&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;/* Gallery Styling */&lt;/span&gt;
    &lt;span class="nc"&gt;.gallery-grid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;220px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;max-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;650px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;overflow-y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.gallery-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0d121c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#232d3f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;border-color&lt;/span&gt; &lt;span class="m"&gt;0.2s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.gallery-card&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-4px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f59e0b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.gallery-img-wrap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.gallery-img-wrap&lt;/span&gt; &lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;object-fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.gallery-info&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.gallery-user-row&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.gallery-user&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.65rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fcd34d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.gallery-prompt&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#94a3b8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;white-space&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;nowrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;text-overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ellipsis&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.vote-bar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#1a2233&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.vote-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1a2233&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#2e3a50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="m"&gt;0.15s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.vote-btn&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#28364f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.vote-btn&lt;/span&gt;&lt;span class="nd"&gt;:active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;/* Modal */&lt;/span&gt;
    &lt;span class="nc"&gt;.modal-backdrop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.85&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="py"&gt;backdrop-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;999&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.modal-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#121824&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#f59e0b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;440px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e2e8f0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;245&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;158&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.modal-input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#090d14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#2e3a50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Press Start 2P'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.modal-input&lt;/span&gt;&lt;span class="nd"&gt;:focus&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f59e0b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"top-notice-bar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"notice-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🐾 DEV Weekend Challenge: Community Bark Gallery is Live!&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"brand-link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"brand-pixel-badge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pixel-cell"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pixel-cell"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pixel-cell"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pixel-cell"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"brand-name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Quackwork Studios&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-links"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/#games"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Games&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/doggame.html"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-link"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color: #f59e0b;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🐾 Bark Gallery&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"game-section"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="c"&gt;&amp;lt;!-- Title &amp;amp; Header --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-header"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-bottom: 16px; text-align: center;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pixel-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Bark Gallery: Speed Sketch Challenge 🎨🐶&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"section-subtitle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;A community-driven dog doodle showcase built for International Dog Day!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Rules Bar --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rules-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-family: 'Press Start 2P', monospace; font-size: 0.75rem; color: #f59e0b; margin-bottom: 8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          📖 HOW TO PLAY &lt;span class="err"&gt;&amp;amp;&lt;/span&gt; COMPETE:
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rules-grid"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rule-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rule-num"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Get a random canine scenario prompt.&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rule-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rule-num"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;You have &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;90s&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; to sketch using the pen &lt;span class="err"&gt;&amp;amp;&lt;/span&gt; spray tools.&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rule-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rule-num"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;3&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Sign with a &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Dog Tag&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;&amp;amp;&lt;/span&gt; upload to the gallery.&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rule-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rule-num"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;4&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Vote below: &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;❤️ Like (+1 pt)&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; or &lt;span class="nt"&gt;&amp;lt;strong&amp;gt;&lt;/span&gt;🦴 Treat (+3 pts)&lt;span class="nt"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; to top the leaderboard!&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"game-layout"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- Drawing Area --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"game-box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"status-bar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"prompt-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"target-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Your 90s Prompt:&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"targetBreed"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"target-breed"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Loading prompt...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

            &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"target-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Time&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"timerDisplay"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"timer-badge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;90s&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

          &lt;span class="c"&gt;&amp;lt;!-- Canvas Frame --&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"canvas-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"drawCanvas"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"480"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"480"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;

            &lt;span class="c"&gt;&amp;lt;!-- Times Up Overlay --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"overlay"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"overlay"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size: 3rem; margin-bottom: 10px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🎨🐾&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-family: 'Press Start 2P', monospace; font-size: 1rem; color: #fcd34d; margin-bottom: 8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;TIME IS UP!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size: 0.85rem; color: #cbd5e1; margin-bottom: 16px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Ready to publish your artwork to the Bark Gallery?&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: flex; gap: 10px; flex-wrap: wrap; justify-content: center;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"overlayRetryBtn"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-pixel btn-secondary"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🔄 Redraw&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"overlayUploadBtn"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-pixel btn-action"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;📤 Upload Artwork&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

          &lt;span class="c"&gt;&amp;lt;!-- Controls Bar --&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tools-bar"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="c"&gt;&amp;lt;!-- Tool Type &amp;amp; Brush Size Subrow --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tools-subrow"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="c"&gt;&amp;lt;!-- Tool Type --&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tool-selector"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tool-btn active"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"penToolBtn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;✏️ Pen&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tool-btn"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"sprayToolBtn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;💨 Spray&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tool-btn"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"eraserToolBtn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🧽 Eraser&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

              &lt;span class="c"&gt;&amp;lt;!-- Brush Sizes --&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"size-selector"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"size-btn"&lt;/span&gt; &lt;span class="na"&gt;data-size=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Thin&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"size-btn active"&lt;/span&gt; &lt;span class="na"&gt;data-size=&lt;/span&gt;&lt;span class="s"&gt;"7"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Med&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"size-btn"&lt;/span&gt; &lt;span class="na"&gt;data-size=&lt;/span&gt;&lt;span class="s"&gt;"16"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Thick&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

            &lt;span class="c"&gt;&amp;lt;!-- Expanded 18 Color Swatches --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-swatches"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn active"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #000000;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#000000"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Black"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #4b5563;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#4b5563"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Dark Gray"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #9ca3af;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#9ca3af"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Light Gray"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #ffffff; border: 1px solid #94a3b8;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#ffffff"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"White"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #451a03;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#451a03"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Dark Brown"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #78350f;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#78350f"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Brown"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #b45309;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#b45309"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Caramel / Tan"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #f59e0b;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#f59e0b"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Golden"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #fef08a;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#fef08a"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Cream / Yellow"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #b91c1c;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#b91c1c"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Dark Red"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #ef4444;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#ef4444"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Bright Red"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #f97316;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#f97316"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Orange"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #84cc16;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#84cc16"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Lime Green"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #22c55e;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#22c55e"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Green"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #06b6d4;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#06b6d4"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Cyan"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #38bdf8;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#38bdf8"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Sky Blue"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #2563eb;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#2563eb"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Royal Blue"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #a855f7;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#a855f7"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Purple"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-btn"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background: #ec4899;"&lt;/span&gt; &lt;span class="na"&gt;data-color=&lt;/span&gt;&lt;span class="s"&gt;"#ec4899"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Pink"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

            &lt;span class="c"&gt;&amp;lt;!-- Action Buttons Row --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tools-subrow"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: flex; gap: 6px; flex-wrap: wrap;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"undoBtn"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-pixel btn-secondary"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Undo last stroke"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;↩️ Undo&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"clearBtn"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-pixel btn-secondary"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Clear canvas"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🗑️ Clear&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"resetTimerBtn"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-pixel btn-secondary"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Reset timer and clear canvas for this prompt"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🔄 Reset&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"skipBtn"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-pixel btn-secondary"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Get a new prompt and reset timer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🎲 Skip&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"publishBtn"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-pixel btn-action"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding: 10px 14px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Upload Art 📤&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

        &lt;span class="c"&gt;&amp;lt;!-- Top 10 Leaderboard --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"leaderboard-box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"border-bottom: 1px solid #232d3f; padding-bottom: 10px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-family: 'Press Start 2P', monospace; font-size: 0.85rem; color: #f59e0b; margin: 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🏆 Top 10 Dogs&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size: 0.75rem; color: #8f9ba8; margin: 4px 0 0 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;❤️ Like (+1 pt) • 🦴 Treat (+3 pts)&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

          &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"leaderboard-table"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;thead&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;th&amp;gt;&lt;/span&gt;#&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;th&amp;gt;&lt;/span&gt;Dog Tag&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"text-align: right;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Points&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/thead&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tbody&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"leaderboardBody"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="c"&gt;&amp;lt;!-- Dynamically populated 10 items --&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/tbody&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

      &lt;span class="c"&gt;&amp;lt;!-- Live Community Gallery --&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"gallery-section"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin-top: 24px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #232d3f; padding-bottom: 12px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-family: 'Press Start 2P', monospace; font-size: 1.1rem; color: #fcd34d; margin: 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🖼️ Community Bark Gallery&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size: 0.8rem; color: #94a3b8; margin: 4px 0 0 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Browse drawings and vote for your favorites!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"galleryCount"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-family: 'Press Start 2P', monospace; font-size: 0.7rem; color: #38bdf8;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0 ARTWORKS&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"galleryGrid"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"gallery-grid"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="c"&gt;&amp;lt;!-- Dynamically populated cards --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Upload Modal --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"uploadModal"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"modal-backdrop"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"modal-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size: 2.5rem; margin-bottom: 8px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;🏷️&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-family: 'Press Start 2P', monospace; font-size: 0.95rem; color: #f59e0b; margin-top: 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Sign Your Art!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size: 0.85rem; color: #cbd5e1; margin: 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Enter your Dog Tag / Username (3–8 letters):&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"usernameInput"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"modal-input"&lt;/span&gt; &lt;span class="na"&gt;maxlength=&lt;/span&gt;&lt;span class="s"&gt;"8"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"BARKUS"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: flex; justify-content: center; gap: 10px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cancelModalBtn"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-pixel btn-secondary"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cancel&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"confirmUploadBtn"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn-pixel btn-action"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Post to Gallery 🚀&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;footer&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"footer-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"footer-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"footer-bottom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"footer-copyright"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          © 2026 Quackwork Studios • DEV Weekend Challenge: Dog Days Edition
        &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PROMPTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog and a duck playing on the beach 🏖️🦆&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog doctor checking a heartbeat with a stethoscope 🩺🐕&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog driving a fast sports car with sunglasses 🏎️&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog camping by a campfire roasting marshmallows 🏕️🔥&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog playing cards with a poker face around a table 🃏♠️&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog skydiving with a parachute in mid-air 🪂&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog chef cooking spaghetti in a chaotic kitchen 🍝👨‍🍳&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog detective inspecting clues with a magnifying glass 🔍🕵️&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog DJ rocking big headphones at a dance party 🎧🎶&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;An astronaut dog floating in outer space 🚀&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog wearing a Santa hat at Christmas 🎅&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog celebrating its birthday with a giant cake 🎂&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog dressed as a spooky Halloween ghost 👻&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog surfing a big ocean wave 🏄‍♂️&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog caught red-handed stealing a slice of pizza 🍕&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A wrinkly Pug wearing retro sunglasses 😎&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A fluffy Corgi with stubby legs chasing a tennis ball 🎾&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A long Dachshund (Wiener Dog) wearing a sweater 🌭&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A majestic Husky howling at the moon 🌕&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A fancy Poodle with a stylish fluffy haircut 🐩&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog dramatically refusing to take a bath in the tub 🛁&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A puppy having intense mud zoomies in the rain 🌧️&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isDrawing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#000000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;brushSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "pen", "spray", "eraser"&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;timeLeft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;timerInterval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isRoundActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Undo Stack (keeps last 15 actions)&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;undoStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="c1"&gt;// 10 Detailed Starter Dog Doodles (all 0 points)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DEFAULT_GALLERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PUGGY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A wrinkly Pug wearing retro sunglasses 😎&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;circle cx='240' cy='240' r='105' fill='%23b45309' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;ellipse cx='240' cy='285' rx='48' ry='32' fill='%23451a03' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;rect x='165' y='200' width='65' height='38' rx='8' fill='%23000'/&amp;gt;&amp;lt;rect x='250' y='200' width='65' height='38' rx='8' fill='%23000'/&amp;gt;&amp;lt;line x1='230' y1='216' x2='250' y2='216' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;polygon points='140,175 125,115 180,155' fill='%2378350f' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;polygon points='340,175 355,115 300,155' fill='%2378350f' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CHOPPER&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog caught stealing a slice of pizza 🍕&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;ellipse cx='190' cy='260' rx='85' ry='55' fill='%23f59e0b' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;circle cx='130' cy='210' r='45' fill='%23f59e0b' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;circle cx='120' cy='200' r='6' fill='%23000'/&amp;gt;&amp;lt;polygon points='145,225 300,265 290,170' fill='%23fef08a' stroke='%23b45309' stroke-width='6'/&amp;gt;&amp;lt;circle cx='215' cy='225' r='10' fill='%23ef4444'/&amp;gt;&amp;lt;circle cx='255' cy='235' r='10' fill='%23ef4444'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BARKY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog wearing a Santa hat at Christmas 🎅&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;ellipse cx='240' cy='275' rx='85' ry='75' fill='%23fef08a' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;circle cx='210' cy='255' r='8' fill='%23000'/&amp;gt;&amp;lt;circle cx='270' cy='255' r='8' fill='%23000'/&amp;gt;&amp;lt;ellipse cx='240' cy='295' rx='14' ry='10' fill='%23000'/&amp;gt;&amp;lt;polygon points='165,210 240,85 315,210' fill='%23ef4444' stroke='%23000' stroke-width='5'/&amp;gt;&amp;lt;rect x='155' y='200' width='170' height='26' rx='13' fill='%23ffffff' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;circle cx='240' cy='75' r='20' fill='%23ffffff' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CAKEDOG&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog celebrating its birthday with a giant cake 🎂&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;ellipse cx='160' cy='260' rx='65' ry='55' fill='%239ca3af' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;circle cx='140' cy='245' r='6' fill='%23000'/&amp;gt;&amp;lt;rect x='250' y='245' width='110' height='65' fill='%23ec4899' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;rect x='270' y='205' width='70' height='40' fill='%2338bdf8' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;line x1='305' y1='205' x2='305' y2='175' stroke='%23f59e0b' stroke-width='6'/&amp;gt;&amp;lt;circle cx='305' cy='170' r='7' fill='%23ef4444'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WAVERIDER&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog surfing a big ocean wave 🏄‍♂️&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;path d='M20,380 Q150,220 280,330 T460,370 L460,480 L20,480 Z' fill='%2338bdf8' stroke='%232563eb' stroke-width='6'/&amp;gt;&amp;lt;ellipse cx='230' cy='310' rx='95' ry='16' fill='%23f59e0b' stroke='%23000' stroke-width='5'/&amp;gt;&amp;lt;ellipse cx='230' cy='240' rx='45' ry='35' fill='%2378350f' stroke='%23000' stroke-width='5'/&amp;gt;&amp;lt;circle cx='215' cy='230' r='5' fill='%23fff'/&amp;gt;&amp;lt;circle cx='245' cy='230' r='5' fill='%23fff'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MOONDOG&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A majestic Husky howling at the moon 🌕&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;circle cx='360' cy='120' r='52' fill='%23fef08a' stroke='%23f59e0b' stroke-width='6'/&amp;gt;&amp;lt;path d='M150,370 L195,240 L265,195 L245,260 L265,370 Z' fill='%234b5563' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;polygon points='235,215 255,165 275,215' fill='%23b91c1c' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;circle cx='215' cy='225' r='4' fill='%23000'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-7&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DUCKPUP&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog and a duck playing on the beach 🏖️🦆&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;ellipse cx='160' cy='280' rx='60' ry='45' fill='%23f59e0b' stroke='%23000' stroke-width='5'/&amp;gt;&amp;lt;circle cx='120' cy='230' r='30' fill='%23f59e0b' stroke='%23000' stroke-width='5'/&amp;gt;&amp;lt;circle cx='310' cy='275' r='35' fill='%23fef08a' stroke='%23000' stroke-width='5'/&amp;gt;&amp;lt;polygon points='345,270 380,278 345,286' fill='%23f97316' stroke='%23000' stroke-width='3'/&amp;gt;&amp;lt;circle cx='240' cy='310' r='22' fill='%23ef4444' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DR_BARK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog doctor checking a heartbeat with a stethoscope 🩺🐕&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;circle cx='240' cy='240' r='80' fill='%23b45309' stroke='%23000' stroke-width='5'/&amp;gt;&amp;lt;rect x='170' y='140' width='140' height='35' rx='8' fill='%2306b6d4' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;path d='M190,260 Q240,350 290,260' fill='none' stroke='%234b5563' stroke-width='8'/&amp;gt;&amp;lt;circle cx='240' cy='320' r='14' fill='%239ca3af' stroke='%23000' stroke-width='3'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-9&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CAMP_DOG&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog camping by a campfire roasting marshmallows 🏕️🔥&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;polygon points='280,330 310,240 340,330' fill='%23ef4444' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;polygon points='295,330 310,270 325,330' fill='%23f59e0b'/&amp;gt;&amp;lt;circle cx='170' cy='270' r='55' fill='%2378350f' stroke='%23000' stroke-width='5'/&amp;gt;&amp;lt;line x1='170' y1='270' x2='290' y2='270' stroke='%23b45309' stroke-width='4'/&amp;gt;&amp;lt;rect x='280' y='260' width='22' height='18' rx='4' fill='%23ffffff' stroke='%23000' stroke-width='2'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doodle-10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SPEEDY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A dog driving a fast sports car with sunglasses 🏎️&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/svg+xml;utf8,&amp;lt;svg xmlns='http://www.w3.org/2000/svg' width='480' height='480' viewBox='0 0 480 480'&amp;gt;&amp;lt;rect width='480' height='480' fill='%23ffffff'/&amp;gt;&amp;lt;circle cx='220' cy='210' r='45' fill='%23f59e0b' stroke='%23000' stroke-width='4'/&amp;gt;&amp;lt;rect x='195' y='195' width='50' height='18' rx='4' fill='%23000'/&amp;gt;&amp;lt;rect x='100' y='250' width='280' height='80' rx='20' fill='%23ef4444' stroke='%23000' stroke-width='6'/&amp;gt;&amp;lt;circle cx='160' cy='330' r='30' fill='%23000'/&amp;gt;&amp;lt;circle cx='320' cy='330' r='30' fill='%23000'/&amp;gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;gallery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doggame_community_gallery&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;DEFAULT_GALLERY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;drawCanvas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetBreedEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;targetBreed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timerDisplay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timerDisplay&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;overlay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;overlay&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Tools &amp;amp; Action Buttons&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;penToolBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;penToolBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sprayToolBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sprayToolBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eraserToolBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eraserToolBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;undoBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;undoBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clearBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clearBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resetTimerBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resetTimerBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;skipBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;skipBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;publishBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;publishBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;overlayRetryBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;overlayRetryBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;overlayUploadBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;overlayUploadBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;galleryGrid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;galleryGrid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;galleryCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;galleryCount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;leaderboardBody&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;leaderboardBody&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uploadModal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uploadModal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usernameInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;usernameInput&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cancelModalBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cancelModalBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;confirmUploadBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirmUploadBtn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;undoStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getImageData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;undoStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;undoStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;clearCanvas&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;saveState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ffffff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;clearCanvas&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;startTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timerInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;timeLeft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;timerDisplay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;timeLeft&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;timerDisplay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;isRoundActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="nx"&gt;timerInterval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;timeLeft&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;timerDisplay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;timeLeft&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeLeft&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;timerDisplay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;warning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeLeft&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timerInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nx"&gt;isRoundActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;stopTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timerInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;isRoundActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCoords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scaleX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scaleY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;touches&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;touches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;clientX&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientX&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;touches&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;touches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;clientY&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientX&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;scaleX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientY&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;scaleY&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// MS Paint Style Spray Function&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;drawSpray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;density&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;brushSize&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;brushSize&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2.2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eraser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ffffff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentColor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;density&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;offsetX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;offsetY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;offsetX&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;offsetX&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;offsetY&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;offsetY&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;offsetX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;offsetY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;startDraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isRoundActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;saveState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;isDrawing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCoords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;spray&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;drawSpray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isDrawing&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isRoundActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCoords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;spray&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;drawSpray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strokeStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eraser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ffffff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentColor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eraser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;brushSize&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;brushSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineCap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineJoin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;round&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;stopDraw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;isDrawing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mousedown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;startDraw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mousemove&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mouseup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stopDraw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mouseleave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stopDraw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;touchstart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;startDraw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;passive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;touchmove&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;passive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;touchend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stopDraw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Color Swatches&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.color-btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.color-btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;currentColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eraser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;penToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nx"&gt;eraserToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Tool Selector&lt;/span&gt;
    &lt;span class="nx"&gt;penToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;penToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;sprayToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;eraserToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;sprayToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;spray&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;sprayToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;penToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;eraserToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;eraserToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;currentTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eraser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;eraserToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;penToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;sprayToolBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Brush Sizes&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.size-btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.size-btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;brushSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Undo Action&lt;/span&gt;
    &lt;span class="nx"&gt;undoBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;undoStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lastState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;undoStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putImageData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;clearBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clearCanvas&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Reset Timer (Keeps same prompt)&lt;/span&gt;
    &lt;span class="nx"&gt;resetTimerBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;clearCanvas&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;undoStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
      &lt;span class="nf"&gt;startTimer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Skip (New Prompt + Reset Timer)&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;nextPrompt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;stopTimer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;clearCanvas&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;undoStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

      &lt;span class="nx"&gt;currentPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PROMPTS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;PROMPTS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
      &lt;span class="nx"&gt;targetBreedEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentPrompt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;startTimer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;skipBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextPrompt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;overlayRetryBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextPrompt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Upload Modal Flow&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;openUploadModal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;stopTimer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;usernameInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doggame_username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BARKUS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;uploadModal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;publishBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;openUploadModal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;overlayUploadBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;overlay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;openUploadModal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;cancelModalBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;uploadModal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;confirmUploadBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cleanName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;usernameInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;A-Z0-9_&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cleanName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;cleanName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DOGE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;cleanName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cleanName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doggame_username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDataURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/jpeg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newArtwork&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;art-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cleanName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentPrompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dataUrl&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;

      &lt;span class="nx"&gt;gallery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unshift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newArtwork&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doggame_community_gallery&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gallery&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

      &lt;span class="nx"&gt;uploadModal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;renderGalleryAndLeaderboard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;nextPrompt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.gallery-section&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;scrollIntoView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;smooth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Voting System&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gallery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;g&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;like&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;likes&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;super&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;superLikes&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;doggame_community_gallery&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gallery&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="nf"&gt;renderGalleryAndLeaderboard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculateScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;likes&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;superLikes&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;renderGalleryAndLeaderboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;galleryCount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;gallery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ARTWORKS`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;galleryGrid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gallery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;div class="gallery-card"&amp;gt;
          &amp;lt;div class="gallery-img-wrap"&amp;gt;
            &amp;lt;img src="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" alt="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div class="gallery-info"&amp;gt;
            &amp;lt;div class="gallery-user-row"&amp;gt;
              &amp;lt;span class="gallery-user"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt;
              &amp;lt;span style="font-size: 0.75rem; color: #10b981; font-weight: bold;"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;calculateScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; PTS&amp;lt;/span&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="gallery-prompt" title="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;
            &amp;lt;div class="vote-bar"&amp;gt;
              &amp;lt;button class="vote-btn" onclick="vote('&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;', 'like')" title="Give a Like (+1 pt)"&amp;gt;
                ❤️ &amp;lt;span&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt;
              &amp;lt;/button&amp;gt;
              &amp;lt;button class="vote-btn" style="border-color: #f59e0b;" onclick="vote('&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;', 'super')" title="Super Like with a Bone! (+3 pts)"&amp;gt;
                🦴 &amp;lt;span&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;superLikes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/span&amp;gt;
              &amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      `&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sorted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;gallery&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;calculateScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;calculateScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="nx"&gt;leaderboardBody&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;tr&amp;gt;
          &amp;lt;td style="color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fcd34d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#cbd5e1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#b45309&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#8f9ba8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; font-weight: bold;"&amp;gt;
            &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.
          &amp;lt;/td&amp;gt;
          &amp;lt;td class="tag-highlight"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;
          &amp;lt;td class="score-highlight"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;calculateScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; PTS&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
      `&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;renderGalleryAndLeaderboard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;nextPrompt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;📂 &lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/ASXGTR/Quackworkstudios" rel="noopener noreferrer"&gt;https://github.com/ASXGTR/Quackworkstudios&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How I Built It 🛠️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🏗️ Architecture &amp;amp; Hosting Transparency
&lt;/h3&gt;

&lt;p&gt;I chose to host this project on my existing studio domain (&lt;strong&gt;Quackwork Studios&lt;/strong&gt;) and custom backend infrastructure because it was the fastest, most reliable way to deliver a friction-free demo. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pre-Existing Infrastructure:&lt;/strong&gt; My website already had a working deployment pipeline, SSL certificates, edge caching, and a clean base template ready to go.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built 100% from Scratch for this Challenge:&lt;/strong&gt; The &lt;em&gt;Bark Gallery&lt;/em&gt; game itself (&lt;code&gt;doggame.html&lt;/code&gt;), its canvas engine, voting logic, and Gemini-generated assets &lt;strong&gt;did not exist before this hackathon&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero Friction for Judges:&lt;/strong&gt; Deploying on my own infrastructure let me skip third-party sandbox restrictions and ensure judges and players could jump right in with instant load times and zero configuration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🤖 Solo Dev Pairing Workflow with Google AI Studio
&lt;/h3&gt;

&lt;p&gt;All development, prototyping, prompt generation, debugging, and code creation was done inside &lt;strong&gt;Google AI Studio&lt;/strong&gt; using the &lt;strong&gt;Gemini 3.7 Flash&lt;/strong&gt; model from the &lt;em&gt;Featured&lt;/em&gt; tab. Gemini acted as a real-time technical co-pilot throughout the build:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ideation &amp;amp; Prototyping:&lt;/strong&gt; We brainstormed dog-themed concepts tailored to the 48-hour hackathon timeframe, taking the idea from initial concept to a playable browser prototype in under an hour.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Full-Stack Frontend Generation:&lt;/strong&gt; Gemini generated the single-file architecture (&lt;code&gt;doggame.html&lt;/code&gt;), including the touch/mouse event listeners, undo state history, and particle-based MS Paint spray effects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Asset Generation in Code:&lt;/strong&gt; Gemini generated 10 hand-drawn SVG dog illustrations directly in code to pre-populate the community gallery with starter doodles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Live Debugging &amp;amp; Refactoring:&lt;/strong&gt; Diagnosed server 404s, resolved edge caching issues, and refactored the canvas engine during development.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  🎨 Creative Features &amp;amp; Toolkit
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🖌️ Drawing Suite:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;💨 &lt;strong&gt;MS Paint-Style Spray Can:&lt;/strong&gt; Realistic particle dispersion physics.&lt;/li&gt;
&lt;li&gt;✏️ &lt;strong&gt;Pen &amp;amp; Eraser:&lt;/strong&gt; 3 stroke thicknesses (Thin, Med, Thick).&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;18-Color Swatch Palette:&lt;/strong&gt; From vibrant neon accents to natural fur tones.&lt;/li&gt;
&lt;li&gt;↩️ &lt;strong&gt;15-Step Undo Stack:&lt;/strong&gt; Fast state restoration to undo misclicks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🕹️ Canvas Controls:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;🎲 &lt;strong&gt;Skip:&lt;/strong&gt; Pulls a fresh prompt and resets the 90s countdown.&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Reset:&lt;/strong&gt; Clears canvas and restarts the timer for the &lt;em&gt;same&lt;/em&gt; prompt.&lt;/li&gt;
&lt;li&gt;🗑️ &lt;strong&gt;Clear:&lt;/strong&gt; Wipes the current sketch immediately.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🛑 Roadblocks, Errors &amp;amp; Solutions
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Linux Case Sensitivity 404:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Bug:&lt;/em&gt; Deploying to GitHub Pages gave a &lt;code&gt;404 Not Found&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Cause:&lt;/em&gt; The file was committed as &lt;code&gt;Doggame.html&lt;/code&gt; (capital D) while the link targeted &lt;code&gt;/doggame.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Fix:&lt;/em&gt; Renamed to all-lowercase &lt;code&gt;doggame.html&lt;/code&gt; and redeployed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Aggressive Edge Caching:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Bug:&lt;/em&gt; Fresh commits weren't showing up immediately for players.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Fix:&lt;/em&gt; Added cache-busting version query parameters (&lt;code&gt;?v=2&lt;/code&gt;, &lt;code&gt;?v=3&lt;/code&gt;) and purged edge caches.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Client-Side API Deprecation &amp;amp; Key Friction:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Bug:&lt;/em&gt; Querying external models client-side required exposing or asking users for API keys.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Fix:&lt;/em&gt; Pivoted to a 100% frictionless &lt;strong&gt;Community Speed-Sketch Showcase&lt;/strong&gt;: client-side JPEG compression (~15KB) paired with instantaneous real-time voting and leaderboard ranking. Zero backend latency, zero friction, and 100% uptime.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Prize Categories 🏆
&lt;/h2&gt;

&lt;p&gt;I am submitting this project for:&lt;/p&gt;

&lt;h3&gt;
  
  
  🌟 &lt;strong&gt;Best Use of Google AI&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Bark Gallery&lt;/em&gt; was developed end-to-end with &lt;strong&gt;Google AI Studio (Gemini 3.7 Flash)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generating all humorous, chaotic prompt scenarios&lt;/li&gt;
&lt;li&gt;Generating the core HTML5 canvas engine and particle spray physics&lt;/li&gt;
&lt;li&gt;Generating the embedded starter SVG illustrations&lt;/li&gt;
&lt;li&gt;Debugging deployment, caching, and state management logic&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🐾 About the Developer
&lt;/h2&gt;

&lt;p&gt;I'm John, a self-taught, solo indie game developer building games at &lt;strong&gt;Quackwork Studios&lt;/strong&gt; (currently developing the multiverse card battler &lt;em&gt;Duckmon&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;Grab your digital spray can, post your dog sketch, don't forget to vote and enter, and let's celebrate International Dog Day! 🐕🎨&lt;/p&gt;

&lt;p&gt;Edit - Adjusted Title &lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>googleaichallenge</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Dev Log 40 - RNGDungeon Mini Game</title>
      <dc:creator>John</dc:creator>
      <pubDate>Thu, 06 Aug 2026 15:13:06 +0000</pubDate>
      <link>https://dev.to/asx/dev-log-40-rngdungeon-mini-game-3n7d</link>
      <guid>https://dev.to/asx/dev-log-40-rngdungeon-mini-game-3n7d</guid>
      <description>&lt;p&gt;Logging my recent progress, thoughts and development.&lt;/p&gt;

&lt;p&gt;Here goes...&lt;/p&gt;

&lt;h1&gt;
  
  
  Duckmon Squad Battle Mode
&lt;/h1&gt;

&lt;p&gt;Still in progress...&lt;/p&gt;

&lt;p&gt;Data entry is draining, even with extra tools to help input, search, edit and adjust values and skills. Draining and boring, i feel myself losing motivation by the minute entering data into my spreadsheet.&lt;/p&gt;

&lt;p&gt;Good news, i am over half way completed. I have finished basically every factions (11 total) skill sets, lists of positive effects and negative &lt;br&gt;
(buffs and debuffs), with 9 fully completed, and one of the remaining 2 being a "Mythic" Class, with fewer card and more unique skills.&lt;/p&gt;

&lt;p&gt;Here is a list of the current move sets - (non detailed, but still a lot)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEBUFF &amp;amp; NEGATIVE

ACID                CORROSIVE DOT (3% BASE HP PER TURN, +3% PER STACK, –3 DEF PER STACK, STACKABLE TO 5)
ATTACK DOWN         ATTACK DEBUFF (−20% DEFAULT BASE ATTACK, SINGLE TARGET)
BIND                    MOVE‑DISABLE DEBUFF (DISABLES 1 MOVE, ACTION‑BASED, STACKABLE)
BLEED           PHYSICAL DOT (4% CURRENT HP PER TURN, STACKABLE, NON‑LETHAL)
BLESSING            CURSE‑IMMUNE REMOVAL DEBUFF (SINGLE‑USE, NON‑STACKING, UNDEAD DAMAGE)
BLIND                   ACCURACY DEBUFF (TURN‑BASED, STACKABLE , -22% CHANCE TO HIT)
BURN                    FIRE DOT (8% MAX HP PER TURN, TYPE‑EFFECTIVE, STACKABLE)
CHARMED         SELF-TARGET REDIRECTION DEBUFF (80% TRIGGER, SINGLE-STACK, ACTION-BASED)
CHILL               ICE BUTTON DISABLE (STACKABLE, 20% CHANCE PER SKILL)
COLD                STACKABLE FROZEN PRIMER (15-20%)
COMA                    FULL DISABLE DEBUFF (TURN‑BASED, ENERGY GAIN ALLOWED, STACKABLE)
CONCUSSED           ENERGY COST INCREASE (TURN-BASED, STACKABLE, +25% ENERGY COST, ROUNDED UP TO NEAREST 10)
CONFUSED            SKILL FAILURE DEBUFF (50 % CHANCE, CONSUMES ENERGY, STACK‑BASED)
CONSTRICT           PHYSICAL DOT (10% MAX HP PER TURN, STACKABLE, TEMPORARY DEX DOWN PER TICK)
CONTAMINATE     HEALING REDUCTION DEBUFF (–50% HEALING RECEIVED, STACKABLE)
CRUSH               FLAT HP LOSS DEBUFF (10% BASE MAX HP ON APPLICATION, STACKABLE FOR DURATION ONLY)
CURSED          HP / ENERGY DRAIN (60 HP OR 60 ENERGY, OR BOTH)
CRYOPHOBIA          ICE VULNERABILITY DEBUFF (+50% EXTRA ICE DAMAGE ON NEXT ICE HIT, STACKABLE)
DEAF                    SWAP‑LOCKING DEBUFF (TURN‑BASED, STACKABLE)
DEF DOWN                DEFENCE DEBUFF (−20 % OF DEFAULT BASE DEFENCE , SINGLE TARGET)
DOOM                KO COUNTDOWN DEBUFF (5-STACK, NON‑REMOVABLE, MYTHIC UNDEAD)
ELECTRIC BURN       ELECTRIC DOT (8% MAX HP PER TURN, TYPE‑EFFECTIVE, STACKABLE)
EMP             TECHNOLOGY VULNERABILITY DEBUFF (+50% EXTRA TECHNOLOGY DAMAGE ON NEXT TECHNOLOGY HIT, STACKABLE)
ENERGY DOWN         ENERGY DEBUFF (−10 ENERGY PER TURN)   
ENERGY DOWN PLUS        ENERGY DEBUFF (−20 ENERGY PER TURN)   
ENERGY DRAIN            INSTANT −30 TEAM ENERGY (NO DAMAGE, NO DOT, NO TICKS)
ENERGY STEAL        INSTANT 60 ENERGY TRANSFER DEBUFF  (NON‑STACKING)
EVASION DOWN            DAMAGE HIT‑CHANCE INCREASE DEBUFF (+25% HIT CHANCE, TURN‑BASED, STACKABLE, SINGLE TARGET)
EXHAUSTED           ENERGY CAP REDUCTION DEBUFF (–20 CURRENT ENERGY, –20 MAX ENERGY, STACKABLE TO 5)
EXPOSED         UNIVERSAL WEAKNESS AMPLIFIER (FORCES ×1.25 SUPER-EFFECTIVE DAMAGE)
FEAR                CHANCE-BASED FORCED-SWAP DEBUFF (50% TRIGGER, TURN-BASED, STACKABLE)
FEVER               MOVE‑DISABLE DEBUFF (DISABLES 1 MOVE, ACTION‑BASED, STACKABLE, ENERGY‑DRAIN)
FLAMMABLE           FIRE VULNERABILITY DEBUFF (+50% EXTRA FIRE DAMAGE, APPLIES BURN ON NEXT FIRE HIT, STACKABLE)
FREEZE BURN             ICE DOT (8% MAX HP PER TURN, TYPE‑EFFECTIVE, STACKABLE)
FROST               ICE DEBUFF (–15% BASE DEX, STACKS EXTEND DURATION ONLY)
FROZEN                  FULL DISABLE DEBUFF (ICE‑TYPE, SKIP‑BASED, STACKABLE)
GRAVE LOCK          GLOBAL GRAVEYARD SEAL (RARE, MYTHIC, TEAMWIDE, PERMANENT, NON‑REMOVABLE)
HACKED          MOVE-DISABLE DEBUFF (DISABLES 2 MOVES, ACTION-BASED, 50% SUCCESS CHANCE, IF FAIL REMOVE 20 ENERGY)
HEAT STROKE     FULL DISABLE DEBUFF (FIRE‑TYPE, HP‑DRAIN, TURN‑BASED, STACKABLE @ 3% HP Per Stack)
HOLY BURN           HOLY DOT (7% MAX HP PER TURN, TYPE‑EFFECTIVE, STACKABLE)
HOLY VENOM          HOLY DOT (10% BASE HP PER TURN, +2% PER STACK, –10% TO –30% INT, STACKABLE TO 5)
ILLNESS         CLEANSE‑BLOCKING DEBUFF (PREVENTS ALL CLEANSE EFFECTS)
INT DOWN                INTELLIGENCE DEBUFF (−20% DEFAULT INT, SINGLE TARGET)
LOCKED          TURN SKIP DEBUFF
LOWER ATTACK            ATTACK DEBUFF (−20% DEFAULT ATTACK PER STACK, TURN‑BASED, STACKABLE)
LOWER DEF               DEFENCE DEBUFF (−20% DEFAULT DEF PER STACK, TURN‑BASED, STACKABLE)
LOWER DEX               DEXTERITY DEBUFF (−20% DEFAULT DEX PER STACK, TURN‑BASED, STACKABLE)
LOWER INT               INTELLIGENCE DEBUFF (−20% DEFAULT INT PER STACK, TURN‑BASED, STACKABLE)
MEGA BIND           MOVE-DISABLE DEBUFF (DISABLES 2 MOVES, TURN-BASED, STACKABLE)
MEGA PURIFY     4× RANDOM BUFF REMOVAL (ENEMY ONLY, INSTANT DEBUFF)
NANITE SWARM        TECHNOLOGY DOT (–12 HP TO TARGET, +12 HP TO OPPOSITE ACTIVE CARD, STACKS = DURATION ONLY)
PARALYZE                FULL DISABLE DEBUFF (NO MOVES ALLOWED, SKIP‑BASED, STACKABLE)
PETRIFY                 FULL DISABLE DEBUFF (UNDEAD‑TYPE, SKIP‑BASED, STACKABLE)
POISON          TOXIC DOT (10% BASE HP PER TURN, +2% PER STACK, –10% TO –30% DEX, STACKABLE TO 5)
PINNED          ANTI SWAP LOCKDOWN ( SWAP BUTTON DISABLE)
PLAGUE          HP DECAY DOT (–5 HP PER TICK, TURN-BASED, STACKABLE TO 5, INFECTIOUS ROT TRIGGER)
PURIFY          2× RANDOM BUFF REMOVAL (ENEMY ONLY, INSTANT DEBUFF)
RADIATION           TOXIC DOT (5% BASE HP PER TURN, +1% PER STACK, –2 ATK PER STACK, STACKABLE TO 5)
RESTRICT            HOLY DOT (10% MAX HP PER TURN, STACKABLE, TEMPORARY INT DOWN PER TICK)
RITUAL BIND     MOVE-DISABLE DEBUFF (DISABLES MOVES 1 &amp;amp; 2, ACTION-BASED, STACKABLE)
ROT             MAX-HP DECAY DOT (–10 DEFAULT MAX HP PER TICK, TURN-BASED, STACKABLE TO 5)
SACRIFICE           DUAL RANDOM GRAVEYARD OFFERING (INSTANT KO, NON-ACTIVE ONLY)
SCARED          FORCED‑SWAP DEBUFF (TURN‑BASED, STACKABLE, ACTION‑LOCK)
SCORCHED            ENERGY REDUCTION DEBUFF (FIRE‑TYPE, TURN‑BASED, STACKABLE)
SCRUPLES            HOLY VULNERABILITY DEBUFF (+50% EXTRA HOLY DAMAGE ON NEXT HOLY HIT, STACKABLE)
SELF BLEED          SELF-INFLICTED PHYSICAL DOT (4% CURRENT HP PER TURN, STACKABLE, NON-LETHAL)
SHOCK                   MOVE‑DISABLE DEBUFF (DISABLES 2 MOVES, ACTION‑BASED, STACKABLE)
SICKNESS            HEALING‑BLOCKING DEBUFF (PREVENTS ALL HP GAIN)
SLEEP                   FULL DISABLE DEBUFF (TURN‑BASED, WAKES ON SKILL DAMAGE, STACKABLE)
SMOG                TOXIC DEBILITATION DEBUFF (–10 HP &amp;amp; –10 ENERGY PER TRIGGER, STACKS INCREASE DURATION ONLY)
SNEEZE          TURN INTERRUPTION DEBUFF (10% CHANCE TO MISFIRE A MOVE, STACKABLE TO 5)
SOUL DRAIN          HP &amp;amp; ENERGY DECAY DOT (–5% BASE HP PER TICK, –10 ENERGY PER TICK, TURN-BASED, STACKABLE TO 5)
SPEED DOWN              DEXTERITY DEBUFF (−20% DEFAULT DEX, ACTION‑BASED, STACKABLE, SINGLE TARGET)
STICKY          MOVE-DISABLE DEBUFF (LOCKS SLOTS 2 &amp;amp; 3, ACTION-BASED, STACKABLE)
STRANGLE            PHYSICAL DOT (9% BASE HP PER TURN, ENERGY GAIN REDUCTION, STACKABLE TO 5)
SUPERSTITIOUS       UNDEAD VULNERABILITY DEBUFF (+50% EXTRA UNDEAD DAMAGE ON NEXT UNDEAD HIT, STACKABLE)
TAUNT               FORCED‑ACTION DEBUFF (TURN‑BASED, STACKABLE, NON‑SWAPPABLE)
TEAM ATTACK DOWN        TEAM‑WIDE ATTACK DEBUFF (−20 % OF DEFAULT BASE ATTACK)
TEAM BLIND          TEAM-WIDE ACCURACY DEBUFF (TURN-BASED, STACKABLE, –22% CHANCE TO HIT)
TEAM DAMAGE     AOE FLAT DAMAGE (20 HP TO ALL OPPOSING CARDS)
TEAM DEF DOWN       TEAM-WIDE DEFENCE DEBUFF ((−20 % DEFAULT ATTACK PER STACK, TURN‑BASED, STACKABLE)
TEAM DEX DOWN       TEAM‑WIDE DEXTERITY DEBUFF (−20 % OF DEFAULT BASE DEXTERITY)
TEAM EVASION DOWN   TEAMWIDE EVADE REDUCTION DEBUFF (INCREASES ENEMY HIT‑CHANCE)
TEAM INT DOWN       TEAM‑WIDE INTELLIGENCE DEBUFF (−20 % OF DEFAULT BASE INTELLIGENCE)
TEAM LOWER ATTACK   TEAM‑WIDE ATTACK DEBUFF (−20 % DEFAULT ATTACK PER STACK, TURN‑BASED, STACKABLE)
TEAM LOWER DEF      TEAM‑WIDE DEFENCE DEBUFF (−20 % DEFAULT DEF PER STACK, TURN‑BASED, STACKABLE)
TEAM LOWER DEX      TEAM‑WIDE DEXTERITY DEBUFF (−20 % DEFAULT DEX PER STACK, TURN‑BASED, STACKABLE)
TEAM LOWER INT      TEAM‑WIDE INTELLIGENCE DEBUFF (−20 % DEFAULT INT PER STACK, TURN‑BASED, STACKABLE)
TEAM SPEED DOWN     TEAM‑WIDE DEXTERITY DEBUFF (−20% DEFAULT DEX, TURN‑BASED)
TOXICITY            TOXIC VULNERABILITY DEBUFF (+50% EXTRA TOXIC DAMAGE ON NEXT TOXIC HIT, STACKABLE)
WEATHERED           NATURE VULNERABILITY DEBUFF (+50% EXTRA NATURE DAMAGE ON NEXT NATURE HIT, STACKABLE)
WRAP                MOVE-DISABLE DEBUFF (DISABLES MOVE 4, ACTION-BASED, STACKABLE)


BUFF &amp;amp; POSITIVE

ATTACK UP               ATTACK BUFF (+20 % OF DEFAULT BASE ATTACK, SELF ONLY)
AVOID               GUARANTEED EVADE BUFF (SELF ONLY, TURN‑BASED, STACKABLE, NON‑REMOVABLE)
BERSERK             FORCED DIRECT DAMAGE BUFF (STACKABLE FOR DURATION ONLY)
BIO SHIELD              TOXIC DAMAGE REDUCTION BUFF (50 % REDUCTION)
BLESSED             HOLY BUFF (DEBUFF BLOCKER, ABSORBS 1 INCOMING DEBUFF STACK)
BONE SHIELD         SELF‑APPLIED 60‑HP BARRIER (PERSISTENT, REMOVABLE)
BURN COUNTER            FIRE DOT COUNTER (ON‑TRIGGER, NON‑STACKING)
CLEANSE             2X RANDOM DEBUFF REMOVAL (SELF ONLY)
CONDUCTION              ENERGY-GAIN BUFF (CONVERTS HALF OF NEXT DIRECT DAMAGE TAKEN INTO TEAM ENERGY)
COUNTER PIERCE          BLEED RETALIATION BUFF (APPLIES 3 BLEED STACKS TO ATTACKER ON DIRECT DAMAGE)
CURE FIRE               FIRE‑TYPE DEBUFF REMOVAL (HEAT STROKE / FEVER / BURN / SCORCHED)
CURSE IMMUNE            DEBUFF‑BLOCKING BUFF (TURN‑BASED, NON‑STACKING, PREVENTS NEW DEBUFFS)
DEF UP              DEFENCE BUFF (+20 % OF DEFAULT BASE DEFENCE , SELF ONLY)
DEFEND              FLAT DAMAGE REDUCTION BUFF (REDUCES NEXT DIRECT DAMAGE BY 25 HP, STACKABLE)
DETOX                   1× RANDOM DEBUFF REMOVAL PER TURN (SELF ONLY, TURN-BASED, MAX 2 STACKS)
DEX UP              DEXTERITY BUFF (+20 % OF DEFAULT BASE DEXTERITY , SELF ONLY)
DURABILITY              PHYSICAL DAMAGE REDUCTION BUFF (50 % REDUCTION)
ELECTRIC BURN COUNTER   ELECTRIC BURN COUNTER — ELECTRIC DOT COUNTER (ON‑TRIGGER, NON‑STACKING)
ELECTRIFIED         ELECTRIC DAMAGE REFLECTION BUFF (15% + 5% PER STACK, SELF ONLY)
ENERGY UP               ENERGY REGEN BUFF (+50 % ENERGY GAIN - TEAM ENERGY POOL)
ENERGY UP PLUS          ENERGY REGEN BUFF (+50 % ENERGY GAIN +10 FLAT — TEAM
ESCAPE              REACTIVE EVADE / SWAP SKILL (EFFECT‑NULLIFIER + RANDOM BENCH SWAP)
EVASION UP              DAMAGE HIT - CHANCE REDUCTION BUFF (SELF ONLY 25%)
FATE                    RANDOM DEBUFF SKILL (TARGETED, SELECTS 2 RANDOM DEBUFFS FROM ALL DEBUFFS, IMMEDIATE EFFECT)
FROSTBITE               ICE DAMAGE REFLECTION BUFF (15% + 5% PER STACK, SELF ONLY)
FROST RESISTANCE            ICE DAMAGE REDUCTION BUFF (50 % REDUCTION)
HASTE                   TURN‑ORDER PRIORITY BUFF (SELF ONLY, STACKABLE, TICK‑BASED)
HAUNT                   UNDEAD COUNTER DOT (ON‑TRIGGER, –5% BASE HP &amp;amp; –10 ENERGY PER TICK, STACKS = DURATION ONLY)
HEAL                    INSTANT HP RECOVERY (SELF ONLY 16% OF DEFAULT MAX)
HEAT RESISTENCE         FIRE DAMAGE REDUCTION BUFF (50% REDUCTION)
HEAT SINK               TECHNOLOGY SELF‑PURGE (–20 HP, +50 ENERGY)
HOLY COUNTER            HOLY DIRECT‑DAMAGE COUNTER (ON‑HIT, NON‑STACKING)
HOLY RESISTANCE         HOLY DAMAGE REDUCTION BUFF (50 % REDUCTION)
HP UP                   PERMANENT SELF MAX HP BUFF (+25 MAX HP TO SELF, REMOVED ON KO)
INSTANT ENERGY          ENERGY GAIN EFFECT (+80 ENERGY IMMEDIATELY - NET GAIN 30)
INT UP              INTELLIGENCE BUFF (+20 % OF DEFAULT BASE INTELLIGENCE, SELF ONLY)
LAVA SKIN               FIRE DAMAGE REFLECTION BUFF (20 BASE + 5 PER STACK)
LUCKY DIP               RANDOM BUFF SKILL (SELF ONLY, SELECTS 1 RANDOM BUFF FROM ALL BUFFS, IMMEDIATE EFFECT)
MAX ENERGY UP           PERMANENT TEAM ENERGY CAP BUFF (+50 MAX ENERGY TO TEAM, STACKABLE TO 5, REMOVED ON BATTLE END)
MEGA CLEANSE            4X RANDOM DEBUFF REMOVAL(SELF ONLY, POSITIVE BUFF)
MEGA ENERGY UP          ENERGY REGEN BUFF (+100% ENERGY GAIN - TEAM ENERGY POOL)
MEGA HEAL               INSTANT HP RECOVERY (SELF ONLY 22% OF DEFAULT MAX)
MEGA RECHARGE           SELF - INFLICTED COMA + BONUS ENERGY (50 BONUS ENERGY)
MINI SHIELD         SELF‑APPLIED 50‑HP BARRIER (PERSISTENT, REMOVABLE) 
MIRROR              COUNTER BUFF (REFLECTS NEXT ACTION WITHOUT NEGATING IT)
NANITE SURGE            TECHNOLOGY SUSTAIN BUFF ( 15% CURRENT HP , 1 DEBUFF STACK REMOVED)
NANO SHIELD         SELF‑APPLIED 30‑HP BARRIER (TECHNOLOGY, PERSISTENT, REMOVABLE)
PHASE                   ENERGY REFUND BUFF (REFUNDS 50% OF NEXT SKILL’S ENERGY COST)
POISON COUNTER          INSTANT TOXIC STACK APPLICATION (BUFF, ON‑DIRECT‑DAMAGE, NON‑STACKING)
POWER GAIN              NEXT DAMAGE SKILL DEALS DOUBLE BASE ATTACK POWER
QUANTUM SHIELD          SELF‑APPLIED 150‑HP BARRIER (MYTHIC TECHNOLOGY, PERSISTENT, REMOVABLE)
RAGE                    OFFENSIVE BEHAVIOUR BUFF (FORCED‑ATTACK MODE, DAMAGE BOOST, TURN‑BASED)
RAISE ATTACK            ATTACK BUFF (+20 % OF DEFAULT BASE ATTACK, SELF ONLY)
RAISE DEF               DEFENCE BUFF (+20 % OF DEFAULT BASE DEF, SELF ONLY)
RAISE DEX               DEXTERITY BUFF (+20 % OF DEFAULT BASE DEXTERITY , SELF ONLY)
RAISE INT               INTELLIGENCE BUFF (+20 % OF DEFAULT BASE INTELLIGENCE, SELF ONLY)
RAISE SPEED         DEXTERITY BUFF (+20 % OF DEFAULT BASE DEXTERITY , SELF ONLY)
REANIMATE               UNDEAD REVIVAL SKILL (GRAVEYARD → HAND, RETURNS AT 65% DEFAULT HP, PERMANENT MAX-HP REDUCTION)
RECHARGE                SELF - INFLICTED COMA + BONUS ENERGY (30 BONUS ENERGY) 
REFLECT             DAMAGE COUNTER BUFF 50% DAMAGE RETURN (TURN‑BASED, STACKABLE)
REFLEX              PHYSICAL DAMAGE REFLECTION BUFF (10% + 3% PER STACK, +2% SELF HEAL PER STACK)
REGEN               NEUTRAL SUSTAIN BUFF (TEAM ENERGY GENERATION + PERCENT HEAL)
REINCARNATION           UNIQUE HOLY / NEUTRAL BUFF (ONE‑TIME SELF‑RESURRECTION, INDEFINITE DURATION)
REMOVE WEAKNESS         FACTION WEAKNESS NEUTRALIZER (DISABLES ×1.25 WEAKNESS MULTIPLIERS)
RESIST TAUNT            ANTI‑TAUNT BUFF (BLOCKS TAUNT, TURN‑BASED, STACKS = DURATION ONLY)
RESURRECT               REVIVAL SKILL (GRAVEYARD → HAND, RANDOM TARGET, RETURNS AT 50% DEFAULT HP, NO BUFFS/DEBUFFS)
RETRIBUTION             HOLY DAMAGE REFLECTION BUFF (15% + 5% PER STACK, SELF ONLY)
RETURN BLIND            TRAP COUNTER DEBUFF (ACTIVATES ONLY WHEN USER TAKES DIRECT DAMAGE)
RETURN DAMAGE           TRAP COUNTER (TRIGGERS WHEN USER TAKES DIRECT DAMAGE)
RETURN HEAT STROKE      TRAP COUNTER FULL DISABLE (FIRE‑TYPE, DIRECT‑DAMAGE TRIGGER, STACKABLE @ 3% HP Per Stack)
SELF DESTRUCT           NEGATIVE SELF BUFF (FORCED SELF-KO, RESOLVES LAST)
SELF REVIVAL            AUTO‑REVIVE BUFF (NON‑STACKING, CONSUMES ON KO, PERMANENT 20% STACKING DEF PENALTY)
SHIELD              SELF - APPLIED 100 - HP BARRIER(PERSISTENT, REMOVABLE)
SPEED UP                DEXTERITY BUFF (+20 % OF DEFAULT BASE DEXTERITY , SELF ONLY)
STOIC                   UNDEAD DAMAGE REDUCTION BUFF (50 % REDUCTION)
STRONG              DIRECT DAMAGE POWER BUFF (+12 BASE POWER TO ALL DAMAGE SKILLS)
SUNGLASSES              ANTI-BLIND SHIELD (INSTANTLY NULLIFIES BLIND, SINGLE-USE, NON-STACKABLE)
SYSTEM RESTORE          3× RANDOM DEBUFF REMOVAL (SELF ONLY, INSTANT TECHNOLOGY PURGE)
TEAM ATTACK UP          ATTACK BUFF (+20 % OF DEFAULT BASE ATTACK, TEAM)
TEAM BLESSED            HOLY TEAM BUFF (TEAMWIDE DEBUFF BLOCKER, ABSORBS 1 INCOMING DEBUFF STACK PER ALLY)
TEAM BURN COUNTER       TEAM FIRE DOT COUNTER (ON‑TRIGGER, NON‑STACKING, NO COUNTER‑LOOPS)
TEAM CLEANSE            TEAM‑WIDE DEBUFF REMOVAL (2 RANDOM STACKS PER CARD)
TEAM DAMAGE COUNTER     TEAM ELEMENTAL RETURN DAMAGE (ON‑DIRECT‑DAMAGE, NON‑STACKING, NO COUNTER‑LOOPS)
TEAM DEF UP         DEFENCE BUFF (+20 % OF DEFAULT BASE DEFENCE , TEAM)
TEAM DEX UP         DEXTERITY BUFF (+20 % OF DEFAULT BASE DEXTERITY , TEAM)
TEAM ELECTRIC BURN COUNTER TEAM ELECTRIC DOT COUNTER (ON‑DIRECT‑DAMAGE, NON‑STACKING, NO COUNTER‑LOOPS)
TEAM EVASION UP         DAMAGE HIT - CHANCE REDUCTION BUFF (TEAM WIDE 25%)
TEAM HEAL               TEAM - WIDE HEALING SKILL(16 % DEFAULT HP)
TEAM HOLY COUNTER       TEAM HOLY DIRECT‑DAMAGE COUNTER (ON‑HIT, NON‑STACKING)
TEAM HP UP              PERMANENT TEAMWIDE MAX HP BUFF (+25 MAX HP TO ALL ALLIES, REMOVED ON KO)
TEAM INT UP         INTELLIGENCE BUFF (+20 % OF DEFAULT BASE INTELLIGENCE, TEAM)
TEAM MEGA HEAL          INSTANT HP RECOVERY (ALL ALLIES 22% OF DEFAULT MAX)
TEAM RAISE ATTACK       ATTACK BUFF (+20 % OF DEFAULT BASE ATTACK, TEAM)
TEAM RAISE DEF          DEFENCE BUFF (+20 % OF DEFAULT BASE DEFENCE , TEAM)
TEAM RAISE DEX          DEXTERITY BUFF (+20 % OF DEFAULT BASE DEXTERITY , TEAM)
TEAM RAISE INT          INTELLIGENCE BUFF (+20 % OF DEFAULT BASE INTELLIGENCE, TEAM)
TEAM RAISE SPEED            DEXTERITY BUFF (+20 % OF DEFAULT BASE DEXTERITY , TEAM)
TEAM SPEED UP           DEXTERITY BUFF (+20 % OF DEFAULT BASE DEXTERITY , TEAM)
THORNS              NATURE DAMAGE REFLECTION BUFF (15% + 5% PER STACK, SELF ONLY)
TIME LOOP               MYTHIC TECHNOLOGY TEMPORAL REVERSAL (REVERT HP TO PREVIOUS VALUE, REMOVE DEBUFFS FROM LAST DIRECT HIT)
TOXIC COUNTER           TOXIC DOT COUNTER (ON‑DIRECT‑DAMAGE, NON‑STACKING, NO COUNTER‑LOOPS)
TOXIC TOUCH         TOXIC DIRECT-DAMAGE COUNTER (ON‑DIRECT‑DAMAGE, STACKS = DURATION ONLY, NO COUNTER‑LOOPS)
TRAUMA RESPONSE         SELF‑HEAL COUNTER BUFF (ON‑DIRECT‑DAMAGE, NON‑STACKING, NO COUNTER‑LOOPS)
ULTIMATE STRENGTH       NEXT PHYSICAL DAMAGE SKILL DEALS TRIPLE BASE ATTACK POWER (MYTHIC PHYSICAL BUFF)
UNDEAD SLAYER           CONDITIONAL DAMAGE (80 HP REMOVAL IF HIT AND TARGET IS UNDEAD)
WOOD SHIELD         SELF‑APPLIED 40‑HP BARRIER (PERSISTENT, REMOVABLE)
ZOMBIE              UNDEAD DEATH-PREVENTION DEBUFF (SURVIVE KO AT 1 HP, –50% BASE STATS, –50% MAX HP, CLEARS ALL DEBUFFS)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are obviously, bullet point versions, and each skill has a internal rule set, how they work with each other , what can stack, how the stacks are generated or removed, what can and can not be applied at the same time. the order of effects, typing modifiers (e.g. fire is strong vs nature). There are other modifiers and internal working.&lt;/p&gt;

&lt;p&gt;I will share one as a example of this,  it may (Will) need a final touching over to solidify effects and look at any special case rules, to make sure everything aligns correctly..&lt;/p&gt;

&lt;h1&gt;
  
  
  Example
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ATTACK UP — ATTACK BUFF (+20% DEFAULT ATTACK, SELF ONLY)

Description :
        Attack Up increases the user’s Attack by +20 % of its DEFAULT ATTACK.

        This buff affects ONLY the active card.
        It does NOT apply to benched allies unless a skill explicitly allows it.

        Attack Up is a separate buff category from Raise Attack.
        Both can stack together and both apply their bonuses independently.

Effect :
        The user gains +20 % of its DEFAULT ATTACK.
        This bonus is added directly to current ATTACK.

    Examples :
        Default ATTACK = 40 → +8 ATTACK
        Default ATTACK = 70 → +14 ATTACK
        Default ATTACK = 50 → +10 ATTACK

        Attack Up does NOT retroactively increase damage already dealt.
        Attack Up does NOT affect DOT damage (Burn, Poison, Bleed, etc).

Interaction With Other ATTACK Buffs :
        Attack Up stacks with :
            • [Raise Attack](ca://s?q=Explain_Raise_Attack)
            • [Team Attack Up](ca://s?q=Explain_Team_Attack_Up)
            • Rage
            • Berserk
            • Any other Attack‑modifying buff

        Attack Up does NOT stack with itself beyond duration limits.

    Example :
        DEFAULT ATTACK = 40
        Raise Attack (+20 %) = +8
        Attack Up (+20 %) = +8
        Total = +16 ATTACK → Final ATTACK = 56

Solo / Team Interaction :
        Attack Up and Team Attack Up are the SAME buff category.
        They do NOT stack their power.
        If both are active, only ONE +20 % bonus is applied.

        Their durations DO stack together :
            • Team Attack Up can extend Attack Up
            • Attack Up can extend Team Attack Up

        Attack Up DOES stack with other buff categories (Raise Attack, Rage, Berserk, etc).

Duration :
        Attack Up lasts for 6 turns total.
        The turn it is used counts as Turn 1.
        After that, it lasts for the next 5 player turns.

        Attack Up ticks down once per player turn.
        It does NOT tick down based on actions.
        It does NOT tick down while benched.

Stacking :
        Attack Up cannot exceed 6 total turns.

        If used again while active :
            • Add only enough turns to reach 6
            • If already at 6, additional uses do nothing

    Example :
        4 turns remain → re‑used → becomes 6
        6 turns remain → re‑used → stays 6

Targeting :
        Attack Up can only target the active card unless a skill explicitly allows targeting benched allies.

Swapping :
        If swapped out :
            • Attack Up remains active
            • Attack Up continues ticking normally
            • Attack Up expires even if the card never returns

Removal Interaction :
        Attack Up can be removed by :
            • Cleanse (removes 2 random buff stacks total)
            • Mega Cleanse (removes 4 random buff stacks total)
            • Any single‑target buff removal skill
            • Any team‑wide buff removal skill
            • Revive (removes all buffs)

        Cleanse and Mega Cleanse remove stacks RANDOMLY from the entire buff pool.

Restrictions :
        Attack Up cannot be used if the card is :
            • Paralyzed
            • Frozen
            • Petrified
            • Asleep
            • In Coma

Expiration :
        Attack Up expires when :
            • All 6 turns have passed
            • A buff‑removal skill removes it
            • The card is knocked out
            • The card is revived

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My spreadsheet is now completed to around 160 units/cards  having a fully completed move set... meaning;&lt;/p&gt;

&lt;p&gt;Each Card has 4 skills. So each has these fields 4x.&lt;/p&gt;

&lt;p&gt;A skill name (which is the move use name)&lt;/p&gt;

&lt;p&gt;A skill effect/multiple (which is the buff,debuff or damage effects), &lt;br&gt;
A energy cost, taken from the team energy pool .&lt;/p&gt;

&lt;p&gt;A Skill Assignment - The Type of skill, neutral, fire, holy, ice etc &lt;/p&gt;

&lt;p&gt;A duration value or stacks applied, It is the same field, stacks using values between 2 - 6, direct dame or single/instant effects using a value of 1.&lt;/p&gt;

&lt;p&gt;A base power value (where applicable), This is used as a modifier stat, working with the cards/units attack value.&lt;/p&gt;

&lt;p&gt;A Hit chance value out of 100 (as a percentage)&lt;/p&gt;

&lt;p&gt;HP is calculated ingame, and does not have a specific data field , using a formula of HP = (DEF × 1.5) + (ATK × 0.75) + DEX + INT&lt;/p&gt;

&lt;p&gt;HP Rounding Rule :&lt;br&gt;
After calculating HP, round to the nearest 5 using :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ends in 1 or 2 → round down

Ends in 3 or 4 → round up

Ends in 6 or 7 → round down

Ends in 8 or 9 → round up

Ends in 0 or 5 → keep as - is
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;There are other formulas, for accuracy (chance to hit) as a example, and more.(I will not share all of my formulas)&lt;/p&gt;

&lt;p&gt;The total cards in my data, is 310,  which already contained fields for &lt;/p&gt;

&lt;p&gt;Card ID - Assigned ID value&lt;/p&gt;

&lt;p&gt;Card Name - Character&lt;/p&gt;

&lt;p&gt;Card Faction - (1-11)&lt;/p&gt;

&lt;p&gt;Card Rarity - (Common - Uncommon - Rare - Epic - Legendary - Mythic)&lt;/p&gt;

&lt;p&gt;Attack - value 0-100+&lt;/p&gt;

&lt;p&gt;Defence - value 0-100+&lt;/p&gt;

&lt;p&gt;Dexterity - value 0-100+&lt;/p&gt;

&lt;p&gt;Intelligence - value 0-100+ ( Ironically with the spelling Inteligence)&lt;/p&gt;

&lt;p&gt;Total Stats Value - A band of values that was used to determine individual stats , within a set range , for each rarity&lt;/p&gt;

&lt;p&gt;Gold Sell Value - Set value to sell any card to a ingame market depending on rarity&lt;/p&gt;

&lt;p&gt;Lore Block - Background lore information&lt;/p&gt;

&lt;p&gt;Avatar ID -  Some are linked to be used as avatars and unlockables&lt;/p&gt;

&lt;p&gt;Quote ID - Same as avatars&lt;/p&gt;

&lt;p&gt;Quote Text - Data saved directly in the spreadsheet&lt;/p&gt;

&lt;p&gt;(The skill Fields x 4)&lt;/p&gt;

&lt;p&gt;A Luck Value Field - This is for something else entirely...&lt;/p&gt;

&lt;p&gt;So completing around 160 complete entries has been a long task, entering values, creating skills, have them interact and try to give factions specific identities while keeping balance and strategy in mind.&lt;/p&gt;

&lt;h1&gt;
  
  
  RNGDungeon
&lt;/h1&gt;

&lt;p&gt;Since i was losing motivation, and feeling a bit fed up of data entry after around doing this for 7 days straight in my spare time,  i decided to attempt another mini .(mini.. lol) , funny they always start mini, these ideas and explode in scope one way or another.   &lt;/p&gt;

&lt;p&gt;I attempted another mini game inside my project.&lt;br&gt;
This is called RNGDungeon mode.&lt;/p&gt;

&lt;p&gt;A game mode that is fully and completely decided by RNG.  Using my assets already in my project, the only field i needed to add to my current data was a luck field. I added this by using a formula inside of my spreadsheet to auto complete intelligence + dexterity / 3 = luck total. &lt;/p&gt;

&lt;p&gt;These luck fields have then been set into luck bands for values such as 1-15 , 16 - 30 etc.&lt;/p&gt;

&lt;p&gt;This effects the RNG % chance of certain events/shops/items, having a better chance to appear in my new game mode,  it is still under construction, but all part of my main project.&lt;/p&gt;

&lt;p&gt;The idea is simple..  I use a listed spinner in a scroll view that lands on a choice of listed data.  Such as your starting character 310 chances all equal in probability.  This then generated ingame stats ,using my database, for HP , armour value, attack, def, int, dex .  and gives the player gold coins , (set from a gold sell value and normalized).  &lt;/p&gt;

&lt;p&gt;Then the dungeon starts, there are 10 categories, header values, each with weighted chance depending on luck value. These are landed on and go into a sub list full of in game events, such as portals, battles, npcs, shops, mystery events. I will use the example shop to continue.. as that is what i have been working on right now.&lt;/p&gt;

&lt;p&gt;You land on a shop,  it goes into sub menu, what type of shop, these are tiered,  and banded by dungeon depth, there are 3 bands 1-10, 11- 25, 25+ and a constant set that is banded 0-100+  these ones unlock more items when the threshold for each band is reached..&lt;/p&gt;

&lt;p&gt;Once you land on the sub shop,  it opens another list , spins with % set chances to land on a item, good or bad,  if you have enough gold ,.. you buy it,, the item effect apply automatically. Healing, or stat increase( or decrease)  and exit to a text screen,  giving a yes no choice ,that is rolled randomly,,  if you exit , you continue back to the main header list , and spin again. If you land on shop again, you enter again, buying another item, or failing to buy due to lack of gold until you land on the continue dungeon.   &lt;/p&gt;

&lt;p&gt;The goal will be using rng, spinning, no skill, to exit the dungeon, going deeper and deeper , fighting enemies, recruiting allies, solving mini puzzles , collecting loot, gold items, etc,  until you either escape , or lose hp to 0. &lt;/p&gt;

&lt;p&gt;I have started creating image assets , and also have 2 generative typewriter scripts that play the text segments out, they are short so the typewriter firs well and has sfx etc.&lt;/p&gt;

&lt;p&gt;It is a mini game inside my main project, but it should be pretty fun once completed. &lt;/p&gt;

&lt;p&gt;The UI is all mostly done, needs some final polish, but the basics are completed, the button works, the spinner works, there are dynamic images and text but this "mini" project is also a lot of work.&lt;/p&gt;

&lt;p&gt;Just wanted to post a update, and will continue to do so, after around 6 months or so, give or take, of working on this full project, it helps keep me sane(kind of).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvvrql1wt630u7v795d89.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvvrql1wt630u7v795d89.jpg" alt=" " width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>devjournal</category>
      <category>csharp</category>
    </item>
    <item>
      <title>DEV LOG 39 - Continued Improvements</title>
      <dc:creator>John</dc:creator>
      <pubDate>Sat, 25 Jul 2026 18:29:11 +0000</pubDate>
      <link>https://dev.to/asx/dev-log-39-continued-improvements-3031</link>
      <guid>https://dev.to/asx/dev-log-39-continued-improvements-3031</guid>
      <description>&lt;p&gt;Dev Log 39 - Continued Improvements&lt;/p&gt;

&lt;p&gt;Hello All, I have continued to work on my project consistently since my last post, and this is my progress over the last few days, the tasks completed and those still underway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skill Auto-Generator Implemented (Major Pipeline Upgrade)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Skill Auto Generator was fully built and integrated into Unity. This tool now automatically creates SkillDefinition ScriptableObjects based on my move data (skills &amp;amp; traits).&lt;/p&gt;

&lt;p&gt;I added a custom EditorWindow under the Duckmon internal unity tab, which can now be used to generate skill data automatically, which outputs assets into Assets/SkillDef/.&lt;/p&gt;

&lt;p&gt;Fixed folder creation logic, eliminating parent directory errors that appeared during this process.&lt;/p&gt;

&lt;p&gt;All skills are not generating correctly, even the Multi-effect skills, and host their own audio effects (SFX) fields. Activation SFX support was added separately from hit SFX. (2 SFX per skill, a activation SFX and a effect/hit SFX)&lt;/p&gt;

&lt;p&gt;Activation SFX Layer Added (Skill Personality Upgrade)&lt;br&gt;
A new SFX layer was added for skill activation sounds, completely separate from hit SFX, damage SFX, and status SFX. This allows each skill to have its own activation identity, improving battle feel and presentation.&lt;/p&gt;

&lt;p&gt;All fields including SkillName, EnergyCost, Element, TraitName, Power, IntScalingK, and Effects populate as intended.&lt;/p&gt;

&lt;p&gt;Neutral and Electric move lists were successfully generated and now in the process of creating and working through the Fire based skillsets.&lt;/p&gt;

&lt;p&gt;This has dramatically helped to speed up content creation, data input and ensures consistency across all skills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quax Trax Mode Created (New Music Feature)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyeads27ej8iz1y6cpw8a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyeads27ej8iz1y6cpw8a.jpg" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A full music player mode named Quax Trax was implemented.&lt;/p&gt;

&lt;p&gt;Includes a complete music library containing all Duckmon soundtrack content in a playable library area of my project.&lt;/p&gt;

&lt;p&gt;Features play, pause, previous, next and stop controls. Includes 3 volume sliders, for SFX, Music Volume and MAster Volume , all plugging directly into my Master Audio Manager which is housed inside of the bootloader.&lt;/p&gt;

&lt;p&gt;Supports playlists with duck-themed UI and an integrated audio visualizer.&lt;/p&gt;

&lt;p&gt;This is a (semi) polished, player-friendly feature that adds charm and personality to the game along with some visual aspects to accompany the soundtrack.&lt;/p&gt;

&lt;p&gt;Quax Trax Visualizer Implemented (Duck-Themed Audio Visualizer)&lt;/p&gt;

&lt;p&gt;A custom 16-bar mirrored audio visualizer was created for Quax Trax.&lt;/p&gt;

&lt;p&gt;Features 16 bars total, with 8 on the left and 8 on the right in mirrored movement for symmetry.&lt;/p&gt;

&lt;p&gt;A splash effect is triggered under each bar when bar height increases.&lt;/p&gt;

&lt;p&gt;Uses transparency for a soft glow, adding motion and fluidity.&lt;/p&gt;

&lt;p&gt;Includes a duck icon overlay positioned above the bars so the bars rise behind the duck, creating the illusion that the duck is flying upward while visually hiding behind the duck for a clean layered look.&lt;/p&gt;

&lt;p&gt;Bars use the splash texture as fill, making them transparent, glowing, reactive, and more organic than plain rectangles.&lt;/p&gt;

&lt;p&gt;Fully synced to music playback in Quax Trax.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Battle System Planning (Modular Rewrite Scheduled)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reviewed the full buff and status design document and identified required updates for the battle engine. These skills/traits/moves/buffs and debuffs are still in development and will be finalized and balanced later once playtesting is able to be completed. &lt;/p&gt;

&lt;p&gt;I have decided to fully generate all skills first via CSV, then finalize the battle system. Doing this for all 11 factions, thus saving the constant rewriting of datasets and scripts to match new entries and conditions/rules. &lt;/p&gt;

&lt;p&gt;Expanded Reasoning: More systems are still being added such as revives, time limit effects, counter effects, other DOT skills, passives and skill specific recoveries and effects. The skill roster is expanding, and buff or debuff categories are still evolving. This approach avoids rewriting the battle engine multiple times. Once the full skill list exists, the system can be finalized cleanly.&lt;/p&gt;

&lt;p&gt;Systems Queued for Modular Updates: SkillExecutor, Buffs, Statuses, TeamBuffs, EnergySystem, TurnManager, and minor updates to DamageCalculator. All Currently existing but will need major updates.&lt;/p&gt;

&lt;p&gt;This ensures the battle engine will match the full intended design once all skills exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Sheets to Python Data Pipeline Integration &lt;br&gt;
(Major Tooling Foundation)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Set up a dedicated Google Cloud project to support automated data access for Duckmon development tools.&lt;/p&gt;

&lt;p&gt;Enabled the Google Sheets API and created a service account for secure programmatic access. (Inspiration from a fellow Dev user post)&lt;/p&gt;

&lt;p&gt;Granted the service account permission to read and write to the Duckmon card database sheet inside google sheets.&lt;/p&gt;

&lt;p&gt;Generated a local authentication key stored privately and referenced only by path.&lt;/p&gt;

&lt;p&gt;The service account acts as a robot user with Editor permissions on the sheet, requiring no OAuth popups.&lt;/p&gt;

&lt;p&gt;Created a Python tool named sheetbot.py that connects directly to the Duckmon card spreadsheet ID, reading the entire dataset of 311 rows up to column AP, and printing card data directly into the console.&lt;/p&gt;

&lt;p&gt;This pipeline allows instant card row retrieval for AI integration, lore writing, and balancing without scrolling through Google Sheets manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python Vertical Card Viewer (Major Data Inspection Upgrade)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edited the Python-powered code card inspection tool, which is now able to read the entire Duckmon card database directly from Google Sheets and display each card one at a time, fully expanded, vertically, with zero truncation inside a seperate window.&lt;/p&gt;

&lt;p&gt;Shows one Duckmon per page, printing every column vertically with no cut-offs. Showing this...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9rvr64w4ph3ibonnn6wq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9rvr64w4ph3ibonnn6wq.jpg" alt=" " width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rather than this...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frieyeuez9lqxukhmet3u.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frieyeuez9lqxukhmet3u.jpg" alt=" " width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This window now displays full Skill 1 through 4 breakdowns including power, cost, type, traits, chances, and durations much more clearly.&lt;/p&gt;

&lt;p&gt;Includes stats, metadata, quotes, and avatar IDs, while lore is intentionally excluded for cleaner developer-focused output.&lt;/p&gt;

&lt;p&gt;Integrates a search system by skill name, trait or effect type, rarity, faction, or any column, alongside an option to show all cards.&lt;/p&gt;

&lt;p&gt;Features curses UI with arrow-key navigation, DELETE to exit views, a clean menu system, and smooth scrolling.&lt;/p&gt;

&lt;p&gt;This serves as a massive improvement in data readability, perfect for balancing skills, checking trait consistency, reviewing metadata, debugging CSV entries, and feeding clean card data into AI for design work. The ability to directly search for a single keyword on any card/unit  or to search directly for any trait name or skill name will be a huge time saver in completed this task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identified some bugs in the code:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fixed Missing select_column(): The menu contained options that called a function that was never defined, causing a crash. A full implementation was added with arrow-key navigation, safe cancellation with DELETE, and width-safe rendering.&lt;/p&gt;

&lt;p&gt;Removed Silent Search Failure: Zero-match searches previously fell back to showing all cards. This was replaced with a clear no matches found message and a pause until a key is pressed.&lt;/p&gt;

&lt;p&gt;Refactored Search System: search_columns and search_single_column were combined into one unified search function supporting lists, reducing duplicated code.&lt;/p&gt;

&lt;p&gt;Added Width-Safe Rendering: Long values that exceeded terminal width now truncate safely, preventing curses exceptions and screen crashes.&lt;/p&gt;

&lt;p&gt;Final Polish: The viewer reliably displays all stats, metadata, skills, effects, chances, durations, avatar IDs, and quote IDs while keeping lore excluded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python Vertical Card Viewer: Real-Time Editor Mode Added&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3kucvrb9xx7ybapjqk9g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3kucvrb9xx7ybapjqk9g.jpg" alt=" " width="613" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Python Vertical Card Viewer has evolved and expanded its use cases, going from what was a read-only inspection tool into a full real-time Duckmon database editor capable of writing directly to Google Sheets from inside the terminal.&lt;/p&gt;

&lt;p&gt;Live Editing Inside the Terminal: Pressing SPACE enters Editor Mode for the current card. UP and DOWN cycle through all fields inside the card. Pressing ENTER edits the selected field, writing the new value immediately to Google Sheets via values.update calls using column-letter mapping, safe row indexing, and immediate local data sync.&lt;/p&gt;

&lt;p&gt;Practical Development Benefits: Allows real-time balancing of Skill 1 through 4 values like power, cost, type, traits, chances, and durations without tabbing between Unity, Sheets, and CSVs. Instantly corrects card names, factions, rarity, stats, quotes, and avatar IDs. This creates a zero-friction iteration loop where you can test a Duckmon in Unity, alt-tab to the terminal, adjust its stats, save instantly, and re-run the battle flow.&lt;/p&gt;

&lt;p&gt;Workflow Details: Features inline field editing without popups or clutter, highlighted field navigation, safe exit flows using DELETE, and lore exclusion to keep the focus on gameplay-critical data.&lt;/p&gt;

&lt;p&gt;Here is the script if anyone wants to repurpose it for there own needs;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTES&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;A heads up before anyone dives in, this is a personal tool i built for my own card sheet so it is rough around the edges in places, but it works fine for my use case.&lt;/p&gt;

&lt;p&gt;The Credentials path / sheet id / spreadsheet id are redacted obviously, swap those with your own service account json + sheet info before running&lt;/p&gt;

&lt;p&gt;get_service() reconnects to the api every time you edit a field instead of caching the connection. Not ideal if you are editing a ton of fields back to back but for me it has never been an issue.&lt;/p&gt;

&lt;p&gt;The HEADER_TO_COL dict is hardcoded to match my sheet's column layout. if you use this and reorder / add columns in your sheet you NEED to update this map too or it'll start writing values to the wrong cells. This is the main thing to watch out for if you fork it&lt;/p&gt;

&lt;p&gt;Edits in editor mode save straight to the sheet the second you hit enter, no confirmation / undo. Works for me since its just my personal card db but if that makes you nervous maybe add a confirm step&lt;/p&gt;

&lt;p&gt;Ironically, "Inteligence" is spelled wrong in the header on purpose (well, not on purpose, just never fixed it). Do not "fix" the typo in the code unless you fix it in your sheet too or the lookup will break.&lt;/p&gt;

&lt;p&gt;No real error handling if the api call fails mid-edit (bad connection etc), it will just kick and curses will dump you back to your terminal, never happened to me but you have been warned.&lt;/p&gt;

&lt;p&gt;The key selection for: delete key = go back / cancel everywhere instead of esc, just a personal preference thing.&lt;/p&gt;

&lt;p&gt;This was built on unix, if you are on windows you will need windows-curses installed for this to even run. (pip install windows-curses)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.oauth2.service_account&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Credentials&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;googleapiclient.discovery&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# GOOGLE SHEETS CONFIG
# -----------------------------
&lt;/span&gt;
&lt;span class="c1"&gt;# NOTE: All sensitive values (spreadsheet ID, credentials path, sheet name)
# have been intentionally redacted for security.
&lt;/span&gt;
&lt;span class="n"&gt;SPREADSHEET_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Redacted&lt;/span&gt;
&lt;span class="n"&gt;CREDENTIALS_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Redacted&lt;/span&gt;
&lt;span class="n"&gt;SHEET_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Redacted&lt;/span&gt;
&lt;span class="n"&gt;RANGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;SHEET_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!A:AP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# COLUMN LETTER MAP
# -----------------------------
&lt;/span&gt;&lt;span class="n"&gt;HEADER_TO_COL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Faction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Rarity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;D&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Attack Top Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;E&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Defense Bottom Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Inteligence Left Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;G&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dexterity Right Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;H&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Total Stats Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gold Sell Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;J&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Avatar ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;K&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Quote ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;L&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;QuoteText&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;M&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Lore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;N&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;O&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 1 Energy Cost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;P&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 1 Energy Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 1 Effect Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;R&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 1 Effect Chance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 1 Effect Duration&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;T&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 1 Attack Power&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;U&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;V&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 2 Energy Cost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;W&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 2 Energy Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 2 Effect Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Y&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 2 Effect Chance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Z&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 2 Effect Duration&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 2 Attack Power&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 3 Energy Cost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 3 Energy Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 3 Effect Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AF&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 3 Effect Chance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 3 Effect Duration&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 3 Attack Power&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AJ&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 4 Energy Cost&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 4 Energy Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 4 Effect Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 4 Effect Chance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 4 Effect Duration&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AO&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 4 Attack Power&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# SHEETS SERVICE
# -----------------------------
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_service&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;creds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Credentials&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_service_account_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;CREDENTIALS_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;scopes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.googleapis.com/auth/spreadsheets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sheets&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# LOAD GOOGLE SHEETS
# -----------------------------
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_sheet&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_service&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spreadsheets&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;spreadsheetId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SPREADSHEET_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RANGE&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;values&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]:&lt;/span&gt;
        &lt;span class="n"&gt;row_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;row_dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
        &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row_dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# UPDATE CELL
# -----------------------------
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;header_name&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;HEADER_TO_COL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="n"&gt;col_letter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HEADER_TO_COL&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;header_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_service&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;values&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;new_value&lt;/span&gt;&lt;span class="p"&gt;]]}&lt;/span&gt;
    &lt;span class="c1"&gt;# +2 because row_index is 0-based and row 1 is headers
&lt;/span&gt;    &lt;span class="n"&gt;sheet_row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row_index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="n"&gt;rng&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;SHEET_NAME&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;col_letter&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;sheet_row&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spreadsheets&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;spreadsheetId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SPREADSHEET_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;valueInputOption&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;USER_ENTERED&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# INPUT BOX
# -----------------------------
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;prompt_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getmaxyx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;noecho&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# COLUMN SELECTOR
# -----------------------------
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getmaxyx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT COLUMN (UP/DOWN, ENTER, DELETE = cancel)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attron&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A_REVERSE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attroff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A_REVERSE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_UP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DOWN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_ENTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# UNIFIED SEARCH
# -----------------------------
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# VIEWER (READ-ONLY)
# -----------------------------
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getmaxyx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VERTICAL CARD VIEWER (UP/DOWN scroll, DELETE = back)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;hname&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;hname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;card lore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;

        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_UP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DOWN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# VIEWER WITH EDITOR MODE
# -----------------------------
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;viewer_editor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;editing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;field_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="c1"&gt;# build list of editable headers (exclude lore)
&lt;/span&gt;    &lt;span class="n"&gt;editable_headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;card lore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getmaxyx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;editing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VERTICAL CARD VIEWER (UP/DOWN cards, SPACE = edit, DELETE = back)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EDITOR MODE (UP/DOWN fields, ENTER = edit, DELETE = exit editor)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hname&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;editable_headers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;editing&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;field_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attron&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A_REVERSE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attroff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A_REVERSE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;

        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;editing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_UP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DOWN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nf"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;editing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
                &lt;span class="n"&gt;field_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_UP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;field_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;editable_headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DOWN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;field_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;editable_headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_ENTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;header_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;editable_headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter new value for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;header_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="n"&gt;new_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;prompt_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="c1"&gt;# update local data
&lt;/span&gt;                &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;header_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_val&lt;/span&gt;
                &lt;span class="c1"&gt;# write back to sheet
&lt;/span&gt;                &lt;span class="nf"&gt;update_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;editing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="c1"&gt;# -----------------------------
# MAIN
# -----------------------------
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;curs_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_sheet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ERROR: No data loaded from Google Sheets.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Press any key to exit.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="n"&gt;menu_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Skill Name (Skill 1–4)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Skill Effect Type / Trait (Skill 1–4)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Rarity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Faction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Card Fields (Number, Name, Stats, Gold)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search ANY Column&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Show ALL Cards&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Show ALL Cards (Editor Mode)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Exit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getmaxyx&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MASTER READER — SEARCH MENU (UP/DOWN, ENTER, DELETE)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;menu_options&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
            &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attron&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A_REVERSE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attroff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;A_REVERSE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_UP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;menu_options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DOWN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;menu_options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_ENTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;menu_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Skill Name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;prompt_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter skill name:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No matches found. Press any key.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="nf"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Skill Effect Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;prompt_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter skill effect type / trait:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 1 Effect Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 2 Effect Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 3 Effect Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Skill 4 Effect Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No matches found. Press any key.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="nf"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Rarity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;prompt_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter rarity:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Rarity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No matches found. Press any key.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="nf"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Faction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;prompt_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter faction:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Faction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No matches found. Press any key.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="nf"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search Card Fields&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;select_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Faction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Card Rarity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Attack Top Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Defense Bottom Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Inteligence Left Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dexterity Right Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Total Stats Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gold Sell Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;prompt_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter search term for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No matches found. Press any key.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                        &lt;span class="k"&gt;continue&lt;/span&gt;
                    &lt;span class="nf"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search ANY Column&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;select_column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;prompt_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter search term for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No matches found. Press any key.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                        &lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                        &lt;span class="k"&gt;continue&lt;/span&gt;
                    &lt;span class="nf"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Show ALL Cards&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nf"&gt;viewer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Show ALL Cards (Editor Mode)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nf"&gt;viewer_editor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdscr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Exit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;

        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEY_DC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;curses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I Will continue to provide updates on my progress for any interested parties, and for my own sanity, :)&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Duckmon: The Demo Was Ready, The Game Was Not</title>
      <dc:creator>John</dc:creator>
      <pubDate>Mon, 20 Jul 2026 20:49:24 +0000</pubDate>
      <link>https://dev.to/asx/duckmon-the-demo-was-ready-the-game-was-not-34dm</link>
      <guid>https://dev.to/asx/duckmon-the-demo-was-ready-the-game-was-not-34dm</guid>
      <description>&lt;h1&gt;
  
  
  Duckmon: The Demo Was Ready, But the Game Was Not
&lt;/h1&gt;

&lt;p&gt;It's been a long time since my last dev.to post, the 12th of February, to be exact. Back then, Duckmon was getting closer and closer to becoming demo ready. After another four or five weeks, it was right on the edge of a release. The loop worked. The systems were stable. The artwork was 99% complete and implemented. The UI flowed end to end, achievements popped, everything was working as intended, and even the server-authoritative backend was humming along with no issues.&lt;/p&gt;

&lt;p&gt;I had registration, verification, card packs, a binder, a shop, factions, and over 300 cards with full art, stats, and lore. I had player profiles, avatars, quote systems, experience and leveling systems, a full soundtrack, and full SFX.&lt;/p&gt;

&lt;p&gt;I was polishing. I was debugging. I was preparing for a real demo release not just a small vertical slice, but a full demo, fully playable, with some sections intentionally blocked off.&lt;/p&gt;

&lt;p&gt;And then something happened.&lt;/p&gt;

&lt;p&gt;I realised the demo was ready… but the game wasn't.&lt;/p&gt;

&lt;p&gt;Not in the sense of bugs or missing features, those were tamed and handled after months of solo work. It was something deeper.&lt;/p&gt;

&lt;p&gt;The loop worked, but it didn't feel alive yet. There was no excitement for me. Every developer's worst self-doubt kicked in: my game is almost finished, but it's boring. After a few matches, even I was bored.&lt;/p&gt;

&lt;p&gt;It needed more depth.&lt;br&gt;
More retention.&lt;br&gt;
More strategy.&lt;br&gt;
More "just one more match" energy.&lt;br&gt;
Some excitement.&lt;/p&gt;

&lt;p&gt;So instead of releasing the demo, I made one of the hardest decisions a solo dev can probably make: I paused the release and expanded the game.&lt;/p&gt;

&lt;h2&gt;
  
  
  Falling Off, Then Finding My Way Back
&lt;/h2&gt;

&lt;p&gt;At the same time, I'd been neglecting everything around the project, not just the game itself. My website hadn't been updated since I made it. My Discord had been abandoned. Even here on dev.to, I'd gone quiet for six months.&lt;/p&gt;

&lt;p&gt;Eventually I neglected the project itself too. I didn't touch Unity for about six weeks or more. Supabase kept pausing my backend from lack of activity. I lost my motivation.&lt;/p&gt;

&lt;p&gt;What pulled me back was simple: I didn't want to have wasted all this time and effort. I wanted to get this project past the point where "working" is enough.&lt;/p&gt;

&lt;p&gt;Duckmon started as a minigame in the first project I ever attempted - my first time ever using Unity or writing code. Then it tried to be a game in Roblox, who weren't too happy with my art style and handed me multiple bans. So I came back to Unity, where nothing restricted me, and it became its own standalone project. After a lot of cursing, late nights, and effort, it finally started to feel like my own multiverse.&lt;/p&gt;

&lt;p&gt;When I booted the project back up to "finish the fight", the battle loop, as functional as it was, felt too shallow for the kind of game I wanted players to sink into. It felt like a cheap knockoff. A poser. An imposter.&lt;/p&gt;

&lt;p&gt;I didn't want Duckmon to be a play-once-and-forget indie game, or something people looked at and called AI slop. I wanted it to be a game people return to, a game with layers, with strategy, with its own identity. Rough, yes. Amateur, hell yeah. But mine.&lt;/p&gt;

&lt;p&gt;So I asked myself: what would make Duckmon worth playing for weeks instead of minutes? What does it need to actually feel replayable and engaging?&lt;/p&gt;

&lt;p&gt;The answer was obvious: depth, systems, strategy, choice, tactics, all balanced with a little luck and future competition. And that meant expanding the battle system far beyond the original scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Squad Battle Mode: The Big Expansion
&lt;/h2&gt;

&lt;p&gt;The first major addition was Squad Battle Mode, a full team-based battler inspired by games like Pokémon and from other RPG battle systems, plus my own obsession with tactical card combat.&lt;/p&gt;

&lt;p&gt;This wasn't just "add more cards." It was a structural reimagining, taking my existing dataset, my card databases, and figuring out how to actually use and expand what I already had.&lt;/p&gt;

&lt;p&gt;Using the cards a player has collected and their active deck, Squad Battle Mode is a 5v5 battle with active and bench units. Every card becomes a unit with 4 unique skills, HP, team energy, elemental typing, and strengths/weaknesses. On top of that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KO → auto-swap logic&lt;/li&gt;
&lt;li&gt;Graveyard tracking&lt;/li&gt;
&lt;li&gt;Team energy economy&lt;/li&gt;
&lt;li&gt;A hybrid system of turn-based and action-based status ticking&lt;/li&gt;
&lt;li&gt;Damage over time, crowd control, buffs, and debuffs&lt;/li&gt;
&lt;li&gt;Team buffs and enemy debuffs&lt;/li&gt;
&lt;li&gt;Faction synergy&lt;/li&gt;
&lt;li&gt;Real tactical decision making, with a little luck mixed in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suddenly Duckmon wasn't just a card battler. It was a team strategy game. And it felt right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Story Mode: A Second Pillar of Duckmon
&lt;/h2&gt;

&lt;p&gt;While Squad Battle Mode was growing the tactical side of the game, a completely different part of the project was growing alongside it, slower, more atmospheric, a narrative-driven aspect.&lt;/p&gt;

&lt;p&gt;Story Mode is inspired by classic choose-your-own-adventure books. Every decision leads to a new node, every node branches into two choices, and every choice pushes the player toward one of ten real endings, plus plenty of game-over endings along the way. It's not a card battler. It's backstory. It's lore you can actually walk through.&lt;/p&gt;

&lt;p&gt;Chapter one of the Electric Faction is already done — full artwork, its own soundtrack, a complete narrative arc. The rest of the faction chapters will get built out depending on how Story Mode lands in the demo.&lt;/p&gt;

&lt;p&gt;Story Mode rewards gold for card packs, but it's not required for progression. It sits alongside the other modes as something optional and atmospheric — a way to explore the world behind the cards without having to fight for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Battle Modes That Now Define Duckmon
&lt;/h2&gt;

&lt;p&gt;Duckmon now has multiple gameplay pillars working together instead of competing with each other: Story Mode for narrative depth, the original battle mode for fast matches, and Squad Battle Mode for tactical depth. Squad Battle Mode itself is planned to expand into six variants:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Classic Squad Battle Mode&lt;/strong&gt; — the core 5v5 team battler, built around a player's own cards, deck, synergies, and strategy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ranked PVP&lt;/strong&gt; — a competitive mode where players fight each other with their own squads, rewarding consistency, strategy, and mastery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Friendly PVP&lt;/strong&gt; — the casual version. No pressure, no ranking, just play.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seasonal Squad Mode&lt;/strong&gt; — a rotating format using predetermined batches of cards. One season might be Ice Faction only, another Epic rarity only, another a curated balance set. Ranked and friendly versions will exist here too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Challenge Mode&lt;/strong&gt; — fighting AI-controlled squads with predetermined cards. No deck building, no collection advantage, just pure tactical problem-solving.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Squad Battles&lt;/strong&gt; — the AI brain is already built specifically for Squad Battle Mode. It reads the board state, tracks energy, evaluates threats, and makes decisions using the same rules the player does, so players can test their squads against something genuinely smart.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Building a Pokémon-Style Battler With My Existing Assets
&lt;/h2&gt;

&lt;p&gt;I didn't want to reinvent the wheel. I wanted to evolve what I already had.&lt;/p&gt;

&lt;p&gt;So I took my existing Duckmon cards : the art, the stats, the lore, and built a full Pokémon-style combat system around them, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A draft system based on the player's currently equipped deck&lt;/li&gt;
&lt;li&gt;Element types and a full type-effectiveness chart&lt;/li&gt;
&lt;li&gt;Status conditions, DOT effects, skip-turn CC, action-based penalties, turn-based durations&lt;/li&gt;
&lt;li&gt;Team energy gain rules&lt;/li&gt;
&lt;li&gt;Server-authoritative combat resolution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything had to be formula accurate, consistent, and scalable. This wasn't a minigame anymore. It was a battle engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Skill System: The Heart of the Depth
&lt;/h2&gt;

&lt;p&gt;To make battles actually mean something, I needed real skills, not placeholders. So I built, and I'm still actively expanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A full skill system&lt;/li&gt;
&lt;li&gt;A CSV-driven skill database, expanded into a dual-purpose master data holder&lt;/li&gt;
&lt;li&gt;A runtime skill executor&lt;/li&gt;
&lt;li&gt;A buff/debuff manager and a status manager&lt;/li&gt;
&lt;li&gt;A DOT system and a team buff system&lt;/li&gt;
&lt;li&gt;A damage calculator, hit chance formula, and turn order formula&lt;/li&gt;
&lt;li&gt;Shield and reflect systems&lt;/li&gt;
&lt;li&gt;A battle stat recalculation pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every skill is a mix of power values, percent values, flat values, duration and tick rules, stat scaling (attack, defence, intelligence, dexterity), element synergies, rarity, status effects, team effects, and healing/cleansing/recovery/revival.&lt;/p&gt;

&lt;p&gt;I've expanded the CSV to include attack skills, support skills, DOT, CC, team buffs, debuffs, healing, shields, reflects, avoidance, energy manipulation, faction-specific moves, and mythic-tier abilities.&lt;/p&gt;

&lt;p&gt;Every Duckmon now has a real identity, not just stats, but a moveset that feels like it belongs to that specific card, built with team synergy and playstyle in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging: The Solo Dev Reality
&lt;/h2&gt;

&lt;p&gt;This part isn't glamorous, but it's real.&lt;/p&gt;

&lt;p&gt;I've spent countless nights debugging and refactoring: status stacking, duration ticking, DOT timing, energy economy, turn order, skill resolution, shield absorption, reflect damage, bench logic, KO logic, graveyard logic, swap logic, UI flow, server sync, race conditions, edge cases, null references, CSV parsing, runtime stat recalculation.&lt;/p&gt;

&lt;p&gt;Solo dev isn't just building. It's fixing. And fixing. And fixing again. And once it's all fixed (it isn't, so break it and fix it again), every fix still made the game stronger.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Decision to Reject Monetization
&lt;/h2&gt;

&lt;p&gt;This part matters to me.&lt;/p&gt;

&lt;p&gt;I don't want Duckmon to be a gacha trap. I don't want it to be a microtransaction machine. I don't want it to be a "pay to progress" game. I want it to be a game first.&lt;/p&gt;

&lt;p&gt;So I made the decision:&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;No monetization in the demo. No monetization in the core game loop. No monetization until the game is worth paying for — if ever, and if that happened, the only monetization would be the purchasing of the game at a cheap price anyway (to possibly cover the steam fees, if i ever get there), no micro transactions in the game ... ever *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The cards you get, from the second you get them, are yours at full potential. No grinding for duplicates, no leveling up cards. You own it, you use it, that's it.&lt;/p&gt;

&lt;p&gt;I'm building Duckmon because I wanted to build something I can be proud of , something I built alone, by myself, starting with zero coding experience, not for the money, just for the love of it. Something I can point to and say, "I built that." Not because I want to squeeze players.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Duckmon Stands Today
&lt;/h2&gt;

&lt;p&gt;Duckmon is no longer a minigame. It's no longer a prototype. It's no longer a "maybe someday" project.&lt;/p&gt;

&lt;p&gt;It's a real game:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server-authoritative backend&lt;/li&gt;
&lt;li&gt;Email registration and verification&lt;/li&gt;
&lt;li&gt;Card packs, binder, shop, factions&lt;/li&gt;
&lt;li&gt;310 cards&lt;/li&gt;
&lt;li&gt;Full battle engine, skill system, status system, DOT/CC system&lt;/li&gt;
&lt;li&gt;Full team battle mode&lt;/li&gt;
&lt;li&gt;Full UI flow and full demo loop&lt;/li&gt;
&lt;li&gt;Story Mode chapter one&lt;/li&gt;
&lt;li&gt;Multiple planned Squad Battle variants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Real depth. Real strategy. Real retention. Real fun.&lt;/p&gt;

&lt;p&gt;The demo isn't delayed. It's evolving. Slowly, i am getting there and i also plan to post updates here more regularly, no promises, but that is my intention. &lt;/p&gt;

</description>
      <category>unity3d</category>
      <category>gamedev</category>
      <category>beginners</category>
      <category>csharp</category>
    </item>
    <item>
      <title>From my first Dev.to challenge to building my own website.</title>
      <dc:creator>John</dc:creator>
      <pubDate>Thu, 12 Feb 2026 10:08:12 +0000</pubDate>
      <link>https://dev.to/asx/from-my-first-devto-challenge-to-building-my-own-website-2ph7</link>
      <guid>https://dev.to/asx/from-my-first-devto-challenge-to-building-my-own-website-2ph7</guid>
      <description>&lt;p&gt;Chaos to Concept: How I Built a Solo Game Dev Site Without a Single "Hello World".&lt;/p&gt;

&lt;p&gt;We’ve all seen the "My first website" posts. Usually, they start with a FreeCodeCamp certificate or some YouTube video tutorials, basically, a "Hello World" tutorial.&lt;/p&gt;

&lt;p&gt;I didn't do any of that. I don't like being told how to build things. I like breaking things until they work. I’m a solo dev, a dad, and a husband who decided to stop playing games and start building them from scratch. No training. No prior experience. &lt;/p&gt;

&lt;p&gt;I have not posted for a while and been absorbed in real life challenges, and my game dev challenges, it has all been one crazy journey, trial by fire and lots of self learned lessons.&lt;/p&gt;

&lt;p&gt;Here is the evolution of my web dev journey, from a Dev.to challenge entry to the official home of my solo game studio and i would like to give props to Dev.to for making this even possible for me, in the sense that if i had not participated in this Halloween challenge in October 2025 , i would never have attempted to create this website.&lt;/p&gt;

&lt;p&gt;Project 1: The "TextZ Ombie" Shrine&lt;br&gt;
The Goal: A landing page for a Dev.to Halloween challenge. The Reality:&lt;a href="https://asxgtr.github.io/TextZ-Ombie-Landing-Page/" rel="noopener noreferrer"&gt;https://asxgtr.github.io/TextZ-Ombie-Landing-Page/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was my "Trial by Fire." I didn't use a tutorial; I just started throwing HTML and CSS at the wall to see what stuck, and if i am being totally honest, a lot of questions to A.I.&lt;/p&gt;

&lt;p&gt;The Vibe: Pure 90s-style chaos.&lt;/p&gt;

&lt;p&gt;The Win: I actually got audio elements working and figured out how to animate emojis to create a "horde" feel. I was proud of my first attempt although i knew it was very "amateur".&lt;/p&gt;

&lt;p&gt;The Lesson: I realized that while I could make a page "work," it didn't tell a story. It was a collection of assets, not a brand. A toe in the water. &lt;/p&gt;

&lt;p&gt;The Pivot: Becoming a Solo "Studio" (in a small sense)&lt;/p&gt;

&lt;p&gt;Between the first site and the second, my game development spiraled. My first project, TextZ Ombie, taught me about systems and UI. Even if it is temporarily on hold, 6 months of game dev from scratch taught me a lot more than any tutorial ever could, and during this development i was creating something in TextZ Ombie that deserved to be a standalone..     So then Duckmon happened, a duck powered card battler that exploded from a minigame into its own standalone multiverse. A combination of card collecting, and a card battle game inspired by the mechanics from Triple Triad (FF8).&lt;/p&gt;

&lt;p&gt;I realized I didn't just need a "page", I needed a headquarters, not a discord server, something that is my own.&lt;/p&gt;

&lt;p&gt;Project 2: Quackwork Studios&lt;br&gt;
The Goal: A professional (more so than project one), "Real &amp;amp; Raw" home for my games. The Reality: &lt;a href="https://quackworkstudios.com/" rel="noopener noreferrer"&gt;https://quackworkstudios.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where the growth really shows. I stayed true to my "No Tutorial" rule, but this time I focused on intentionality.&lt;/p&gt;

&lt;p&gt;What changed?&lt;/p&gt;

&lt;p&gt;Identity: I moved away from the neon on black chaos to a more sophisticated "Dark Mode" aesthetic that screams "Indie Dev."&lt;/p&gt;

&lt;p&gt;The Stack: I integrated things I never thought I'd touch Cloudflare, Ionos, and even Supabase/Resend for the backend contact forms. Wiring together DNS and Github and all other things i basically do not understand , until it just "worked"&lt;/p&gt;

&lt;p&gt;The Narrative: Instead of just showing assets, I’m showing a journey. The site now features a devlog, active project tracking, and a clear "About" section that explains my philosophy: A.I assisted, Solo built.&lt;/p&gt;

&lt;p&gt;The "No Tutorial" Comparison&lt;br&gt;
Website 1 (TextZ Ombie) &lt;br&gt;
Website 2 (Quackwork Studios)&lt;/p&gt;

&lt;p&gt;Why I’m Sharing This&lt;br&gt;
I see a lot of people get stuck in "tutorial hell." They’re afraid to build because they haven't finished a course yet, have not got a certificate, done the training, did the "Hello World". &lt;/p&gt;

&lt;p&gt;My advice? &lt;/p&gt;

&lt;p&gt;Just build it. My first site was a mess of emojis and raw HTML. &lt;/p&gt;

&lt;p&gt;My second site is the more professional (Lightly) face of my studio. All anyone needs is a stubborn idea and the willingness to fail until it looked right.&lt;/p&gt;

&lt;p&gt;I’m currently building Duckmon in Unity and this project is coming along fantastically right now, with a working server authoritative stance, working legit Email registration, verification and support. Card pack openings, Card Binder, a Shop, Faction screens, a 310 Card collection each with unique full card art, stats and lore. It is really not too far from a demo release state (with the need for further polishing). But more importantly it is working, like a real game.&lt;/p&gt;

&lt;p&gt;If you’re a solo dev or a "creationist" who uses AI to amplify your workflow, I’d love to connect or hear your story/stories.&lt;/p&gt;

&lt;p&gt;What was the one project that made you feel like you finally "leveled up" from a idea to a creator?&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>unity3d</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Dev Log 38 - The Christmas Resurrection (Kind - Of )</title>
      <dc:creator>John</dc:creator>
      <pubDate>Mon, 22 Dec 2025 00:48:16 +0000</pubDate>
      <link>https://dev.to/asx/dev-log-38-the-christmas-resurrection-kind-of--2gnm</link>
      <guid>https://dev.to/asx/dev-log-38-the-christmas-resurrection-kind-of--2gnm</guid>
      <description>&lt;p&gt;🎄 Dev Log: The Christmas Resurrection&lt;br&gt;
(a.k.a. “Still No Halloween Results”)&lt;/p&gt;

&lt;p&gt;Hello again, internet. Yes, I’m alive. Yes, it’s almost Christmas. No, the Halloween Frontend Challenge results still haven’t been released. I assume the judges were eaten by CSS goblins. Happens.&lt;/p&gt;

&lt;p&gt;Anyway. I am here to talk about why I vanished.&lt;/p&gt;

&lt;p&gt;🎃 1. The Great Dev Log Hiatus&lt;br&gt;
I fully intended to keep posting dev logs. I really did.&lt;/p&gt;

&lt;p&gt;Then the challenge results never came out and my brain went:&lt;/p&gt;

&lt;p&gt;“Ah. Time to hibernate.”&lt;/p&gt;

&lt;p&gt;And so I did.&lt;/p&gt;

&lt;p&gt;🧪 2. The Mini Game That Became a Monster&lt;/p&gt;

&lt;p&gt;I started building a tiny mini‑game inside my main project.&lt;/p&gt;

&lt;p&gt;I thought it was a "mini" game anyway , some fun collectable cards , maybe play again AI in my project, just a little side thing. A distraction. A palate cleanser.&lt;/p&gt;

&lt;p&gt;Naturally, it mutated into its own ecosystem, a full blown 2nd project complete with:&lt;/p&gt;

&lt;p&gt;its own UI&lt;/p&gt;

&lt;p&gt;its own logic&lt;/p&gt;

&lt;p&gt;its own lore&lt;/p&gt;

&lt;p&gt;its own problems&lt;/p&gt;

&lt;p&gt;its own identity crisis&lt;/p&gt;

&lt;p&gt;Classic me.&lt;/p&gt;

&lt;p&gt;🟦 3. The Roblox Arc (a.k.a. My Exile)&lt;br&gt;
Then I decided to “learn Roblox scripting for fun.”&lt;/p&gt;

&lt;p&gt;Turns out roblox has it's own coding language , a version of Lua, specifically a customized version known as Luau.&lt;/p&gt;

&lt;p&gt;I had never even heard of it , but the promise of free server hosting , and taking care of all the fiddly stuff, was enough for me to give it a try.&lt;/p&gt;

&lt;p&gt;This was a mistake.&lt;/p&gt;

&lt;p&gt;Within days ( or weeks ):&lt;/p&gt;

&lt;p&gt;I got a warning&lt;/p&gt;

&lt;p&gt;Then a 1‑day ban&lt;/p&gt;

&lt;p&gt;Then a 3‑day ban&lt;/p&gt;

&lt;p&gt;All because the AI moderation system decided that any amount of visible skin is a war crime.&lt;/p&gt;

&lt;p&gt;I wasn’t even making anything weird. I was making a card game. A card Game where the main subject is ducks. Apparently elbows are forbidden, as are any ducks with 6 packs.&lt;/p&gt;

&lt;p&gt;So I left Roblox like a disgraced wizard and returned to Unity while i await the banishment, like a peasant thrown from the village.&lt;/p&gt;

&lt;p&gt;🧱 4. The Birth of This New Project&lt;/p&gt;

&lt;p&gt;Out of the ashes of my Roblox exile came this new Unity project. ( side project ) &lt;/p&gt;

&lt;p&gt;It started simple:&lt;/p&gt;

&lt;p&gt;Title screen&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd4gsjx1qzlhzoi3os8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjd4gsjx1qzlhzoi3os8p.png" alt=" " width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Credits panel&lt;/p&gt;

&lt;p&gt;Settings panel&lt;/p&gt;

&lt;p&gt;Then I blinked and suddenly I had:&lt;/p&gt;

&lt;p&gt;A global audio engine&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using UnityEngine;
using System.Collections;

namespace Audio
{
    public class AudioManager : MonoBehaviour
    {
        public static AudioManager Instance;

        [Header("Music")]
        public AudioClip titleTheme;
        private AudioSource musicSource;

        [Header("SFX Looping")]
        private AudioSource sfxLoopSource;

        private bool hasFadedOut = false;
        private float fadeDuration = 8f;

        void Awake()
        {
            if (Instance != null &amp;amp;&amp;amp; Instance != this)
            {
                Destroy(gameObject);
                return;
            }

            Instance = this;
            DontDestroyOnLoad(gameObject);

            // Create audio sources
            musicSource = gameObject.AddComponent&amp;lt;AudioSource&amp;gt;();
            musicSource.loop = true;
            musicSource.playOnAwake = false;

            sfxLoopSource = gameObject.AddComponent&amp;lt;AudioSource&amp;gt;();
            sfxLoopSource.loop = true;
            sfxLoopSource.playOnAwake = false;

            ApplyVolumesFromOptions();
            PlayTitleTheme();
        }

        public void ApplyVolumesFromOptions()
        {
            if (AudioOptionsManager.Instance != null)
            {
                AudioListener.volume = AudioOptionsManager.Instance.MasterVolume;
                musicSource.volume = AudioOptionsManager.Instance.MusicVolume;
                sfxLoopSource.volume = AudioOptionsManager.Instance.SFXVolume;

                Debug.Log("[AudioManager] Volumes synced from AudioOptionsManager.");
            }
        }

        public void PlayTitleTheme()
        {
            if (titleTheme != null &amp;amp;&amp;amp; !hasFadedOut)
            {
                musicSource.clip = titleTheme;
                musicSource.loop = true;
                musicSource.Play();
            }
        }

        public void StopMusic()
        {
            musicSource.Stop();
        }

        public void FadeOutMusic()
        {
            if (!hasFadedOut)
            {
                StartCoroutine(FadeOutRoutine());
            }
        }

        private IEnumerator FadeOutRoutine()
        {
            hasFadedOut = true;
            float startVolume = musicSource.volume;
            musicSource.loop = false;

            for (float t = 0; t &amp;lt; fadeDuration; t += Time.deltaTime)
            {
                musicSource.volume = Mathf.Lerp(startVolume, 0f, t / fadeDuration);
                yield return null;
            }

            musicSource.volume = 0f;
            musicSource.Stop();
        }

        public void PlayLoop(AudioClip clip, float volume = 1f)
        {
            if (clip == null)
            {
                Debug.LogWarning("[AudioManager] Tried to play null AudioClip.");
                return;
            }

            sfxLoopSource.clip = clip;
            sfxLoopSource.volume = Mathf.Clamp01(volume);
            sfxLoopSource.loop = true;
            sfxLoopSource.Play();
        }

        // Expose sources for external control
        public AudioSource MusicSource =&amp;gt; musicSource;
        public AudioSource SFXLoopSource =&amp;gt; sfxLoopSource;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using UnityEngine;
using UnityEngine.UI;
using Audio;

public class AudioOptionsManager : MonoBehaviour
{
    public static AudioOptionsManager Instance { get; private set; }

    [Header("UI")]
    [SerializeField] private Slider masterSlider;
    [SerializeField] private Slider musicSlider;
    [SerializeField] private Slider sfxSlider;
    [SerializeField] private Button resetButton;
    [SerializeField] private Button closeButton;

    [Header("Audio Sources")]
    [SerializeField] private AudioSource musicSource;
    [SerializeField] private AudioSource sfxLoopSource;

    public const float DefaultMasterVolume = 0.75f;
    public const float DefaultMusicVolume = 0.75f;
    public const float DefaultSFXVolume = 0.75f;

    private float masterVolume = DefaultMasterVolume;
    private float musicVolume = DefaultMusicVolume;
    private float sfxVolume = DefaultSFXVolume;

    public float MasterVolume =&amp;gt; masterVolume;
    public float MusicVolume =&amp;gt; musicVolume;
    public float SFXVolume =&amp;gt; sfxVolume;

    private void Awake()
    {
        Instance = this;
    }

    private void Start()
    {
        // Auto-assign sources from AudioManager
        if (AudioManager.Instance != null)
        {
            if (musicSource == null)
                musicSource = AudioManager.Instance.MusicSource;

            if (sfxLoopSource == null)
                sfxLoopSource = AudioManager.Instance.SFXLoopSource;
        }

        // Wire UI
        masterSlider.onValueChanged.AddListener(OnMasterVolumeChanged);
        musicSlider.onValueChanged.AddListener(OnMusicVolumeChanged);
        sfxSlider.onValueChanged.AddListener(OnSFXVolumeChanged);
        resetButton.onClick.AddListener(OnResetAudio);
        closeButton.onClick.AddListener(OnClosePressed);

        // Initialize sliders
        masterSlider.value = masterVolume;
        musicSlider.value = musicVolume;
        sfxSlider.value = sfxVolume;

        ApplyVolumes();
    }

    private void OnMasterVolumeChanged(float value)
    {
        masterVolume = Mathf.Clamp01(value);
        ApplyVolumes();
    }

    private void OnMusicVolumeChanged(float value)
    {
        musicVolume = Mathf.Clamp01(value);
        ApplyVolumes();
    }

    private void OnSFXVolumeChanged(float value)
    {
        sfxVolume = Mathf.Clamp01(value);
        ApplyVolumes();
    }

    private void OnResetAudio()
    {
        masterVolume = DefaultMasterVolume;
        musicVolume = DefaultMusicVolume;
        sfxVolume = DefaultSFXVolume;

        masterSlider.value = masterVolume;
        musicSlider.value = musicVolume;
        sfxSlider.value = sfxVolume;

        ApplyVolumes();
    }

    private void ApplyVolumes()
    {
        AudioListener.volume = masterVolume;

        if (musicSource != null)
            musicSource.volume = musicVolume;

        if (sfxLoopSource != null)
            sfxLoopSource.volume = sfxVolume;
    }

    private void OnClosePressed()
    {
        // MenuManager handles showing/hiding the panel
        gameObject.SetActive(false);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A clean UI architecture&lt;/p&gt;

&lt;p&gt;A proper menu flow&lt;/p&gt;

&lt;p&gt;A credits panel that actually scrolls ( growth! )&lt;/p&gt;

&lt;p&gt;Progress is faster this time because I actually know Unity now. I no longer open the editor, panic, and close it for two days.&lt;/p&gt;

&lt;p&gt;Character development.&lt;/p&gt;

&lt;p&gt;🧩 5. The PlayFab Signup&lt;/p&gt;

&lt;p&gt;At some point I also signed up for PlayFab. ( Today ) &lt;/p&gt;

&lt;p&gt;Why? Because future me will need:&lt;/p&gt;

&lt;p&gt;cloud saves&lt;/p&gt;

&lt;p&gt;player data&lt;/p&gt;

&lt;p&gt;inventory syncing&lt;/p&gt;

&lt;p&gt;maybe multiplayer&lt;/p&gt;

&lt;p&gt;maybe trading&lt;/p&gt;

&lt;p&gt;maybe a full backend economy&lt;/p&gt;

&lt;p&gt;Or maybe I just like dashboards. Hard to say.&lt;/p&gt;

&lt;p&gt;🃏 6. The 310‑Card Database&lt;/p&gt;

&lt;p&gt;Yes. I imported 310 cards into Unity.&lt;/p&gt;

&lt;p&gt;All with:&lt;/p&gt;

&lt;p&gt;names&lt;/p&gt;

&lt;p&gt;stats&lt;/p&gt;

&lt;p&gt;rarities&lt;/p&gt;

&lt;p&gt;factions&lt;/p&gt;

&lt;p&gt;lore&lt;/p&gt;

&lt;p&gt;effects&lt;/p&gt;

&lt;p&gt;spreadsheet‑driven data&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz56mywjpt84qxno6sq63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz56mywjpt84qxno6sq63.png" alt=" " width="800" height="238"&gt;&lt;/a&gt;&lt;br&gt;
This is the moment I realised:&lt;/p&gt;

&lt;p&gt;“Oh. This isn’t a mini‑project anymore.”&lt;/p&gt;

&lt;p&gt;This is a real game now.&lt;/p&gt;

&lt;p&gt;A few Examples ..&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1wvpks9gepplejldba9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1wvpks9gepplejldba9.png" alt=" " width="480" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61so73cmjyrpxnfjdsyg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61so73cmjyrpxnfjdsyg.png" alt=" " width="385" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh46mybormyk8cle95cn1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh46mybormyk8cle95cn1.png" alt=" " width="477" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiis5x5jkh932v8skvkgf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiis5x5jkh932v8skvkgf.png" alt=" " width="478" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and another 306 more !! ( i was still busy , sidetracked very much ) &lt;/p&gt;

&lt;p&gt;🧠 7. The Present Day&lt;br&gt;
Right now the project has:&lt;/p&gt;

&lt;p&gt;a clean title screen&lt;/p&gt;

&lt;p&gt;a working settings panel&lt;/p&gt;

&lt;p&gt;a scrolling credits panel&lt;/p&gt;

&lt;p&gt;a global audio system&lt;/p&gt;

&lt;p&gt;a database of 310 cards&lt;/p&gt;

&lt;p&gt;a PlayFab backend ready to be used&lt;/p&gt;

&lt;p&gt;a developer who is no longer afraid of Unity&lt;/p&gt;

&lt;p&gt;and a dev log that has risen from the dead&lt;/p&gt;

&lt;p&gt;🎁 8. What’s Next&lt;/p&gt;

&lt;p&gt;In no particular order:&lt;/p&gt;

&lt;p&gt;UI transitions&lt;/p&gt;

&lt;p&gt;One‑shot SFX&lt;/p&gt;

&lt;p&gt;Scene loading&lt;/p&gt;

&lt;p&gt;Card binder&lt;/p&gt;

&lt;p&gt;Card inspection&lt;/p&gt;

&lt;p&gt;Gameplay prototype&lt;/p&gt;

&lt;p&gt;More lore&lt;/p&gt;

&lt;p&gt;More chaos&lt;/p&gt;

&lt;p&gt;And maybe — just maybe — the Halloween challenge results.&lt;/p&gt;

&lt;p&gt;Merry Christmas&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftleszu6n71a4v20erxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftleszu6n71a4v20erxy.png" alt=" " width="800" height="894"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>unity3d</category>
      <category>beginners</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Dev Log 37 - Consolidated Update</title>
      <dc:creator>John</dc:creator>
      <pubDate>Sat, 15 Nov 2025 13:44:13 +0000</pubDate>
      <link>https://dev.to/asx/dev-log-37-consolidated-update-oo7</link>
      <guid>https://dev.to/asx/dev-log-37-consolidated-update-oo7</guid>
      <description>&lt;p&gt;Consolidated Update&lt;br&gt;
Date: 15 November 2025 &lt;/p&gt;

&lt;p&gt;Hi, to anyone still reading my logs, this log entry is a consolidation of some recent personal dev logs , consolidated as a single log for myself, so not much of a fun or exciting read. &lt;/p&gt;

&lt;p&gt;Fixed discard/resurrection and opener-swap bugs; &lt;br&gt;
Hardened inventory/registry/loot flows; &lt;br&gt;
Centralized shrine-safe equip checks; &lt;br&gt;
Rewired and polished Use/Loot/Inventory/Gear UI; &lt;br&gt;
Implemented Options + Audio UI and Credits polish;&lt;br&gt;
Restored tooltip pipeline compatibility; &lt;br&gt;
Added defensive guards, logging, and tests.&lt;/p&gt;

&lt;p&gt;Discard flow: true removal of runtime instances; no resurrection from loot or saves.&lt;/p&gt;

&lt;p&gt;InventoryStateManager: unregister-by-reference, compatibility shims, TryGetLiveItemByReference.&lt;/p&gt;

&lt;p&gt;Loot pickup: always instantiate fresh runtime clones and register them before adding to inventory.&lt;/p&gt;

&lt;p&gt;Equip logic: all entry points use TryEquipInventoryItemIfSlotEmpty to prevent Hands overwrite; tooltip remains open on blocked equip.&lt;/p&gt;

&lt;p&gt;Open flow: exact-slot replacement for opened items; apply opener damage only (no removal); preserve state copy from sealed → opened item.&lt;/p&gt;

&lt;p&gt;UI robustness: defensive ExecuteInventoryAction; OpenOptionSlot UI no auto-invoke; Use/Loot/Inventory panels relabeled and rewired.&lt;/p&gt;

&lt;p&gt;Options &amp;amp; Audio UI: OptionsScene + in-game panel; ScreenFader/SceneSkipBlocker integration for Title Menu; functioning Master/Music/SFX sliders.&lt;/p&gt;

&lt;p&gt;Credits screen: new unique background, prefab-safe layout and polish.&lt;/p&gt;

&lt;p&gt;Tooltip pipeline: merged missing members into InventoryItem, ensured hydration and prefab bindings restored.&lt;/p&gt;

&lt;p&gt;Many minor bugs and runtime NREs fixed; added lots of logging / debuggers and probe points.&lt;/p&gt;

&lt;p&gt;Conversation summary (diagnosis → fixes)&lt;/p&gt;

&lt;p&gt;ItemFactory crash due to null registry and opener (knife types) disappearing when opening sealed items.&lt;/p&gt;

&lt;p&gt;Discarded items reappearing when taking loot.&lt;/p&gt;

&lt;p&gt;Tooltip fields/labels not showing after restoring backup → compile errors and prefab binding mismatches.&lt;/p&gt;

&lt;p&gt;Diagnosis and result&lt;/p&gt;

&lt;p&gt;Crash: PlayerInventoryManager.itemRegistry could be null; ItemFactory used it → NRE.&lt;/p&gt;

&lt;p&gt;Knife disappearance: ambiguous ID-based removals or incorrect slot replacement removed openers; asset-reference hydration issues allowed the wrong instance to be removed.&lt;/p&gt;

&lt;p&gt;Discard resurrection: discarded backing assets remained referenced (registry, gear.ContainedAssets or saves) and loot/pickup code reused those references instead of creating fresh instances.&lt;/p&gt;

&lt;p&gt;Tooltip regressions: InventoryItem in current project lacked fields/methods used by other advanced systems; prefab bindings inconsistent between backup and main project.&lt;/p&gt;

&lt;p&gt;Files inspected and iteratively edited&lt;/p&gt;

&lt;p&gt;ItemFactory: add null-registry guards and ensure fresh clone creation via Instantiate or ItemFactory.Create.&lt;/p&gt;

&lt;p&gt;OpenPanelUI.cs: canonical swap now uses ItemFactory.CS - Create, copies sealed→opened state, replaces exact gear slot, applies opener damage without removing opener, refreshes UI.&lt;/p&gt;

&lt;p&gt;ItemOpenerResolver.cs: verified it applies durability only; validated special-case logic (charcoal, tin can).&lt;/p&gt;

&lt;p&gt;PlayerInventoryManager.cs: added instance-based removal overloads (RemoveItem(InventoryItem), RemoveItem(Object)), InsertItemAt/ReplaceItemInPlace, TryGetGearAndIndex, GetSlotIndex; destroyed runtime clones on discard and improved logging.&lt;/p&gt;

&lt;p&gt;InventoryStateManager.cs: added UnregisterItem(InventoryItem), restored MarkItemAsEquipped overloads, TryGetLiveItemByReference, and defensive RegisterItem behavior.&lt;/p&gt;

&lt;p&gt;UsePanelIconRegistry.cs: corrected syntax, added missing keys (slice, repair) and returned clean registry.&lt;/p&gt;

&lt;p&gt;OpenOptionSlotUIManager: Initialize shows target (sealed container) and attaches single click listener (no auto invoke).&lt;/p&gt;

&lt;p&gt;ItemTooltipManager: ExecuteInventoryAction rewritten defensively; preserves attach, discard, equip, use, open, fill, pour, eat, drink flows.&lt;/p&gt;

&lt;p&gt;LootTooltipManager &amp;amp; LootButtonActionManager: patched to use TryEquipInventoryItemIfSlotEmpty and to instantiate fresh clones when taking loot.&lt;/p&gt;

&lt;p&gt;InventorySlotUI: ensured LoadItem/HasItem/GetAsset behave reliably with runtime clones.&lt;/p&gt;

&lt;p&gt;UI wiring: updated Use/Loot/Inventory/Gear button labels and logic to reflect new guard flows.&lt;/p&gt;

&lt;p&gt;Concrete code patterns applied&lt;/p&gt;

&lt;p&gt;Discard pipeline:&lt;/p&gt;

&lt;p&gt;PlayerInventoryManager.RemoveItem(instance) removes from gear.ContainedAssets, destroys runtime asset clone, RefreshInventoryState(), OnInventoryChanged, InventoryStateManager.UnregisterItem(item).&lt;/p&gt;

&lt;p&gt;Loot pickup:&lt;/p&gt;

&lt;p&gt;itemRegistry.GetCloneByID(template) + Object.Instantiate(template) → register new InventoryItem → AddItemToFirstFreeSlot(newItem, runtimeAsset).&lt;/p&gt;

&lt;p&gt;Open swap:&lt;/p&gt;

&lt;p&gt;Hydrate sealed asset reference → find exact gear slot (gear + index) → ReplaceItemInPlace(openedAsset) → ItemOpenerResolver.ApplyOpenerDamage(opener) → PlayerInventoryManager.UpdateItem(opener) → InventoryStateManager.Register/Unregister as needed.&lt;/p&gt;

&lt;p&gt;Equip:&lt;/p&gt;

&lt;p&gt;All equip calls go through PlayerEquipManager.TryEquipInventoryItemIfSlotEmpty(item). Failure shows warning and leaves tooltip open.&lt;/p&gt;

&lt;p&gt;UI safety:&lt;/p&gt;

&lt;p&gt;OpenOptionSlotUIManager shows correct target and waits for explicit click.&lt;/p&gt;

&lt;p&gt;ItemTooltipManager guards slot/asset/injectable/item presence and logs failure points.&lt;/p&gt;

&lt;p&gt;Why the final fix stopped the knife disappearing&lt;/p&gt;

&lt;p&gt;Replaced ambiguous ID-based removals with instance/slot-specific ReplaceItemInPlace; asset hydration ensures the slot contains the expected backing asset; opener damage reduces durability only and never removes the opener; this prevents accidental removal of the opener or another instance.&lt;/p&gt;

&lt;p&gt;Tooltip pipeline rescue (backup → main merge)&lt;br&gt;
Problem context&lt;/p&gt;

&lt;p&gt;Tooltip fields (descriptions, use labels, temperature, contamination) displayed in backup but not in main project.&lt;/p&gt;

&lt;p&gt;Restoring backup into main project produced compile errors because the backup InventoryItem lacked newer fields/methods current systems required.&lt;/p&gt;

&lt;p&gt;Prefab and scene bindings mismatched, causing hydration failures and CS0117/CS1061 compile errors.&lt;/p&gt;

&lt;p&gt;Root causes identified&lt;/p&gt;

&lt;p&gt;Missing InventoryItem members (UseButton1Label…UseButton5Label, TemperatureCelsius, ContaminationLevel, GetUseLabel(int)).&lt;/p&gt;

&lt;p&gt;Tooltip prefab bindings unassigned or different between projects.&lt;/p&gt;

&lt;p&gt;Some code was operating on stale prefab references instead of freshly instantiated, hydrated runtime clones.&lt;/p&gt;

&lt;p&gt;Concrete fixes applied&lt;/p&gt;

&lt;p&gt;Restored and merged missing InventoryItem fields:&lt;/p&gt;

&lt;p&gt;UseButton1Label … UseButton5Label&lt;/p&gt;

&lt;p&gt;TemperatureCelsius&lt;/p&gt;

&lt;p&gt;ContaminationLevel&lt;/p&gt;

&lt;p&gt;Added accessor GetUseLabel(int index)&lt;/p&gt;

&lt;p&gt;Ensured tooltip UI reads from hydrated InventoryItem instances (not from template assets).&lt;/p&gt;

&lt;p&gt;Added validator logs to confirm tooltip UI bindings are assigned and active at runtime.&lt;/p&gt;

&lt;p&gt;Compared backup and main project, merged required members into current InventoryItem, then updated backups with the fixed state.&lt;/p&gt;

&lt;p&gt;Why this approach worked&lt;/p&gt;

&lt;p&gt;The backup proved the core logic; missing members in the current InventoryItem made advanced systems fail. Merging required members preserved new features while restoring compatibility. Validator logs exposed null bindings so they were fixed surgically.&lt;/p&gt;

&lt;p&gt;Recommended follow-ups (TO-DO) &lt;/p&gt;

&lt;p&gt;GitHub update - Commit and tag this working state (e.g., vTooltipRelic-YYYYMMDD).&lt;/p&gt;

&lt;p&gt;Export working tooltip prefab and InventoryItem.cs as portable relics.&lt;/p&gt;

&lt;p&gt;Tests performed (representative)&lt;/p&gt;

&lt;p&gt;Discard lifecycle: discard B → loot with B picked up → created fresh instance; discarded instance never returns; save/load confirmed none-resurrection.&lt;/p&gt;

&lt;p&gt;Equip protection: attempts from loot/inventory when Hands occupied blocked and tooltip retained.&lt;/p&gt;

&lt;p&gt;Open flow: container→open and opener→open validated; no auto-selection; exact-slot replacement; opener persistence and durability decrement verified.&lt;/p&gt;

&lt;p&gt;Tooltip pipeline: restored tooltip fields displayed correctly; no compile errors after merge; prefab bindings validated at runtime.&lt;/p&gt;

&lt;p&gt;Options/Audio: Title Menu → OptionsScene via fader and blocker; in-game panel toggle now correctly , with resolved EventSystem conflicts; sliders update AudioManager live and working.&lt;/p&gt;

&lt;p&gt;UI stability: repeated interactions produced no NREs after defensive patches.&lt;/p&gt;

&lt;p&gt;Logs, probes and instrumentation added&lt;br&gt;
Ghost item detection in PlayerInventoryManager.LogGhostItems.&lt;/p&gt;

&lt;p&gt;ReplaceItemInPlace probes: log gear slot, index, expected vs actual asset reference before replacement.&lt;/p&gt;

&lt;p&gt;InventoryStateManager logs for RegisterItem, UnregisterItem, RemoveItem.&lt;/p&gt;

&lt;p&gt;ItemTooltipManager added explicit logs for missing slot/asset/injectable/item to pinpoint NRE sources.&lt;/p&gt;

&lt;p&gt;Tooltip Validator helper logs extended to confirm live bindings are assigned and active.&lt;/p&gt;

&lt;p&gt;Implementation notes &amp;amp; caveats&lt;br&gt;
Only destroy runtime clones; do not destroy template ScriptableObjects from ItemRegistry — mark runtime clones at creation or track them.&lt;/p&gt;

&lt;p&gt;InventoryStateManager is keyed by ItemID for compatibility; UnregisterItem removes by reference first then by ID fallback.&lt;/p&gt;

&lt;p&gt;Ensure persistence respects unique instance identification if you want save-level exclusion of removed instances.&lt;/p&gt;

&lt;p&gt;Audit other systems for use of InventoryStateManager.GetLiveItem for construction — they must instead use ItemFactory/Create or Instantiate templates.&lt;/p&gt;

&lt;p&gt;updated code ( personal reference )&lt;/p&gt;

&lt;p&gt;Itemtooltipmanager&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Game.Inventory;
using Game.Items;
using Game.Player;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using static UnityEditor.Progress;

public class ItemTooltipManager : MonoBehaviour
{
    public static ItemTooltipManager Instance { get; private set; }

    [Header("UI References")]
    public GameObject panel;
    public TextMeshProUGUI ItemDisplayNameText;
    public TextMeshProUGUI ItemDescriptionText;
    public TextMeshProUGUI ItemLoreTagText;
    public TextMeshProUGUI ItemWeightLabelText;
    public TextMeshProUGUI ItemWeightValueText;
    public TextMeshProUGUI ItemConditionLabelText;
    public TextMeshProUGUI ItemDurabilityValueText;
    public TextMeshProUGUI ItemUsesText;
    public TextMeshProUGUI ItemRarityText;
    public TextMeshProUGUI ItemLiquidVolumeText;
    public TextMeshProUGUI ItemGasVolumeText;

    [Header("Overlay")]
    public Image overlayImage;

    [Header("Inventory Buttons")]
    public Button Button1;
    public Button Button2;
    public Button Button3;
    public Button Button4;
    public Button Button5;

    public TextMeshProUGUI Button1Label;
    public TextMeshProUGUI Button2Label;
    public TextMeshProUGUI Button3Label;
    public TextMeshProUGUI Button4Label;
    public TextMeshProUGUI Button5Label;

    [Header("Use Panel Button Icons")]
    public Image Button1Icon;
    public Image Button2Icon;
    public Image Button3Icon;
    public Image Button4Icon;
    public Image Button5Icon;

    [Header("Panel References")]
    [SerializeField] private UsePanelManager usePanelManager;

    [Header("Liquid Info Panel")]
    public GameObject LiquidInfoPanel;
    public TextMeshProUGUI LiquidTypeText;
    public TextMeshProUGUI ContaminationValueText;
    public TextMeshProUGUI TemperatureValueText;

    private InventoryItem currentItem;
    private InventorySlotUI activeSlot;

    private Dictionary&amp;lt;int, Button&amp;gt; buttonMap;
    private Dictionary&amp;lt;int, TextMeshProUGUI&amp;gt; labelMap;
    private Dictionary&amp;lt;int, Image&amp;gt; iconMap;

    private void Awake()
    {
        Instance = this;

        buttonMap = new()
        {
            { 1, Button1 },
            { 2, Button2 },
            { 3, Button3 },
            { 4, Button4 },
            { 5, Button5 }
        };

        labelMap = new()
        {
            { 1, Button1Label },
            { 2, Button2Label },
            { 3, Button3Label },
            { 4, Button4Label },
            { 5, Button5Label }
        };

        iconMap = new()
        {
            { 1, Button1Icon },
            { 2, Button2Icon },
            { 3, Button3Icon },
            { 4, Button4Icon },
            { 5, Button5Icon }
        };

        Button1.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(1));
        Button2.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(2));
        Button3.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(3));
        Button4.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(4));
        Button5.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(5));

        SetTextVisibility(false);
        foreach (var kvp in buttonMap)
        {
            kvp.Value.gameObject.SetActive(false);
            labelMap[kvp.Key].text = "";
            iconMap[kvp.Key].enabled = false;
        }

        LiquidInfoPanel?.SetActive(false);
        ItemLiquidVolumeText?.gameObject.SetActive(false);
        ItemGasVolumeText?.gameObject.SetActive(false);
    }

    public void ShowTooltip(InventoryItem item, InventorySlotUI slot = null)
    {
        if (panel == null || item == null || !item.IsValid())
        {
            HideTooltip();
            return;
        }

        var liveItem = InventoryStateManager.Instance?.GetLiveItem(item.ItemID);
        if (liveItem != null)
        {
            item = liveItem;
            Debug.Log($"[Worm] 🧬 Live item rebound for tooltip: {item.ItemID}");
        }

        currentItem = item;
        activeSlot = slot;

        panel.SetActive(true);
        panel.transform.SetAsLastSibling();
        overlayImage?.gameObject.SetActive(false);

        SetTextVisibility(true);
        ItemDisplayNameText.text = !string.IsNullOrEmpty(item.DisplayName)
            ? item.DisplayName
            : "[Unnamed Item]";

        ItemDescriptionText.text = item.GetDescription();
        ItemLoreTagText.text = item.GetLoreTag();

        ItemWeightLabelText.text = "Weight";
        ItemWeightLabelText.color = ItemConditionResolver.GetWeightColor(item.GetWeight());
        ItemWeightValueText.text = $"{item.GetWeight():0.00} kg";
        ItemWeightValueText.color = ItemConditionResolver.GetWeightColor(item.GetWeight());

        UpdateUses(item);
        InjectInventoryButtons(item);

        bool hasLiquid = item.CurrentVolumeML &amp;gt; 0 || item.MaxVolumeML &amp;gt; 0;
        bool hasGas = item.CurrentGasVolumeML &amp;gt; 0 || item.MaxGasVolumeML &amp;gt; 0;

        if (hasLiquid)
        {
            ItemLiquidVolumeText.text = $"Volume {item.CurrentVolumeML}/{item.MaxVolumeML}ml";
            ItemLiquidVolumeText.gameObject.SetActive(true);

            if (item.CurrentVolumeML &amp;gt; 0)
            {
                LiquidInfoPanel?.SetActive(true);
                LiquidTypeText.text = item.CurrentLiquidType ?? "";
                ContaminationValueText.text = item.ContaminationTag ?? "";
                TemperatureValueText.text = item.LiquidTemperatureCelsius &amp;gt; 0
                    ? $"{item.LiquidTemperatureCelsius:0.#}°C"
                    : "";
            }
            else
            {
                LiquidInfoPanel?.SetActive(false);
            }
        }
        else
        {
            ItemLiquidVolumeText.text = "";
            ItemLiquidVolumeText.gameObject.SetActive(false);
            LiquidInfoPanel?.SetActive(false);
        }

        if (hasGas)
        {
            ItemGasVolumeText.text = $"Volume {item.CurrentGasVolumeML}/{item.MaxGasVolumeML}ml";
            ItemGasVolumeText.gameObject.SetActive(true);
        }
        else
        {
            ItemGasVolumeText.text = "";
            ItemGasVolumeText.gameObject.SetActive(false);
        }

        Debug.Log($"[Worm] 🧪 Tooltip data: Liquid={item.CurrentVolumeML}/{item.MaxVolumeML}, Gas={item.CurrentGasVolumeML}/{item.MaxGasVolumeML}");
    }

    public void RebindTooltip(InventoryItem item, InventorySlotUI slot)
    {
        if (item == null || slot == null || string.IsNullOrEmpty(item.ItemID))
        {
            Debug.LogWarning("[Worm] ❌ RebindTooltip failed.");
            return;
        }

        currentItem = item;
        activeSlot = slot;
        ShowTooltip(item, slot);
        Debug.Log($"[Worm] 🔁 Tooltip rebound for item: {item.ItemID}, slot: {slot.name}");
    }
    private void ExecuteInventoryAction(int slot)
    {
        if (currentItem == null)
        {
            Debug.LogWarning("[Tenchu] currentItem is null.");
            return;
        }

        string action = currentItem.GetButtonLabel(slot, "inventory");
        if (string.IsNullOrEmpty(action))
        {
            Debug.LogWarning("[Tenchu] Action label is empty.");
            return;
        }

        Debug.Log($"[Tenchu] Slot {slot} triggered action: {action}");

        switch (action.ToLowerInvariant())
        {
            case "attach":
                UniversalAttachmentManager.Instance?.TryAttach(currentItem.assetReference);
                HideTooltip();
                break;

            case "discard":
                if (currentItem == null)
                {
                    Debug.LogWarning("[Tenchu] ❌ Discard failed: currentItem is null.");
                    return;
                }

                bool removed = false;

                // Prefer removal by live instance if possible
                if (PlayerInventoryManager.Instance != null)
                {
                    removed = PlayerInventoryManager.Instance.RemoveItem(currentItem);
                    if (!removed)
                        removed = PlayerInventoryManager.Instance.RemoveItem(currentItem.ItemID);
                }
                else
                {
                    Debug.LogWarning("[Tenchu] ❌ Discard failed: PlayerInventoryManager.Instance is null.");
                }

                // Ensure global registry no longer references the instance
                if (InventoryStateManager.Instance != null)
                {
                    InventoryStateManager.Instance.UnregisterItem(currentItem);
                }
                else
                {
                    Debug.LogWarning("[Tenchu] ⚠️ InventoryStateManager.Instance is null; cannot unregister item.");
                }

                if (removed)
                {
                    if (activeSlot != null)
                    {
                        activeSlot.ClearSlot();
                        Debug.Log($"[Tenchu] 🧼 Cleared slot: {activeSlot.name}");
                    }

                    HideTooltip();
                    Debug.Log($"[Tenchu] 🗑️ Discarded item: {currentItem.ItemID}");
                }
                else
                {
                    Debug.LogWarning($"[Tenchu] ⚠️ Failed to remove item '{currentItem.ItemID}' from PlayerInventoryManager.");
                    // Still hide tooltip and attempt UI clear to avoid stale UI state
                    if (activeSlot != null)
                    {
                        activeSlot.ClearSlot();
                        Debug.Log($"[Tenchu] 🧼 Cleared slot (fallback): {activeSlot.name}");
                    }
                    HideTooltip();
                }
                break;

            case "equip":
                bool equipped = PlayerEquipManager.Instance?.TryEquipInventoryItemIfSlotEmpty(currentItem) ?? false;
                if (!equipped)
                {
                    Debug.LogWarning($"[Tooltip] 🚫 Equip blocked for '{currentItem.ItemID}' — slot may be occupied.");
                    PlayerEquipManager.Instance?.ShowEquipWarning("Hands slot is occupied. Unequip first.");
                }
                HideTooltip();
                break;

            case "use":
            case "fill":
            case "empty":
            case "combine":
            case "place":
            case "pour":
            case "eat":
            case "drink":
                usePanelManager?.OpenPanel(currentItem, activeSlot);
                break;

            case "open":
                Debug.Log($"[Tenchu] 🧿 Opening ritual triggered for '{currentItem.ItemID}'");
                OpenPanelManager.Instance?.ShowOpenersFor(currentItem);
                break;

            default:
                Debug.LogWarning($"[Tenchu] Unhandled action: {action}");
                break;
        }
    }

    private void InjectInventoryButtons(InventoryItem item)
    {
        foreach (var kvp in buttonMap)
        {
            kvp.Value.gameObject.SetActive(false);
            labelMap[kvp.Key].text = "";
            iconMap[kvp.Key].enabled = false;
        }

        SetButton(1, item.InventoryButton1Label);
        SetButton(2, item.InventoryButton2Label);
        SetButton(3, item.InventoryButton3Label);
        SetButton(4, item.InventoryButton4Label);
        SetButton(5, item.InventoryButton5Label);
    }

    private void SetButton(int slot, string labelText)
    {
        bool hasLabel = !string.IsNullOrEmpty(labelText);
        buttonMap[slot].gameObject.SetActive(hasLabel);
        labelMap[slot].text = hasLabel ? labelText : "";

        if (iconMap.TryGetValue(slot, out var icon))
        {
            var sprite = UsePanelIconRegistry.GetIcon(labelText);
            icon.sprite = sprite;
            icon.enabled = sprite != null;
        }
    }

    public void UpdateUses(InventoryItem item)
    {
        string conditionLabel = item.GetConditionLabel();
        Color conditionColor = ItemConditionResolver.GetConditionColorByDurability(item.Durability);

        ItemConditionLabelText.text = $"Condition: {conditionLabel}";
        ItemConditionLabelText.color = conditionColor;

        ItemDurabilityValueText.text = $"Durability: {item.Durability}/100";
        ItemDurabilityValueText.color = conditionColor;

        if (item.ZeroUseMode == ZeroUseMode.UntilDurabilityZero)
        {
            ItemUsesText.gameObject.SetActive(false);
        }
        else if (item.RemainingUses &amp;gt; 0)
        {
            float percent = item.MaxUses &amp;gt; 0 ? (float)item.RemainingUses / item.MaxUses : 0f;
            Color useColor = ItemConditionResolver.GetUseColorByPercentage(percent);

            ItemUsesText.text = $"Uses: {item.RemainingUses}";
            ItemUsesText.color = useColor;
            ItemUsesText.gameObject.SetActive(true);
        }
        else
        {
            switch (item.ZeroUseMode)
            {
                case ZeroUseMode.Unlimited:
                    ItemUsesText.text = "Uses: Unlimited";
                    ItemUsesText.color = ItemConditionResolver.GetUseColorByPercentage(1.0f);
                    ItemUsesText.gameObject.SetActive(true);
                    break;
                case ZeroUseMode.Zero:
                    ItemUsesText.text = "Uses: 0";
                    ItemUsesText.color = ItemConditionResolver.GetUseColorByPercentage(0f);
                    ItemUsesText.gameObject.SetActive(true);
                    break;
                default:
                    ItemUsesText.gameObject.SetActive(false);
                    break;
            }
        }

        if (!string.IsNullOrEmpty(item.Rarity))
        {
            ItemRarityText.text = $"Rarity: {item.Rarity}";
            ItemRarityText.color = GetColorForRarity(item.Rarity);
        }
    }

    private Color GetColorForRarity(string rarity)
    {
        return rarity switch
        {
            "Common" =&amp;gt; Color.white,
            "Uncommon" =&amp;gt; new Color(0.3f, 1.0f, 0.3f),
            "Rare" =&amp;gt; new Color(0.3f, 0.5f, 1.0f),
            "Epic" =&amp;gt; new Color(0.6f, 0.2f, 0.8f),
            "Legendary" =&amp;gt; new Color(1.0f, 0.84f, 0.0f),
            _ =&amp;gt; Color.white
        };
    }

    public void HideTooltip()
    {
        Debug.Log($"[Worm] 🧹 Tooltip hidden. Clearing slot: {(activeSlot != null ? activeSlot.name : "null")}");
        currentItem = null;
        activeSlot = null;
        SetTextVisibility(false);

        foreach (var kvp in buttonMap)
        {
            kvp.Value.gameObject.SetActive(false);
            labelMap[kvp.Key].text = "";
            iconMap[kvp.Key].enabled = false;
        }

        ItemLiquidVolumeText.text = "";
        ItemLiquidVolumeText.gameObject.SetActive(false);

        ItemGasVolumeText.text = "";
        ItemGasVolumeText.gameObject.SetActive(false);

        LiquidInfoPanel?.SetActive(false);
        panel?.SetActive(false);
    }

    private void SetTextVisibility(bool visible)
    {
        ItemDisplayNameText.enabled = visible;
        ItemDescriptionText.enabled = visible;
        ItemLoreTagText.enabled = visible;
        ItemWeightLabelText.enabled = visible;
        ItemWeightValueText.enabled = visible;
        ItemConditionLabelText.enabled = visible;
        ItemDurabilityValueText.enabled = visible;
        ItemUsesText.enabled = visible;
        ItemRarityText.enabled = visible;
        ItemLiquidVolumeText.enabled = visible;
        ItemGasVolumeText.enabled = visible;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inventorystatemanager&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Game.Inventory;
using System.Collections.Generic;
using UnityEngine;

public class InventoryStateManager : MonoBehaviour
{
    public static InventoryStateManager Instance { get; private set; }

    // Keyed by item.ItemID for backwards compatibility, but we also support removal by reference.
    private Dictionary&amp;lt;string, InventoryItem&amp;gt; liveItems = new();

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
            Debug.Log("[Worm] 🧬 InventoryStateManager initialized.");
        }
        else
        {
            Destroy(gameObject);
        }
    }

    public void RegisterItem(InventoryItem item)
    {
        if (item == null || string.IsNullOrEmpty(item.ItemID))
        {
            Debug.LogWarning("[Worm] ❌ Attempted to register null or invalid item.");
            return;
        }

        // If there's already a registered instance for this ItemID, warn if it's a different reference.
        if (liveItems.TryGetValue(item.ItemID, out var existing))
        {
            if (!ReferenceEquals(existing, item))
            {
                Debug.LogWarning($"[Worm] ⚠️ RegisterItem: replacing existing registered instance for ID '{item.ItemID}'. Existing instance will be overwritten.");
            }
        }

        liveItems[item.ItemID] = item;
        Debug.Log($"[Worm] ✅ Registered item: {item.ItemID} | Volume={item.CurrentVolumeML} | LiquidType={item.CurrentLiquidType}");
    }

    public bool IsItemRegistered(string itemID)
    {
        return !string.IsNullOrEmpty(itemID) &amp;amp;&amp;amp; liveItems.ContainsKey(itemID);
    }

    public InventoryItem GetLiveItem(string itemID)
    {
        if (string.IsNullOrEmpty(itemID))
        {
            Debug.LogWarning("[Worm] ❌ GetLiveItem called with null or empty ID.");
            return null;
        }

        if (liveItems.TryGetValue(itemID, out var item))
        {
            Debug.Log($"[Worm] 🧪 Retrieved live item: {itemID} | Volume={item.CurrentVolumeML} | LiquidType={item.CurrentLiquidType}");
            return item;
        }

        // Silent null is fine for normal flow; keep warning for debug visibility
        Debug.LogWarning($"[Worm] ⚠️ No live item found for ID: {itemID}");
        return null;
    }

    // Restore compatibility: mark a registered item as equipped (by ID)
    public void MarkItemAsEquipped(string itemID)
    {
        if (string.IsNullOrEmpty(itemID))
        {
            Debug.LogWarning("[Worm] ❌ MarkItemAsEquipped called with null or empty ID.");
            return;
        }

        if (liveItems.TryGetValue(itemID, out var item))
        {
            item.IsEquipped = true;
            Debug.Log($"[Worm] 🧬 Item '{itemID}' marked as equipped.");
        }
        else
        {
            Debug.LogWarning($"[Worm] ❌ Item '{itemID}' not found in registry when marking equipped.");
        }
    }

    // Overload: mark as equipped by instance reference
    public void MarkItemAsEquipped(InventoryItem item)
    {
        if (item == null)
        {
            Debug.LogWarning("[Worm] ❌ MarkItemAsEquipped called with null item.");
            return;
        }

        // Prefer reference-based lookup
        if (TryGetLiveItemByReference(item, out var registered))
        {
            registered.IsEquipped = true;
            Debug.Log($"[Worm] 🧬 Item '{registered.ItemID}' marked as equipped by reference.");
            return;
        }

        // Fallback by ID
        MarkItemAsEquipped(item.ItemID);
    }

    // New: Unregister by InventoryItem instance (preferred)
    public void UnregisterItem(InventoryItem item)
    {
        if (item == null)
        {
            Debug.LogWarning("[Worm] ❌ UnregisterItem called with null.");
            return;
        }

        // Try remove by reference first
        string keyToRemove = null;
        foreach (var kvp in liveItems)
        {
            if (ReferenceEquals(kvp.Value, item))
            {
                keyToRemove = kvp.Key;
                break;
            }
        }

        if (!string.IsNullOrEmpty(keyToRemove))
        {
            liveItems.Remove(keyToRemove);
            Debug.Log($"[Worm] 🗑️ Unregistered live item by reference: {keyToRemove}");
            return;
        }

        // Fallback: remove by matching ItemID if present
        if (!string.IsNullOrEmpty(item.ItemID) &amp;amp;&amp;amp; liveItems.Remove(item.ItemID))
        {
            Debug.Log($"[Worm] 🗑️ Unregistered live item by ID fallback: {item.ItemID}");
            return;
        }

        Debug.LogWarning($"[Worm] ⚠️ UnregisterItem: item '{item.ItemID}' not found in registry.");
    }

    // Keep RemoveItem by ID for callers that only have itemID
    public void RemoveItem(string itemID)
    {
        if (string.IsNullOrEmpty(itemID))
        {
            Debug.LogWarning("[Worm] ❌ RemoveItem called with null or empty ID.");
            return;
        }

        if (liveItems.Remove(itemID))
        {
            Debug.Log($"[Worm] 🗑️ Removed item: {itemID} from live registry.");
        }
        else
        {
            Debug.LogWarning($"[Worm] ⚠️ Item '{itemID}' not found in live registry.");
        }
    }

    public Dictionary&amp;lt;string, InventoryItem&amp;gt; GetAllLiveItems()
    {
        return liveItems;
    }

    public void ClearAll()
    {
        liveItems.Clear();
        Debug.Log("[Worm] 🧹 InventoryStateManager cleared all live items.");
    }

    // Helper: attempt to find a live item by exact instance reference
    public bool TryGetLiveItemByReference(InventoryItem instance, out InventoryItem found)
    {
        found = null;
        if (instance == null) return false;
        foreach (var kvp in liveItems)
        {
            if (ReferenceEquals(kvp.Value, instance))
            {
                found = kvp.Value;
                return true;
            }
        }
        return false;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usepanelmanager&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Game.Inventory;
using Game.Player;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Game.UI;

public class UsePanelManager : MonoBehaviour
{
    public static UsePanelManager Instance { get; private set; }

    public bool IsOpen =&amp;gt; panelRoot != null &amp;amp;&amp;amp; panelRoot.activeInHierarchy;

    [Header("Panel Root")]
    [SerializeField] private GameObject panelRoot;

    [Header("UI References")]
    [SerializeField] private TMP_Text TitleText;
    [SerializeField] private Image BlackoutImage;
    [SerializeField] private Image ItemIcon;
    [SerializeField] private TMP_Text ItemName;

    [Header("Buttons")]
    [SerializeField] private Button Button2;
    [SerializeField] private Button Button3;
    [SerializeField] private Button Button4;
    [SerializeField] private Button Button5;
    [SerializeField] private Button Button6;

    [Header("Labels")]
    [SerializeField] private TMP_Text Button2Label;
    [SerializeField] private TMP_Text Button3Label;
    [SerializeField] private TMP_Text Button4Label;
    [SerializeField] private TMP_Text Button5Label;
    [SerializeField] private TMP_Text Button6Label;

    [Header("Icons")]
    [SerializeField] private Image Button2Icon;
    [SerializeField] private Image Button3Icon;
    [SerializeField] private Image Button4Icon;
    [SerializeField] private Image Button5Icon;
    [SerializeField] private Image Button6Icon;

    [Header("Use Sprite Registry")]
    [SerializeField] private UseSpriteRegistry useSpriteRegistry;

    [Header("Attachment Panel")]
    [SerializeField] private UniversalAttachmentPanel attachmentPanel;

    [Header("Story Node")]
    [SerializeField] private StoryNodeLoader storyNodeLoader;

    [Header("Close Button")]
    [SerializeField] private Button closeButton;

    private List&amp;lt;Button&amp;gt; buttons;
    private List&amp;lt;TMP_Text&amp;gt; labels;
    private List&amp;lt;Image&amp;gt; icons;

    private InventorySlotUI currentSlot;

    private void Awake()
    {
        Instance = this;
        buttons = new List&amp;lt;Button&amp;gt; { Button2, Button3, Button4, Button5, Button6 };
        labels = new List&amp;lt;TMP_Text&amp;gt; { Button2Label, Button3Label, Button4Label, Button5Label, Button6Label };
        icons = new List&amp;lt;Image&amp;gt; { Button2Icon, Button3Icon, Button4Icon, Button5Icon, Button6Icon };

        if (BlackoutImage != null)
            BlackoutImage.gameObject.SetActive(false);
    }

    public void OpenPanel(InventoryItem item, InventorySlotUI slot)
    {
        if (slot == null || item == null) return;

        if (panelRoot.activeInHierarchy)
        {
            HidePanel();
        }

        currentSlot = slot;

        panelRoot.SetActive(true);
        panelRoot.transform.localScale = Vector3.one;
        panelRoot.transform.SetAsLastSibling();

        var cg = panelRoot.GetComponent&amp;lt;CanvasGroup&amp;gt;();
        if (cg != null)
        {
            cg.alpha = 1f;
            cg.interactable = true;
            cg.blocksRaycasts = true;
        }

        HideAllButtons();
        UpdateItemDisplay(item);

        if (TitleText != null)
            TitleText.text = "Item Use Menu";

        if (BlackoutImage != null)
            BlackoutImage.gameObject.SetActive(true);

        // ✅ Only show contextual use actions (not Attach/Equip)
        for (int i = 1; i &amp;lt;= 5; i++)
        {
            string label = item.GetUseLabel(i);
            if (!string.IsNullOrEmpty(label) &amp;amp;&amp;amp; i - 1 &amp;lt; buttons.Count)
            {
                if (label.Equals("Attach", System.StringComparison.OrdinalIgnoreCase) ||
                    label.Equals("Equip", System.StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                Sprite icon = GetIconForLabel(label);

                UnityEngine.Events.UnityAction action = () =&amp;gt;
                {
                    Debug.Log($"[UsePanelManager] Action triggered: {label} for item {item.ItemID}");

                    switch (label.ToLowerInvariant())
                    {
                        case "open":
                            if (ItemOpenerResolver.IsOpenerTool(item))
                            {
                                // Tool path → show containers, then close
                                OpenPanelManager.Instance?.ShowOpenersFor(item);
                                HidePanel();
                            }
                            else
                            {
                                // Container path → show tools, keep panel open
                                OpenPanelManager.Instance?.ShowOpenersFor(item);
                            }
                            break;

                        case "slice":
                            Debug.Log($"[UsePanelManager] Slice action placeholder for {item.ItemID}");
                            HidePanel();
                            break;

                        case "repair":
                            Debug.Log($"[UsePanelManager] Repair action placeholder for {item.ItemID}");
                            HidePanel();
                            break;

                        case "fill":
                        case "empty":
                        case "combine":
                        case "place":
                        case "pour":
                        case "eat":
                        case "drink":
                            InventoryStateManager.Instance?.RegisterItem(item);
                            HidePanel();
                            break;

                        default:
                            Debug.LogWarning($"[UsePanelManager] Unhandled action: {label}");
                            HidePanel();
                            break;
                    }
                };

                ShowButton(i - 1, label, icon, action);
            }
        }
    }

    private void HideAllButtons()
    {
        foreach (var btn in buttons)
        {
            if (btn != null)
            {
                btn.gameObject.SetActive(false);
                btn.onClick.RemoveAllListeners();
            }
        }

        foreach (var icon in icons)
        {
            if (icon != null)
            {
                icon.sprite = null;
                icon.gameObject.SetActive(false);
            }
        }
    }

    private void UpdateItemDisplay(InventoryItem item)
    {
        if (ItemIcon != null)
            ItemIcon.sprite = item?.Icon;

        if (ItemName != null)
            ItemName.text = item?.DisplayName ?? "Unknown Item";
    }

    private void ShowButton(int index, string label, Sprite icon, UnityEngine.Events.UnityAction action)
    {
        if (index &amp;lt; 0 || index &amp;gt;= buttons.Count) return;

        var btn = buttons[index];
        var lbl = labels[index];
        var icn = icons[index];

        if (btn != null)
        {
            btn.gameObject.SetActive(true);
            btn.onClick.RemoveAllListeners();
            btn.onClick.AddListener(action);
        }

        if (lbl != null)
            lbl.text = label;

        if (icn != null)
        {
            icn.sprite = icon;
            icn.enabled = icon != null;
            icn.gameObject.SetActive(icon != null);
        }
    }

    private Sprite GetIconForLabel(string label)
    {
        if (useSpriteRegistry == null || string.IsNullOrEmpty(label)) return null;
        return useSpriteRegistry.GetSprite(label);
    }

    public void HidePanel()
    {
        if (panelRoot != null)
        {
            panelRoot.SetActive(false);

            var cg = panelRoot.GetComponent&amp;lt;CanvasGroup&amp;gt;();
            if (cg != null)
            {
                cg.blocksRaycasts = false;
                cg.interactable = false;
            }
        }

        if (BlackoutImage != null)
            BlackoutImage.gameObject.SetActive(false);

        currentSlot = null;

        ItemTooltipManager.Instance?.HideTooltip();
    }

    public void ManualClosePanel()
    {
        Debug.Log("[UsePanelManager] 🧹 ManualClosePanel triggered via inspector button");
        HidePanel();
    }

    public void ForceClosePanel()
    {
        Debug.Log("[UsePanelManager] 🧹 ForceClosePanel invoked — forcibly collapsing panel");

        try
        {
            if (panelRoot != null)
            {
                panelRoot.SetActive(false);

                var cg = panelRoot.GetComponent&amp;lt;CanvasGroup&amp;gt;();
                if (cg != null)
                {
                    cg.alpha = 0f;
                    cg.interactable = false;
                    cg.blocksRaycasts = false;
                }
            }

            if (BlackoutImage != null)
                BlackoutImage.gameObject.SetActive(false);

            currentSlot = null;

            ItemTooltipManager.Instance?.HideTooltip();

            Debug.Log("[UsePanelManager] ✅ Panel forcibly closed and state reset");
        }
        catch (System.Exception ex)
        {
            Debug.LogError($"[UsePanelManager] ❌ ForceClosePanel failed: {ex.Message}");
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>devjournal</category>
      <category>beginners</category>
      <category>unity3d</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Dev Log 36 - Mythic Pause</title>
      <dc:creator>John</dc:creator>
      <pubDate>Sat, 08 Nov 2025 16:28:46 +0000</pubDate>
      <link>https://dev.to/asx/dev-log-36-mythic-pause-4apk</link>
      <guid>https://dev.to/asx/dev-log-36-mythic-pause-4apk</guid>
      <description>&lt;p&gt;🧊 🌋 ❄️ ✈️ ⚔️ 9-Day Break: The Mythic Pause&lt;/p&gt;

&lt;p&gt;A personal reflection and journal log&lt;/p&gt;

&lt;p&gt;🌍 Icelandic Interlude: The First Real Break&lt;br&gt;
I travelled to the beautiful country of Iceland — a land of glaciers, volcanoes, and mythic quiet. It felt like stepping into another world. My first real vacation, and it was everything I hoped for:&lt;/p&gt;

&lt;p&gt;A slower, more intentional pace of life&lt;/p&gt;

&lt;p&gt;Surprisingly delicious food (despite the warnings)&lt;/p&gt;

&lt;p&gt;Friendly locals and a calm atmosphere, even with tourists&lt;/p&gt;

&lt;p&gt;Expensive, yes — but worth every krona&lt;/p&gt;

&lt;p&gt;After seven days of awe, I returned home and took two days to re-sync with reality. Then I reopened my survival engine project — and it felt like deciphering someone else’s code.&lt;/p&gt;

&lt;p&gt;🧭 Reentry Ritual: Reforging Flow&lt;br&gt;
I eased back in slowly, rekindling my dev rituals:&lt;/p&gt;

&lt;p&gt;Reviewed commits and journal entries&lt;/p&gt;

&lt;p&gt;Revisited ItemTooltipManager.cs and InventoryStateManager.cs&lt;/p&gt;

&lt;p&gt;Verified tooltip accuracy and runtime truth&lt;/p&gt;

&lt;p&gt;Rebound live item data and refreshed UI bindings&lt;/p&gt;

&lt;p&gt;Reconnected with my discard ritual sabotage&lt;/p&gt;

&lt;p&gt;🧨 Sabotage Discovered: False Discard Ritual&lt;br&gt;
❌ Issue&lt;br&gt;
Pressing the discard button triggered the use panel instead of purging the item.&lt;/p&gt;

&lt;p&gt;Symptoms:&lt;/p&gt;

&lt;p&gt;Use panel opened on discard&lt;/p&gt;

&lt;p&gt;Item visually disappeared but wasn’t truly deleted&lt;/p&gt;

&lt;p&gt;Discarded items reappeared after looting&lt;/p&gt;

&lt;p&gt;🔧 Fixes Applied: The True Purge Path&lt;br&gt;
Separated discard logic in ExecuteInventoryAction()&lt;/p&gt;

&lt;p&gt;Removed "discard" from use panel logic&lt;/p&gt;

&lt;p&gt;Added null guards and slot cleanup&lt;/p&gt;

&lt;p&gt;Forged RemoveItem() in InventoryStateManager&lt;/p&gt;

&lt;p&gt;Added RemoveItemByID() in PlayerInventoryManager&lt;/p&gt;

&lt;p&gt;Called activeSlot.ClearSlot() to purge lingering UI&lt;/p&gt;

&lt;p&gt;Verified resurrection trap → loot panel was rehydrating from ContainedAssets&lt;/p&gt;

&lt;p&gt;Purged item from all sources&lt;/p&gt;

&lt;p&gt;✅ Outcome: Ritual Sealed&lt;br&gt;
Discard now fully deletes item across all systems&lt;/p&gt;

&lt;p&gt;No false panel summons&lt;/p&gt;

&lt;p&gt;No ghost sprites&lt;/p&gt;

&lt;p&gt;No resurrection on loot&lt;/p&gt;

&lt;p&gt;Console logs confirm true purge&lt;/p&gt;

&lt;p&gt;🧪 Debug Tags&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Tenchu] 🗑️ Discarded item: {itemID}  
[Unicorn] 🧹 Removed item '{itemID}' from gear slot  
[Worm] 🧬 Removed item: {itemID} from live registry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧤 Equip Ritual Reforged: The Hands Transfer Purge&lt;br&gt;
❌ Issue&lt;br&gt;
Equipped items were appearing in both the hands slot and the inventory — violating runtime truth.&lt;/p&gt;

&lt;p&gt;Symptoms:&lt;/p&gt;

&lt;p&gt;Item appeared in hands and inventory simultaneously&lt;/p&gt;

&lt;p&gt;Unequipping duplicated the item&lt;/p&gt;

&lt;p&gt;InventoryStateManager and gear slots retained stale references&lt;/p&gt;

&lt;p&gt;🔧 Fixes Applied: The True Equip Path&lt;br&gt;
Purged from InventoryStateManager → RemoveItem(itemID)&lt;/p&gt;

&lt;p&gt;Purged from PlayerInventoryManager → RemoveItem(itemID)&lt;/p&gt;

&lt;p&gt;Cleared from UI slot → slot.GetItem()?.ItemID == item.ItemID → slot.ClearSlot()&lt;/p&gt;

&lt;p&gt;Injected into hands slot → GearSlotUI.RefreshSlotWithInventoryItem(item)&lt;/p&gt;

&lt;p&gt;Verified equip flow in EquipInventoryItem() → All purges occur before injection&lt;/p&gt;

&lt;p&gt;✅ Outcome: Ritual Sealed&lt;br&gt;
Item now transfers cleanly from inventory to hands&lt;/p&gt;

&lt;p&gt;No duplication on unequip&lt;/p&gt;

&lt;p&gt;No ghost sprites or registry remnants&lt;/p&gt;

&lt;p&gt;Console confirms full purge and equip&lt;/p&gt;

&lt;p&gt;🧪 Debug Tags&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[EquipManager] 🧼 Removed '{itemID}' from InventoryStateManager  
[EquipManager] 🧼 Removed '{itemID}' from PlayerInventoryManager  
[EquipManager] 🧹 Cleared inventory UI slot for '{itemID}'  
[EquipManager] 🧤 InventoryItem equipped to slot 'Hands' → {itemID}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📜 Relic Logged: The Hands Transfer Purge Ritual&lt;br&gt;
Restores runtime truth by ensuring equipped items are fully purged from inventory systems before injection into hands.&lt;/p&gt;

&lt;p&gt;🧠 Dev Mindset: From Fog to Flow&lt;br&gt;
The first few hours felt like wandering through someone else's shrine. My keyboard was unfamiliar, my systems distant. But each debug tag was a breadcrumb. By the time I traced the discard sabotage, I was fully reawakened. The rituals returned. The myth resumed.&lt;/p&gt;

&lt;p&gt;🧪 Test Rituals&lt;br&gt;
Equipped item from slot 3 → verified removal from UI and registry&lt;/p&gt;

&lt;p&gt;Unequipped item → confirmed reappearance in first free slot&lt;/p&gt;

&lt;p&gt;Discarded item → confirmed no resurrection on loot&lt;/p&gt;

&lt;p&gt;Attempted equip with no free slot → verified graceful failure&lt;/p&gt;

&lt;p&gt;Rebound tooltip after contamination → confirmed live data accuracy&lt;/p&gt;

&lt;p&gt;🧰 Ritual Hooks&lt;br&gt;
ExecuteInventoryAction() → Entry point for discard and equip logic&lt;/p&gt;

&lt;p&gt;RemoveItem() → Purges item from registry and gear slots&lt;/p&gt;

&lt;p&gt;ClearSlot() → Wipes UI remnants&lt;/p&gt;

&lt;p&gt;EquipInventoryItem() → Seals the hands transfer ritual&lt;/p&gt;

&lt;p&gt;RefreshSlotWithInventoryItem() → Injects item into hands slot&lt;/p&gt;

&lt;p&gt;📈 Impact&lt;br&gt;
Enables true equip/unequip cycles&lt;/p&gt;

&lt;p&gt;Prevents inventory overflow and ghost duplication&lt;/p&gt;

&lt;p&gt;Strengthens tooltip accuracy and runtime clarity&lt;/p&gt;

&lt;p&gt;Paves the way for equip swap fallback and slot registry automation&lt;/p&gt;

&lt;p&gt;🧩 Open Threads&lt;br&gt;
Tooltip overlay cleanup on unequip&lt;/p&gt;

&lt;p&gt;Equip swap fallback logic&lt;/p&gt;

&lt;p&gt;Slot registry automation&lt;/p&gt;

&lt;p&gt;Ghost item detection on scene reload&lt;/p&gt;

&lt;p&gt;🔮 Reflection &amp;amp; Reconnection&lt;br&gt;
This return wasn’t just technical — it was emotional. I reconnected with my systems, my rituals, and my mythic mindset. I remembered why I build: to immortalize clarity, to ritualize resilience, and to seal every fix as a legacy relic.&lt;/p&gt;

&lt;p&gt;🧩 Next Steps: The HUD Binding Ritual&lt;br&gt;
Continue wiring function logic to HUD and inventory buttons&lt;/p&gt;

&lt;p&gt;Polish tooltip overlays and contamination indicators&lt;/p&gt;

&lt;p&gt;Expand systems: battle logic, equip swap fallback, slot registry automation&lt;/p&gt;

&lt;p&gt;Revisit vector purification and overlay controller cleanup&lt;/p&gt;

&lt;p&gt;Slowly but surely the progress will continue.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>beginners</category>
      <category>unity3d</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Dev Log 35 - Equip Hands Tooltips</title>
      <dc:creator>John</dc:creator>
      <pubDate>Wed, 22 Oct 2025 21:39:10 +0000</pubDate>
      <link>https://dev.to/asx/dev-log-35-equip-hands-tooltips-2k51</link>
      <guid>https://dev.to/asx/dev-log-35-equip-hands-tooltips-2k51</guid>
      <description>&lt;p&gt;🧙‍♂️ Survival Engine Debug Log: Hands Slot Resurrection &amp;amp; Tooltip Bifurcation Ritual&lt;/p&gt;

&lt;p&gt;🔍 Initial Problem: The Ghost of Hands Slot&lt;/p&gt;

&lt;p&gt;The Hands slot was a phantom. No sprite. No tooltip. No runtime truth. Clicking it felt like whispering into the void. Hovering? Nothing.&lt;/p&gt;

&lt;p&gt;Meanwhile, gear slots were living their best lives — fully wired, fully responsive. Hands was the neglected middle child of the UI hierarchy.&lt;/p&gt;

&lt;p&gt;🧪 Phase 1: Interface Alignment &amp;amp; Shrine Purification&lt;br&gt;
✅ Verified:&lt;/p&gt;

&lt;p&gt;GearSlotUI.cs was referencing ghost fields like GetRarity() and GetArmourValue() — banished.&lt;/p&gt;

&lt;p&gt;IInjectableItem was shrine-pure, defining all necessary methods for runtime injection.&lt;/p&gt;

&lt;p&gt;🔧 Actions:&lt;/p&gt;

&lt;p&gt;Refactored GearSlotUI.cs to use only valid IInjectableItem methods: GetItemID(), GetDisplayName(), GetDescription(), GetLoreTag(), GetWeight(), GetConditionState(), GetItem()&lt;/p&gt;

&lt;p&gt;📚 Lesson Learned: Don’t trust legacy fields. They lie. Interfaces are truth.&lt;/p&gt;

&lt;p&gt;🧱 Phase 2: Hands Slot Injection Ritual&lt;br&gt;
✅ Implemented:&lt;/p&gt;

&lt;p&gt;AssignItemFromInteraction() now detects IInjectableItem and injects into Hands slot&lt;/p&gt;

&lt;p&gt;RefreshSlotWithInventoryItem() wires up overlay sprite&lt;/p&gt;

&lt;p&gt;ShowTooltip() pulls live data via InventoryManager.Instance.itemRegistry.GetByID(item.ItemID)&lt;/p&gt;

&lt;p&gt;🧪 Result:&lt;/p&gt;

&lt;p&gt;Sprite now appears in Hands slot&lt;/p&gt;

&lt;p&gt;Tooltip sometimes works, but responsiveness was flaky — like a cursed relic half-awake&lt;/p&gt;

&lt;p&gt;🧼 Phase 3: Tooltip Locking &amp;amp; Responsiveness Fix&lt;/p&gt;

&lt;p&gt;🔍 Problem: Clicking gear slots sometimes failed to show tooltip. Tooltip locking logic was interfering with slot switching.&lt;/p&gt;

&lt;p&gt;✅ Fix:&lt;/p&gt;

&lt;p&gt;Patched OnPointerClick() to:&lt;/p&gt;

&lt;p&gt;Unlock and hide previous slot’s tooltip&lt;/p&gt;

&lt;p&gt;Lock and show current slot’s tooltip&lt;/p&gt;

&lt;p&gt;Reset currentSelectedSlot properly&lt;/p&gt;

&lt;p&gt;📚 Lesson Learned: Tooltips are like jealous spirits. You must banish the old one before summoning the new.&lt;/p&gt;

&lt;p&gt;🧪 Phase 4: Runtime Validation Ritual&lt;br&gt;
✅ Created:&lt;/p&gt;

&lt;p&gt;RuntimeValidator.cs to scan:&lt;/p&gt;

&lt;p&gt;GearSlotUI prefab bindings&lt;/p&gt;

&lt;p&gt;Tooltip fields&lt;/p&gt;

&lt;p&gt;ItemEntry prefab components&lt;/p&gt;

&lt;p&gt;🧼 Fixes:&lt;/p&gt;

&lt;p&gt;Removed invalid rarityText reference&lt;/p&gt;

&lt;p&gt;Added individual checks for all tooltip fields&lt;/p&gt;

&lt;p&gt;Confirmed prefab bindings were shrine-pure&lt;/p&gt;

&lt;p&gt;📚 Lesson Learned: Prefab validation is not optional. It’s the holy water that keeps runtime demons away.&lt;/p&gt;

&lt;p&gt;🧠 Phase 5: Registry Access Restoration&lt;br&gt;
🔍 Problem: InventoryManager.itemRegistry was private, causing access errors&lt;/p&gt;

&lt;p&gt;✅ Fix:&lt;/p&gt;

&lt;p&gt;Made itemRegistry public&lt;/p&gt;

&lt;p&gt;Alternatively offered a getter method GetItemRegistry()&lt;/p&gt;

&lt;p&gt;📚 Lesson Learned: If you can’t access the registry, you are not a priest. You are a peasant.&lt;/p&gt;

&lt;p&gt;🧰 Phase 6: Tooltip Panel Bifurcation&lt;br&gt;
✅ Implemented:&lt;/p&gt;

&lt;p&gt;Split tooltip system into 3 prefab-safe panels:&lt;/p&gt;

&lt;p&gt;🛡️ Gear Tooltip Panel&lt;/p&gt;

&lt;p&gt;🧰 Inventory Tooltip Panel&lt;/p&gt;

&lt;p&gt;🎯 Ranged Tooltip Panel&lt;/p&gt;

&lt;p&gt;✅ Refactored GearSlotUI.cs to:&lt;/p&gt;

&lt;p&gt;Route tooltips based on item type&lt;/p&gt;

&lt;p&gt;Use safe casting (item.itemAsset as MeleeWeaponItem)&lt;/p&gt;

&lt;p&gt;Inject prefab-safe data into each panel&lt;/p&gt;

&lt;p&gt;🧼 Fixes:&lt;/p&gt;

&lt;p&gt;Removed legacy references to tooltipPanel, displayNameText, etc.&lt;/p&gt;

&lt;p&gt;Updated RuntimeValidator.cs to validate new fields&lt;/p&gt;

&lt;p&gt;📚 Lesson Learned: One tooltip to rule them all? Nope. Three tooltips to bifurcate runtime truth.&lt;/p&gt;

&lt;p&gt;🗡️ Phase 7: Melee Diagnostics Injection&lt;br&gt;
✅ Extended Inventory Tooltip Panel to support:&lt;/p&gt;

&lt;p&gt;Base Damage, Melee Type, Armor Pierce, Crit Chance, Bleed Chance, Stun Chance&lt;/p&gt;

&lt;p&gt;Rarity, Condition, Weight, Lore, Description&lt;/p&gt;

&lt;p&gt;✅ Logic:&lt;/p&gt;

&lt;p&gt;Melee fields are shown only for MeleeWeaponItem&lt;/p&gt;

&lt;p&gt;Hidden ("—") for non-melee items&lt;/p&gt;

&lt;p&gt;✅ Inspector Wiring:&lt;/p&gt;

&lt;p&gt;All fields injected into GearSlotUI.cs&lt;/p&gt;

&lt;p&gt;Prefab bindings confirmed shrine-pure&lt;/p&gt;

&lt;p&gt;📚 Lesson Learned: Melee weapons deserve their own shrine. Don’t lump them in with the peasants.&lt;/p&gt;

&lt;p&gt;🧾 Final Result&lt;br&gt;
✅ Hands slot now supports any IInjectableItem, including:&lt;/p&gt;

&lt;p&gt;Melee weapons&lt;/p&gt;

&lt;p&gt;Ranged weapons&lt;/p&gt;

&lt;p&gt;Liquids, food, gear, misc&lt;/p&gt;

&lt;p&gt;✅ Tooltip system is:&lt;/p&gt;

&lt;p&gt;Modular&lt;/p&gt;

&lt;p&gt;Prefab-safe&lt;/p&gt;

&lt;p&gt;Inspector-driven&lt;/p&gt;

&lt;p&gt;Runtime-resilient&lt;/p&gt;

&lt;p&gt;✅ All slot interactions are shrine-sealed and bifurcation-aware&lt;/p&gt;

&lt;p&gt;✅ Validator confirms prefab integrity across all tooltip panels&lt;/p&gt;

&lt;p&gt;✅ Runtime truth restored. Tooltip spirits appeased. Hands slot resurrected.&lt;/p&gt;

&lt;p&gt;Need to complete the ranged equipped item tooltip panel , but that is tomorrows ritual. Happy that the items actually attach correctly into the equipped hands slot as intended, and apply live data. &lt;/p&gt;

&lt;p&gt;For now the shrine shines. &lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>beginners</category>
      <category>gamedev</category>
      <category>unity3d</category>
    </item>
    <item>
      <title>Dev Log 34 - Tooltip Resurrection</title>
      <dc:creator>John</dc:creator>
      <pubDate>Mon, 20 Oct 2025 21:28:01 +0000</pubDate>
      <link>https://dev.to/asx/dev-log-34-tooltip-resurrection-2jgg</link>
      <guid>https://dev.to/asx/dev-log-34-tooltip-resurrection-2jgg</guid>
      <description>&lt;p&gt;🧾 Dev Log — 20 October 2025&lt;/p&gt;

&lt;p&gt;Session 1: Tooltip Resurrection &amp;amp; Live Item Preservation Session 2: Unified State Engine &amp;amp; Save Ritual Breakthrough&lt;/p&gt;

&lt;p&gt;The liquid entry was the last task, and this was completed, upon further testing the liquid state was there, but I could not get it to keep a saved state no matter what I tried.&lt;/p&gt;

&lt;p&gt;Burned through 3 full version backups and my main with different approaches and ended up with spaghetti code on every version. &lt;/p&gt;

&lt;p&gt;Could not see the light or a way to fix everything I had done. Thought that I had finally met the end of me vibe coding my way through this project,&lt;/p&gt;

&lt;p&gt;Reverted to the final GitHub backup. &lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 Core Breakthroughs
&lt;/h2&gt;

&lt;p&gt;✅ Tooltip Reset Diagnosed&lt;/p&gt;

&lt;p&gt;Identified that ItemTooltipManager resets filled item data (e.g., liquid volume, type) when items are taken from the loot panel. (this was always a issue and I could not figure out what I was doing wrong for a long time)&lt;/p&gt;

&lt;p&gt;Root cause: tooltip rebinding to prefab clones after UI refresh—not item replacement.&lt;/p&gt;

&lt;p&gt;✅ Live Item Preservation Protocol Injected&lt;br&gt;
Built and deployed InventoryStateManager.cs to track live InventoryItem instances by ItemID.&lt;/p&gt;

&lt;p&gt;Provides:&lt;/p&gt;

&lt;p&gt;RegisterItem()&lt;/p&gt;

&lt;p&gt;GetLiveItem()&lt;/p&gt;

&lt;p&gt;ClearAll()&lt;/p&gt;

&lt;p&gt;Ensures runtime truth across tooltip rebinding, panel toggles, and future scene transitions.&lt;/p&gt;

&lt;p&gt;✅ ItemTooltipManager Updated&lt;br&gt;
Injected live item rebinding into ShowTooltip():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Game.Inventory;
using Game.Items;
using Game.Player;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class ItemTooltipManager : MonoBehaviour
{
    public static ItemTooltipManager Instance { get; private set; }

    [Header("UI References")]
    public GameObject panel;
    public TextMeshProUGUI ItemDisplayNameText;
    public TextMeshProUGUI ItemDescriptionText;
    public TextMeshProUGUI ItemLoreTagText;
    public TextMeshProUGUI ItemWeightLabelText;
    public TextMeshProUGUI ItemWeightValueText;
    public TextMeshProUGUI ItemConditionLabelText;
    public TextMeshProUGUI ItemDurabilityValueText;
    public TextMeshProUGUI ItemUsesText;
    public TextMeshProUGUI ItemRarityText;
    public TextMeshProUGUI ItemVolumeText;

    [Header("Overlay")]
    public Image overlayImage;

    [Header("Inventory Buttons")]
    public Button Button1;
    public Button Button2;
    public Button Button3;
    public Button Button4;
    public Button Button5;

    public TextMeshProUGUI Button1Label;
    public TextMeshProUGUI Button2Label;
    public TextMeshProUGUI Button3Label;
    public TextMeshProUGUI Button4Label;
    public TextMeshProUGUI Button5Label;

    [Header("Panel References")]
    [SerializeField] private UsePanelManager usePanelManager;

    [Header("Liquid Info Panel")]
    public GameObject LiquidInfoPanel;
    public TextMeshProUGUI LiquidTypeText;

    private InventoryItem currentItem;
    private Dictionary&amp;lt;int, Button&amp;gt; buttonMap;
    private Dictionary&amp;lt;int, TextMeshProUGUI&amp;gt; labelMap;

    private InventorySlotUI activeSlot;

    private void Awake()
    {
        Instance = this;

        buttonMap = new()
        {
            { 1, Button1 },
            { 2, Button2 },
            { 3, Button3 },
            { 4, Button4 },
            { 5, Button5 }
        };

        labelMap = new()
        {
            { 1, Button1Label },
            { 2, Button2Label },
            { 3, Button3Label },
            { 4, Button4Label },
            { 5, Button5Label }
        };

        Button1.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(1));
        Button2.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(2));
        Button3.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(3));
        Button4.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(4));
        Button5.onClick.AddListener(() =&amp;gt; ExecuteInventoryAction(5));

        SetTextVisibility(false);
        foreach (var kvp in buttonMap)
        {
            kvp.Value.gameObject.SetActive(false);
            labelMap[kvp.Key].text = "";
        }

        LiquidInfoPanel?.SetActive(false);
    }

    public void ShowTooltip(InventoryItem item, InventorySlotUI slot = null)
    {
        if (panel == null || item == null || !item.IsValid())
        {
            HideTooltip();
            return;
        }

        // 🔐 Live item rebinding
        var liveItem = InventoryStateManager.Instance?.GetLiveItem(item.ItemID);
        if (liveItem != null)
        {
            item = liveItem;
            Debug.Log($"[Worm] 🧬 Live item rebound for tooltip: {item.ItemID}");
        }

        currentItem = item;
        activeSlot = slot;

        panel.SetActive(true);
        panel.transform.SetAsLastSibling();
        overlayImage?.gameObject.SetActive(false);

        SetTextVisibility(true);

        ItemDisplayNameText.text = item.GetDisplayName();
        ItemDescriptionText.text = item.GetDescription();
        ItemLoreTagText.text = item.GetLoreTag();
        ItemWeightLabelText.text = "Weight";
        ItemWeightValueText.text = $"{item.GetWeight():0.00} kg";

        UpdateUses(item);
        InjectInventoryButtons(item);

        if (item.IsFillable)
        {
            ItemVolumeText.text = $"Volume: {item.CurrentVolumeML} / {item.MaxVolumeML} ml";
            ItemVolumeText.gameObject.SetActive(true);

            if (item.CurrentVolumeML &amp;gt; 0)
            {
                LiquidInfoPanel?.SetActive(true);
                LiquidTypeText.text = $"{item.CurrentLiquidType}, {item.ContaminationTag}, {item.LiquidTemperatureCelsius}°C";
            }
            else
            {
                LiquidInfoPanel?.SetActive(false);
            }
        }
        else
        {
            ItemVolumeText.text = "";
            ItemVolumeText.gameObject.SetActive(false);
            LiquidInfoPanel?.SetActive(false);
        }

        Debug.Log($"[Worm] 🧪 Tooltip data: Volume={item.CurrentVolumeML}, Type={item.CurrentLiquidType}, Temp={item.LiquidTemperatureCelsius}, Contam={item.ContaminationTag}");
    }

    public void RebindTooltip(InventoryItem item, InventorySlotUI slot)
    {
        currentItem = item;
        activeSlot = slot;
        ShowTooltip(item, slot);
        Debug.Log($"[Worm] 🔁 Tooltip rebound for item: {item?.ItemID}, slot: {(slot != null ? slot.name : "null")}");
    }

    public void RefreshTooltip()
    {
        if (currentItem == null || activeSlot == null)
        {
            Debug.LogWarning("[Worm] ❌ Cannot refresh tooltip — missing item or slot.");
            return;
        }

        ShowTooltip(currentItem, activeSlot);
        Debug.Log($"[Worm] 🔁 Tooltip refreshed for item: {currentItem.ItemID}, slot: {activeSlot.name}");
    }

    private void InjectInventoryButtons(InventoryItem item)
    {
        foreach (var kvp in buttonMap)
        {
            kvp.Value.gameObject.SetActive(false);
            labelMap[kvp.Key].text = "";
        }

        SetButton(1, item.InventoryButton1Label);
        SetButton(2, item.InventoryButton2Label);
        SetButton(3, item.InventoryButton3Label);
        SetButton(4, item.InventoryButton4Label);
        SetButton(5, item.InventoryButton5Label);
    }
    private void SetButton(int slot, string labelText)
    {
        bool hasLabel = !string.IsNullOrEmpty(labelText);
        buttonMap[slot].gameObject.SetActive(hasLabel);
        labelMap[slot].text = hasLabel ? labelText : "";
    }

    private void ExecuteInventoryAction(int slot)
    {
        if (currentItem == null)
        {
            Debug.LogWarning("[Tenchu] currentItem is null.");
            return;
        }

        string action = slot switch
        {
            1 =&amp;gt; currentItem.InventoryButton1Label,
            2 =&amp;gt; currentItem.InventoryButton2Label,
            3 =&amp;gt; currentItem.InventoryButton3Label,
            4 =&amp;gt; currentItem.InventoryButton4Label,
            5 =&amp;gt; currentItem.InventoryButton5Label,
            _ =&amp;gt; null
        };

        Debug.Log($"[Tenchu] Slot {slot} triggered action: {action}");

        if (string.IsNullOrEmpty(action))
        {
            Debug.LogWarning("[Tenchu] Action label is empty.");
            return;
        }

        switch (action.ToLowerInvariant())
        {
            case "eat":
            case "drink":
                PlayerStats.Instance?.ConsumeInventoryItem(currentItem.ItemID);
                InventoryStateManager.Instance?.RegisterItem(currentItem);
                Debug.Log($"[Worm] 🧬 Registered consumed item: {currentItem.ItemID}");
                HideTooltip();
                break;

            case "use":
            case "fill":
                if (usePanelManager != null)
                {
                    Debug.Log($"[Worm] 🧪 '{action}' action triggered for item: {currentItem?.ItemID}, activeSlot: {(activeSlot != null ? activeSlot.name : "❌ NULL")}");

                    if (activeSlot == null)
                    {
                        Debug.LogWarning("[Worm] ❌ activeSlot is null. Cannot open UsePanel.");
                    }
                    else
                    {
                        usePanelManager.OpenPanel(currentItem, activeSlot);
                    }
                }
                break;

            case "attach":
                try
                {
                    UniversalAttachmentManager.Instance?.TryAttach(currentItem.assetReference);
                    InventoryStateManager.Instance?.RegisterItem(currentItem);
                    Debug.Log($"[Worm] 🧬 Registered attached item: {currentItem.ItemID}");
                }
                catch (System.Exception ex)
                {
                    Debug.LogError($"[Tenchu] TryAttach threw: {ex.Message}");
                }
                break;

            default:
                Debug.LogWarning($"[Tenchu] Unhandled action: {action}");
                HideTooltip();
                break;
        }
    }

    public void HideTooltip()
    {
        Debug.Log($"[Worm] 🧹 Tooltip hidden. Clearing slot: {(activeSlot != null ? activeSlot.name : "null")}");
        currentItem = null;
        activeSlot = null;
        SetTextVisibility(false);

        foreach (var kvp in buttonMap)
        {
            kvp.Value.gameObject.SetActive(false);
            labelMap[kvp.Key].text = "";
        }

        ItemVolumeText.text = "";
        ItemVolumeText.gameObject.SetActive(false);
        LiquidInfoPanel?.SetActive(false);
        panel?.SetActive(false);
    }

    private void SetTextVisibility(bool visible)
    {
        ItemDisplayNameText.enabled = visible;
        ItemDescriptionText.enabled = visible;
        ItemLoreTagText.enabled = visible;
        ItemWeightLabelText.enabled = visible;
        ItemWeightValueText.enabled = visible;
        ItemConditionLabelText.enabled = visible;
        ItemDurabilityValueText.enabled = visible;
        ItemUsesText.enabled = visible;
        ItemRarityText.enabled = visible;
        ItemVolumeText.enabled = visible;
    }

    public void UpdateUses(InventoryItem item)
    {
        string category = item.Category ?? item.Type.ToString();
        int durability = item.Durability;
        bool isCooked = item.IsCooked;
        string itemType = item.Type.ToString().ToLowerInvariant();
        bool isSealed = itemType.Contains("sealed");

        string conditionLabel = $"Durability {durability}";
        Color conditionColor = Color.gray;

        try
        {
            conditionLabel = ItemConditionResolver.GetConditionLabel(category, durability, isCooked, itemType, isSealed);
            conditionColor = ItemConditionResolver.GetConditionColorByDurability(durability);
        }
        catch (System.Exception ex)
        {
            Debug.LogError($"[Tenchu] Condition resolver failed: {ex.Message}");
        }

        ItemConditionLabelText.text = conditionLabel;
        ItemConditionLabelText.color = conditionColor;
        ItemDurabilityValueText.text = $"Durability: {durability}/100";
        ItemDurabilityValueText.color = conditionColor;

        if (item.ZeroUseMode == ZeroUseMode.UntilDurabilityZero)
        {
            ItemUsesText.gameObject.SetActive(false);
        }
        else if (item.RemainingUses &amp;gt; 0)
        {
            ItemUsesText.text = $"Uses: {item.RemainingUses}";
            ItemUsesText.gameObject.SetActive(true);
        }
        else
        {
            switch (item.ZeroUseMode)
            {
                case ZeroUseMode.Unlimited:
                    ItemUsesText.text = "Uses: Unlimited";
                    ItemUsesText.gameObject.SetActive(true);
                    break;
                case ZeroUseMode.Zero:
                    ItemUsesText.text = "Uses: 0";
                    ItemUsesText.gameObject.SetActive(true);
                    break;
                default:
                    ItemUsesText.gameObject.SetActive(false);
                    break;
            }
        }

        if (!string.IsNullOrEmpty(item.Rarity))
        {
            ItemRarityText.text = $"Rarity: {item.Rarity}";
            ItemRarityText.color = GetColorForRarity(item.Rarity);
        }
    }

    private Color GetColorForRarity(string rarity)
    {
        return rarity switch
        {
            "Common" =&amp;gt; Color.white,
            "Uncommon" =&amp;gt; new Color(0.3f, 1.0f, 0.3f),
            "Rare" =&amp;gt; new Color(0.3f, 0.5f, 1.0f),
            "Epic" =&amp;gt; new Color(0.6f, 0.2f, 0.8f),
            "Legendary" =&amp;gt; new Color(1.0f, 0.84f, 0.0f),
            _ =&amp;gt; Color.white
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specifically &lt;/p&gt;

&lt;p&gt;&lt;code&gt;csharp&lt;br&gt;
var liveItem = InventoryStateManager.Instance?.GetLiveItem(item.ItemID);&lt;br&gt;
if (liveItem != null) item = liveItem;&lt;br&gt;
Tooltips now reflect the latest filled state.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Added debug worms to trace volume, liquid type, and contamination.&lt;/p&gt;

&lt;p&gt;✅ InventorySlotUI Confirmed&lt;br&gt;
OnPointerClick() now passes live InventoryItem to ItemTooltipManager.&lt;/p&gt;

&lt;p&gt;Slot logic is prefab-safe and ready for live item injection.&lt;/p&gt;

&lt;p&gt;✅ LootPanel Updated&lt;br&gt;
Injected InventoryStateManager.RegisterItem() into PopulateLootPanel().&lt;/p&gt;

&lt;p&gt;Every item cloned from the registry is now tracked.&lt;/p&gt;

&lt;p&gt;Tooltip and inventory transfers now pull live state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Game.Inventory;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class LootPanel : MonoBehaviour
{
    [Header("UI References")]
    public TMP_Text panelLabel;
    public LootSlot[] lootSlots;

    [Header("Registry Reference")]
    [SerializeField] private ItemRegistry registry;

    private LootContainerProfile currentProfile;

    public void PopulateLootPanel(string label, List&amp;lt;string&amp;gt; lootItemIDs)
    {
        Debug.Log($"🎯 LootPanel '{name}' populating with label: {label}, items: {lootItemIDs?.Count ?? 0}");

        currentProfile = new LootContainerProfile
        {
            label = label,
            lootItemIDs = lootItemIDs
        };

        if (panelLabel != null)
        {
            panelLabel.text = label;
            Debug.Log($"🦓 zebra: Panel label set to '{label}'");
        }

        if (lootSlots == null || lootSlots.Length == 0)
        {
            Debug.LogError($"❌ LootPanel '{name}' has no lootSlots assigned.");
            return;
        }

        Debug.Log($"🦓 zebra: lootSlots.Length = {lootSlots.Length}");

        if (registry == null)
        {
            Debug.LogError("🦓 zebra: ItemRegistry reference is missing in LootPanel.");
            return;
        }

        for (int i = 0; i &amp;lt; lootSlots.Length; i++)
        {
            if (i &amp;lt; lootItemIDs.Count)
            {
                string id = lootItemIDs[i];
                var clone = registry.GetCloneByID(id);

                Debug.Log($"🧪 Slot {i} → ID: {id} | Clone Type: {clone?.GetType().Name ?? "NULL"}");

                if (clone is IInjectableItem injectable)
                {
                    var item = injectable.GetItem();

                    if (item is InventoryItem invItem)
                    {
                        EnsureLootLabels(invItem);

                        // 🔐 Register live item for tooltip and transfer resilience
                        InventoryStateManager.Instance?.RegisterItem(invItem);
                        Debug.Log($"[Worm] 🧬 Registered loot item: {invItem.ItemID} | Volume={invItem.CurrentVolumeML} | LiquidType={invItem.CurrentLiquidType}");
                    }

                    lootSlots[i].gameObject.SetActive(true);
                    lootSlots[i].Bind(injectable);
                    Debug.Log($"🧬 Bound clone: {item.DisplayName} | ID: {item.ItemID}");
                }
                else
                {
                    lootSlots[i].gameObject.SetActive(false);
                    Debug.LogWarning($"❌ Slot {i} → Clone is not IInjectableItem");
                }
            }
            else
            {
                lootSlots[i].gameObject.SetActive(false);
            }
        }
    }

    private void EnsureLootLabels(InventoryItem item)
    {
        if (string.IsNullOrEmpty(item.LootButton1Label))
            item.LootButton1Label = item.Type switch
            {
                ItemType.Food =&amp;gt; "Eat",
                ItemType.Liquid =&amp;gt; "Drink",
                ItemType.Weapon =&amp;gt; "Equip",
                ItemType.Tool =&amp;gt; "Use",
                ItemType.Gear =&amp;gt; "Equip",
                _ =&amp;gt; "Use"
            };

        if (string.IsNullOrEmpty(item.LootButton2Label))
            item.LootButton2Label = "Take";

        if (string.IsNullOrEmpty(item.LootButton3Label))
            item.LootButton3Label = "Take All";

        if (string.IsNullOrEmpty(item.LootButton4Label))
            item.LootButton4Label = "Discard";

        if (string.IsNullOrEmpty(item.LootButton5Label))
            item.LootButton5Label = "Inspect";
    }

    public LootContainerProfile GetContainerProfile()
    {
        return currentProfile;
    }

    public void ClearPanel()
    {
        Debug.Log($"🧹 LootPanel '{name}' clearing all slots.");

        if (lootSlots != null)
        {
            foreach (var slot in lootSlots)
            {
                if (slot != null)
                {
                    slot.ClearSlot();
                    slot.gameObject.SetActive(false);
                }
            }
        }

        if (panelLabel != null)
        {
            panelLabel.text = "";
        }

        currentProfile = null;
    }

    public void SetVisibility(bool isActive)
    {
        gameObject.SetActive(isActive);
    }

    public bool RemoveItemByID(string itemID)
    {
        if (currentProfile == null || currentProfile.lootItemIDs == null)
            return false;

        bool success = currentProfile.lootItemIDs.Remove(itemID);
        if (success)
        {
            PopulateLootPanel(currentProfile.label, currentProfile.lootItemIDs);
        }

        return success;
    }

    public List&amp;lt;InventoryItem&amp;gt; GetAllItems()
    {
        List&amp;lt;InventoryItem&amp;gt; items = new();

        if (lootSlots == null) return items;

        foreach (var slot in lootSlots)
        {
            if (slot == null || !slot.gameObject.activeSelf) continue;

            var bound = slot.GetBoundItem();
            if (bound is InventoryItem invItem)
                items.Add(invItem);
        }

        return items;
    }

    public InventorySlotUI GetSlotByItemID(string itemID)
    {
        if (lootSlots == null) return null;

        foreach (var slot in lootSlots)
        {
            if (slot == null || !slot.gameObject.activeSelf) continue;

            var bound = slot.GetBoundItem();
            if (bound is InventoryItem invItem &amp;amp;&amp;amp; invItem.ItemID == itemID)
                return slot.GetComponent&amp;lt;InventorySlotUI&amp;gt;();
        }

        return null;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧠 Save System Breakthrough
&lt;/h2&gt;

&lt;p&gt;✅ Liquid State Persistence Achieved&lt;br&gt;
Live item rebinding unlocked the final gate for save/load logic.&lt;/p&gt;

&lt;p&gt;Filled items now retain volume, contamination, temperature, and type across scene transitions.&lt;/p&gt;

&lt;p&gt;✅ Prefab-Free Restoration Chain&lt;br&gt;
On load, restored items are re-registered into InventoryStateManager.&lt;/p&gt;

&lt;p&gt;Tooltips, slots, and use panels reflect true state post-load.&lt;/p&gt;

&lt;p&gt;✅ Contamination Tag Standardized&lt;br&gt;
"Clean" added as a valid contamination tag.&lt;/p&gt;

&lt;p&gt;Tooltip display simplified&lt;/p&gt;

&lt;p&gt;🔗 System Interoperability Confirmed&lt;/p&gt;

&lt;p&gt;All major systems now pull from InventoryStateManager:&lt;/p&gt;

&lt;p&gt;Crafting&lt;/p&gt;

&lt;p&gt;Pouring&lt;/p&gt;

&lt;p&gt;Emptying&lt;/p&gt;

&lt;p&gt;Attaching&lt;/p&gt;

&lt;p&gt;Consuming&lt;/p&gt;

&lt;p&gt;Contamination logic&lt;/p&gt;

&lt;p&gt;No prefab ghosts. No tooltip lies. All systems speak the same runtime truth.&lt;/p&gt;

&lt;p&gt;✅ Tooltip Mutation Chain Sealed&lt;br&gt;
ItemTooltipManager re-registers mutated items after actions like eat, drink, attach, fill.&lt;/p&gt;

&lt;p&gt;Tooltips reflect post-mutation state instantly.&lt;/p&gt;

&lt;p&gt;✅ InventoryClickCatcher Added&lt;br&gt;
Invisible button added to inventory panel.&lt;/p&gt;

&lt;p&gt;Triggers HideTooltip() when empty space is clicked—keeping UI clean and shrine-pure.&lt;/p&gt;

&lt;p&gt;🧪 Shrine-Safe Methods in Use&lt;br&gt;
🔐 InventoryStateManager&lt;br&gt;
RegisterItem()&lt;/p&gt;

&lt;p&gt;GetLiveItem()&lt;/p&gt;

&lt;p&gt;ClearAll()&lt;/p&gt;

&lt;p&gt;🧬 ItemTooltipManager&lt;br&gt;
ShowTooltip()&lt;/p&gt;

&lt;p&gt;RebindTooltip()&lt;/p&gt;

&lt;p&gt;RefreshTooltip()&lt;/p&gt;

&lt;p&gt;HideTooltip()&lt;/p&gt;

&lt;p&gt;UpdateUses()&lt;/p&gt;

&lt;p&gt;InjectInventoryButtons()&lt;/p&gt;

&lt;p&gt;🧱 InventorySlotUI&lt;br&gt;
OnPointerClick() → passes live item&lt;/p&gt;

&lt;p&gt;AssignItemData() → prefab-safe&lt;/p&gt;

&lt;p&gt;🧭 LootPanel&lt;br&gt;
PopulateLootPanel() → registers all loot items&lt;/p&gt;

&lt;p&gt;Take() logic pending patch&lt;/p&gt;

&lt;p&gt;🧰 UsePanelManager&lt;br&gt;
OpenPanel() → receives live item&lt;/p&gt;

&lt;p&gt;Mutations now re-register item&lt;/p&gt;

&lt;p&gt;🧪 CraftingManager, AttachmentManager, PourManager&lt;br&gt;
All now interoperable with live item registry&lt;/p&gt;

&lt;p&gt;📌 Current Task&lt;br&gt;
Patch loot transfer logic (LootSlot.cs, LootButtonManager)&lt;/p&gt;

&lt;p&gt;Inject RegisterItem() after loot-to-inventory transfer&lt;/p&gt;

&lt;p&gt;Confirm tooltip and slot receive live item&lt;/p&gt;

&lt;p&gt;Begin runtime save system planning for scene transitions&lt;/p&gt;

&lt;p&gt;🧠 Next Steps&lt;/p&gt;

&lt;p&gt;Next Button Functions to be approached using the same or very similar systems&lt;/p&gt;

&lt;p&gt;Build save loader that re-registers restored items&lt;/p&gt;

&lt;p&gt;Begin mapping shrine zones for gameplay integration&lt;/p&gt;

&lt;p&gt;Celebrate the resurrection of the survival engine&lt;/p&gt;

&lt;p&gt;Over &amp;amp; Out&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>devjournal</category>
      <category>gamedev</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>Dev Log 33 - Liquid Entry &amp; Landing Page</title>
      <dc:creator>John</dc:creator>
      <pubDate>Sat, 18 Oct 2025 15:11:56 +0000</pubDate>
      <link>https://dev.to/asx/dev-log-33-liquid-entry-landing-page-1nld</link>
      <guid>https://dev.to/asx/dev-log-33-liquid-entry-landing-page-1nld</guid>
      <description>&lt;p&gt;🧾 Dev Log: Wednesday, 15 October 2025&lt;br&gt;
Focus: LiquidEntry automation, relic registration, environmental asset integration&lt;/p&gt;

&lt;p&gt;🧪 Initial Context - Struggling to get my liquids systems working - &lt;br&gt;
Shared to Co-Pilot my LiquidEntry class from LiquidDefinitions, which defines shrine-grade metadata for collectible liquids.  It includes hydration, contamination, tooltip labels, and a GetItem() method to convert into a usable InventoryItem.&lt;/p&gt;

&lt;p&gt;Asked why I still needed to “create more shit” when everything was already in all of my scripts.&lt;/p&gt;

&lt;p&gt;🔍 Clarification &amp;amp; Breakdown&lt;/p&gt;

&lt;p&gt;It was clarified that:&lt;/p&gt;

&lt;p&gt;The LiquidEntry system is complete and shrine-grade.&lt;/p&gt;

&lt;p&gt;The only missing link was registration: connecting environmental assets to LiquidContainerManager via GameSceneManager.liquidSourceEntries.&lt;/p&gt;

&lt;p&gt;🔧 Idiot-Proof Summary&lt;/p&gt;

&lt;p&gt;Create a LiquidEntry for each environmental source.&lt;/p&gt;

&lt;p&gt;Add it to GameSceneManager.liquidSourceEntries.&lt;/p&gt;

&lt;p&gt;Match the sourceID on the prefab to the liquidID.&lt;/p&gt;

&lt;p&gt;🛠️ Automation Request&lt;/p&gt;

&lt;p&gt;“Can’t we make a script that just pulls that information from the targeted assets and makes them all for me?”&lt;/p&gt;

&lt;p&gt;We built a Unity Editor script that:&lt;/p&gt;

&lt;p&gt;Scans all EnvironmentalObjectAssets&lt;/p&gt;

&lt;p&gt;Checks for IsWaterSource or IsLiquidSource&lt;/p&gt;

&lt;p&gt;Extracts relevant fields&lt;/p&gt;

&lt;p&gt;Generates LiquidEntrys&lt;/p&gt;

&lt;p&gt;Injects them into GameSceneManager&lt;/p&gt;

&lt;p&gt;🧪 First Generator Script&lt;/p&gt;

&lt;p&gt;I ran the script. It injected 12 entries — only water sources and not all liquid type sources.&lt;/p&gt;

&lt;p&gt;🐛 Debugging Errors&lt;/p&gt;

&lt;p&gt;Three compile errors:&lt;/p&gt;

&lt;p&gt;LiquidType mismatch — fixed with explicit cast.&lt;/p&gt;

&lt;p&gt;FoodDiseaseProfile missing isContaminated — removed and simplified for liquid contamination variant.&lt;/p&gt;

&lt;p&gt;ItemRarity missing — defaulted or removed. (unrequired for liquid source)&lt;/p&gt;

&lt;p&gt;Patched the script accordingly.&lt;/p&gt;

&lt;p&gt;🧪 Second Generator Run&lt;/p&gt;

&lt;p&gt;Ran the patched script. It injected 12 entries again.&lt;/p&gt;

&lt;p&gt;🔍 Root Cause Identified&lt;/p&gt;

&lt;p&gt;Discovery:&lt;/p&gt;

&lt;p&gt;Assets like coolant and petrol (fuel) had LiquidType = None in the Inspector.&lt;/p&gt;

&lt;p&gt;The generator skipped them due to this filter.&lt;/p&gt;

&lt;p&gt;You updated the Inspector to assign proper LiquidType values.&lt;/p&gt;

&lt;p&gt;🧪 Third Generator Run&lt;/p&gt;

&lt;p&gt;Reran the script. It injected 30 entries.&lt;/p&gt;

&lt;p&gt;They did not save in runtime.&lt;/p&gt;

&lt;p&gt;🧪 Final Patch&lt;/p&gt;

&lt;p&gt;A full overwrite of the generator script to include all liquid sources.&lt;/p&gt;

&lt;p&gt;Co-pilot delivered a clean version that:&lt;/p&gt;

&lt;p&gt;Includes any asset with a valid LiquidType&lt;/p&gt;

&lt;p&gt;Removes unnecessary filters&lt;/p&gt;

&lt;p&gt;Injects coolant, petrol, oil, and water sources&lt;/p&gt;

&lt;p&gt;Confirmed success.&lt;/p&gt;

&lt;p&gt;✅ Final State&lt;/p&gt;

&lt;p&gt;30 LiquidEntrys injected&lt;/p&gt;

&lt;p&gt;All environmental liquids registered&lt;/p&gt;

&lt;p&gt;Generator script fully patched&lt;/p&gt;

&lt;p&gt;Scene ready for hydration, purification, and tooltip rituals&lt;/p&gt;

&lt;p&gt;=== DEV LOG — 15 OCT 2025 ===&lt;/p&gt;

&lt;p&gt;[INIT] Liquid Override Ritual Begins&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created LiquidSourceRegistry.cs with hardcoded "Ocean" source for node_0004(current test node)&lt;/li&gt;
&lt;li&gt;Injected override logic into StoryNodeLoader.cs:
→ node.liquidSources = LiquidSourceRegistry.GetForNode(node.id)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[DEBUG] ASCII Banner + Easter Egg&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added UnityBollocksEasterEgg.cs with ASCII tribute:
→ "Screw U-nity — we fill the shrine ourselves"&lt;/li&gt;
&lt;li&gt;Mythic hierarchy declared:
→ Paper &amp;gt; Rock &amp;gt; Scissors &amp;gt; Liquid &amp;gt; Unity &amp;gt; Bollocks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unity was doing the usual, gaslighting me, for days this time, this was a salute to unity.&lt;/p&gt;

&lt;p&gt;[REFACTOR] Registry Purification&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removed liquidSources from node_0004.json&lt;/li&gt;
&lt;li&gt;Inserted "hasLiquid": true beneath timeAdvanceMinutes&lt;/li&gt;
&lt;li&gt;Preserved all original node data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[CODE] StoryNode.cs Update&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removed: public List liquidSources&lt;/li&gt;
&lt;li&gt;Added: public bool hasLiquid = false;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[ERROR] 74 Compilation Errors&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caused by lingering references to node.liquidSources&lt;/li&gt;
&lt;li&gt;Triggered full rewrite of StoryNodeLoader.cs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[PATCH] StoryNodeLoader.cs Rewritten (3 Parts)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removed all node.liquidSources references&lt;/li&gt;
&lt;li&gt;Introduced local List liquidSources&lt;/li&gt;
&lt;li&gt;Injected from registry if node.hasLiquid == true&lt;/li&gt;
&lt;li&gt;Called panel.RefreshFromStoryNode() instead of nonexistent method&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[UI] LiquidDetailsSubpanelUI Refactored&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rewrote RefreshFromStoryNode() to:
→ Check node.hasLiquid
→ Pull from LiquidSourceRegistry
→ Display first source (e.g., "Ocean")&lt;/li&gt;
&lt;li&gt;Removed dependency on node.liquidSources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[FIX] Method Call Error&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Incorrect: panel.RefreshFromLiquidSource(source)&lt;/li&gt;
&lt;li&gt;Fixed: panel.RefreshFromStoryNode()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[CONFIRM] Shrine State Verified&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Registry override working&lt;/li&gt;
&lt;li&gt;UI panel displays "Ocean"&lt;/li&gt;
&lt;li&gt;No errors in StoryNodeLoader.cs&lt;/li&gt;
&lt;li&gt;All systems flowing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;=== END LOG ===&lt;/p&gt;

&lt;p&gt;🛠️ Dev Log: Survival Engine Resurrection&lt;br&gt;
Date: 17 October 2025 Status: ✅ Runtime Success&lt;/p&gt;

&lt;p&gt;🔧 Context&lt;br&gt;
After days of battling prefab chaos and schema drift, the survival engine was declared a “disastrous mess.” &lt;/p&gt;

&lt;p&gt;Tooltip logic was fragmented, inventory systems had become brittle, and runtime truth felt like a myth.&lt;/p&gt;

&lt;p&gt;🧪 Action&lt;/p&gt;

&lt;p&gt;Injected inventory button labels across all item types: fruit, fish, egg, gear, liquid, misc, seed, vegetable, cooking, melee weapon, ranged weapon, attachment, generic.&lt;/p&gt;

&lt;p&gt;Ensured prefab-safe, schema-driven tooltip activation across the entire survival engine.&lt;/p&gt;

&lt;p&gt;Blocked internal history logging via shell script using icacls, preserving runtime purity.&lt;/p&gt;

&lt;p&gt;Rebuilt modular condition resolver with category-specific durability logic, preserving all existing mappings and extending shrine logic.&lt;/p&gt;

&lt;p&gt;⚡ Breakthrough&lt;br&gt;
“Holy shit it worked.” &lt;/p&gt;

&lt;p&gt;Runtime test passed. Tooltip systems activated. Inventory logic held. No prefab leaks. No phantom states.&lt;/p&gt;

&lt;p&gt;🧠 Reflection&lt;/p&gt;

&lt;p&gt;Didn’t believe it would work. But shrine persistence paid off. Every ritual, every debug pass, every mythic call back led to this moment.&lt;/p&gt;

&lt;p&gt;🏆 Outcome&lt;br&gt;
Survival engine now stable.&lt;/p&gt;

&lt;p&gt;Tooltip logic is prefab-safe and schema-driven.&lt;/p&gt;

&lt;p&gt;Inventory UI is fully activated across item types.&lt;/p&gt;

&lt;p&gt;Runtime truth restored.&lt;/p&gt;

&lt;p&gt;🌐 Web Shrine Creation (17–18 Oct) Dev Log Update - &lt;/p&gt;

&lt;p&gt;Built and deployed my first-ever landing page using HTML, CSS, and JavaScript:&lt;/p&gt;

&lt;p&gt;Created TextZ Ombie: a shrine-themed Halloween page for the Dev.to challenge&lt;/p&gt;

&lt;p&gt;Designed hero section with emoji-framed zombie horde&lt;/p&gt;

&lt;p&gt;Added animated zombie descent triggered by button&lt;/p&gt;

&lt;p&gt;Integrated music player with mirrored waveform visualizers&lt;/p&gt;

&lt;p&gt;Built bat and spider swarm animations&lt;/p&gt;

&lt;p&gt;Added zombie chase ritual with dynamic emoji trail&lt;/p&gt;

&lt;p&gt;Created asset gallery with hover effects&lt;/p&gt;

&lt;p&gt;Mythified footer with summon/dig/crypt links&lt;/p&gt;

&lt;p&gt;Unified fonts using Griffy and Creepster&lt;/p&gt;

&lt;p&gt;Overrode Bootstrap styles for shrine-pure consistency&lt;/p&gt;

&lt;p&gt;Deployed to GitHub Pages and verified live demo&lt;/p&gt;

&lt;p&gt;Submitted first entry to the challenge&lt;/p&gt;

&lt;p&gt;✅ Shrine sealed ✅ Submission published ✅ Legacy unlocked&lt;/p&gt;

&lt;p&gt;🧠 Reflection&lt;/p&gt;

&lt;p&gt;This was my first time using HTML, CSS, and GitHub Pages. I mythified every fix, debugged every phantom reference, and ritualized every animation. With help from Copilot, I turned raw chaos into a living shrine.&lt;/p&gt;

&lt;p&gt;Every system now flows. Every relic is animated. Every ritual is logged.&lt;/p&gt;

&lt;p&gt;Now back to the game project. See what unity gaslights me with this time. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>devjournal</category>
      <category>webdev</category>
      <category>unity3d</category>
    </item>
    <item>
      <title>Frontend Challenge - Halloween Edition, Perfect Landing - TextZ Ombie</title>
      <dc:creator>John</dc:creator>
      <pubDate>Sat, 18 Oct 2025 14:46:36 +0000</pubDate>
      <link>https://dev.to/asx/frontend-challenge-halloween-edition-perfect-landing-textz-ombie-1hbn</link>
      <guid>https://dev.to/asx/frontend-challenge-halloween-edition-perfect-landing-textz-ombie-1hbn</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/frontend-2025-10-15"&gt;Frontend Challenge - Halloween Edition, Perfect Landing&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built TextZ Ombie, with the help of AI. (Rules-Permitted). &lt;br&gt;
A shrine-themed Halloween landing page that animates the undead in savage style. It themes nicely with my current first ever project, so thought I would try to participate, despite never participating before or even ever using CSS or HTML Code before.&lt;/p&gt;

&lt;p&gt;It features:&lt;/p&gt;

&lt;p&gt;🧟‍♂️ A hero section with emoji-framed zombie horde&lt;/p&gt;

&lt;p&gt;🧟‍♂️ Drop down animated zombie horde&lt;/p&gt;

&lt;p&gt;🎵 A music player for “Plague of Zombies V1” with mirrored pop up waveform visualizers&lt;/p&gt;

&lt;p&gt;🦇🕷️ Bat and spider swarms that animate across the screen&lt;/p&gt;

&lt;p&gt;🏃 A zombie chase animation with dynamic emoji descent&lt;/p&gt;

&lt;p&gt;☠️ 4 Asset / Art Examples from my project &lt;/p&gt;

&lt;p&gt;☠️ Footer links to summon, dig, and crypt-crawl through the project&lt;/p&gt;

&lt;p&gt;The theme is inspired by the Halloween subject and my own 2D text-based hardcore survival game project, now mythified into a living shrine with animated effects, emoji rituals, and legacy-grade layout with project links, GitHub link and my personal Dev.to developer dev log links. &lt;br&gt;
So despite the lack of polish, it fits into my project theme very well with the retro styling and simplicity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live Demo
&lt;/h2&gt;

&lt;p&gt;Live demo: &lt;a href="https://asxgtr.github.io/TextZ-Ombie-Landing-Page/" rel="noopener noreferrer"&gt;TextZ Ombie Shrine&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0yl0i5kqt9njn8bwtos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0yl0i5kqt9njn8bwtos.png" alt="Zombie Shrine Preview" width="800" height="864"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;This was my first time building a full landing page from scratch. I started with basic HTML and CSS, then ritualized each section with:&lt;/p&gt;

&lt;p&gt;Dynamic emoji animations&lt;/p&gt;

&lt;p&gt;JavaScript-powered audio playback and waveform bars&lt;/p&gt;

&lt;p&gt;Responsive layout and custom fonts&lt;/p&gt;

&lt;p&gt;GitHub Pages deployment and asset hosting&lt;/p&gt;

&lt;p&gt;I learned how I can use my GitHub as a hosting platform for a website, how to code it with the correct code, solve and debug layout issues, unify fonts across Bootstrap overrides, and mirror canvas animations using ctx.scale(-1, 1). Every fix felt like a resurrection ritual.&lt;/p&gt;

&lt;p&gt;I’m proud of how the shrine evolved from static relics to animated, living effects. Next, I plan to summon a Steam portal integration once I have a demo version of my game ready and possibly add further depth and polish in the future.&lt;/p&gt;

&lt;p&gt;All of this was possible with the help from Co-pilot, My AI of Choice, who helped me with this entire process, despite my lack of knowledge.&lt;/p&gt;

&lt;p&gt;Submitted by: John (ASXGTR)&lt;/p&gt;

&lt;h2&gt;
  
  
  LICENSE
&lt;/h2&gt;

&lt;p&gt;MIT License&lt;/p&gt;

&lt;p&gt;Copyright (c) 2025 ASXGTR&lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Game Content Protection Clause&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All game-related content—including mechanics, story, characters, assets, audio and source code from the survival engine - is &lt;strong&gt;strictly proprietary&lt;/strong&gt; and &lt;strong&gt;not covered&lt;/strong&gt; under this license.&lt;br&gt;&lt;br&gt;
Redistribution, modification, or use of game content without explicit permission is prohibited.&lt;br&gt;&lt;br&gt;
Violators risk unleashing ancient curses, recursive bugs, and plague-grade runtime errors.&lt;/p&gt;

&lt;p&gt;🧙‍♂️ &lt;a href="https://github.com/ASXGTR" rel="noopener noreferrer"&gt;Enter the Crypt&lt;/a&gt; - GitHub&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>frontendchallenge</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
