Code Sketch


yyyyyy
By: Mhalsakant School
Category: Programming
import java.awt._
import java.awt.datatransfer.StringSelection
import java.awt.event._
import java.io._
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.security.MessageDigest
import javax.imageio.ImageIO
import javax.swing._
import javax.swing.border._
import javax.swing.event._
import javax.swing.filechooser.FileNameExtensionFilter

// ============================================================
// IMAGE PROFILE
// ============================================================

case class ImageProfile(
  fileName: String,
  absolutePath: String,
  width: Int,
  height: Int,
  ratio: Double,
  averageR: Int,
  averageG: Int,
  averageB: Int,
  brightness: Int,
  dominantHex: String
)

// ============================================================
// SECURITY
// ============================================================

object PlatformSecurity {

  private val PASSWORD_HASH =
    "951f97336a749358c189391a108e9bff26e4ff756cfeb365af5809a2b1c33ef8"

  def sha256(text: String): String = {
    val digest =
      MessageDigest.getInstance("SHA-256")

    val bytes =
      digest.digest(
        text.getBytes(StandardCharsets.UTF_8)
      )

    val builder =
      new StringBuilder

    var i = 0

    while (i < bytes.length) {
      val value = bytes(i) & 0xff
      val hex = Integer.toHexString(value)

      if (hex.length == 1) {
        builder.append("0")
      }

      builder.append(hex)
      i += 1
    }

    builder.toString
  }

  def verify(candidate: String): Boolean = {
    val candidateHash =
      sha256(candidate)

    MessageDigest.isEqual(
      candidateHash.getBytes(StandardCharsets.UTF_8),
      PASSWORD_HASH.getBytes(StandardCharsets.UTF_8)
    )
  }
}

// ============================================================
// IMAGE ANALYZER
// ============================================================

object ImageAnalyzer {

  def analyze(file: File): Option[ImageProfile] = {
    try {
      val image =
        ImageIO.read(file)

      if (image == null) {
        None
      } else {

        val width =
          image.getWidth

        val height =
          image.getHeight

        var totalR = 0L
        var totalG = 0L
        var totalB = 0L
        var totalBrightness = 0L
        var count = 0L

        val stepX =
          math.max(1, width / 48)

        val stepY =
          math.max(1, height / 48)

        var y = 0

        while (y < height) {
          var x = 0

          while (x < width) {

            val rgb =
              image.getRGB(x, y)

            val r =
              (rgb >> 16) & 0xff

            val g =
              (rgb >> 8) & 0xff

            val b =
              rgb & 0xff

            totalR += r
            totalG += g
            totalB += b

            totalBrightness +=
              ((r * 299) +
               (g * 587) +
               (b * 114)) / 1000

            count += 1L
            x += stepX
          }

          y += stepY
        }

        val safeCount =
          math.max(1L, count)

        val averageR =
          (totalR / safeCount).toInt

        val averageG =
          (totalG / safeCount).toInt

        val averageB =
          (totalB / safeCount).toInt

        val brightness =
          (totalBrightness / safeCount).toInt

        val dominantHex =
          "#%02X%02X%02X".format(
            averageR,
            averageG,
            averageB
          )

        Some(
          ImageProfile(
            file.getName,
            file.getAbsolutePath,
            width,
            height,
            if (height == 0)
              1.0
            else
              width.toDouble / height.toDouble,
            averageR,
            averageG,
            averageB,
            brightness,
            dominantHex
          )
        )
      }

    } catch {
      case _: Throwable =>
        None
    }
  }

  def makePreviewIcon(
      file: File,
      maxWidth: Int,
      maxHeight: Int
  ): Option[ImageIcon] = {

    try {
      val image =
        ImageIO.read(file)

      if (image == null) {
        None
      } else {

        val sourceWidth =
          math.max(1, image.getWidth)

        val sourceHeight =
          math.max(1, image.getHeight)

        val scale =
          math.min(
            maxWidth.toDouble / sourceWidth,
            maxHeight.toDouble / sourceHeight
          )

        val finalScale =
          math.min(1.0, scale)

        val newWidth =
          math.max(
            1,
            (image.getWidth * finalScale).toInt
          )

        val newHeight =
          math.max(
            1,
            (image.getHeight * finalScale).toInt
          )

        val scaled =
          image.getScaledInstance(
            newWidth,
            newHeight,
            Image.SCALE_SMOOTH
          )

        Some(
          new ImageIcon(scaled)
        )
      }

    } catch {
      case _: Throwable =>
        None
    }
  }
}

// ============================================================
// HTML TOOLS
// ============================================================

object HtmlTools {

  def escapeHtml(text: String): String = {
    if (text == null) {
      ""
    } else {
      text
        .replace("&", "&amp;")
        .replace("<", "&lt;")
        .replace(">", "&gt;")
        .replace("\"", "&quot;")
        .replace("'", "&#39;")
    }
  }

  def escapeAttribute(text: String): String = {
    escapeHtml(text)
      .replace("\n", " ")
      .replace("\r", " ")
  }

  def slug(text: String): String = {
    val cleaned =
      Option(text)
        .getOrElse("")
        .toLowerCase
        .replaceAll("[^a-z0-9]+", "-")

    val trimmed =
      cleaned
        .replaceAll("^-+", "")
        .replaceAll("-+$", "")

    if (trimmed.isEmpty) {
      "creator-project"
    } else {
      trimmed.take(56)
    }
  }
}

// ============================================================
// PROJECT GENERATOR
// IMPORTANT: No line-ending "+" concatenation is used.
// ============================================================

object ProjectGenerator {

  private val commonCss =
    """
      |<style>
      |*{box-sizing:border-box}
      |html,body{
      |margin:0;
      |padding:0;
      |min-height:100%;
      |font-family:Inter,Segoe UI,Arial,sans-serif
      |}
      |body{
      |background:#0b1020;
      |color:#edf2ff
      |}
      |.page{
      |max-width:1120px;
      |margin:0 auto;
      |padding:36px
      |}
      |.card{
      |background:rgba(20,28,52,.92);
      |border:1px solid rgba(255,255,255,.10);
      |border-radius:24px;
      |padding:28px;
      |box-shadow:0 18px 55px rgba(0,0,0,.22)
      |}
      |.hero{
      |padding:56px 36px;
      |text-align:center;
      |border-radius:28px;
      |background:linear-gradient(135deg,#131d3c,#17264f)
      |}
      |.eyebrow{
      |display:inline-block;
      |padding:8px 12px;
      |border-radius:999px;
      |background:rgba(255,255,255,.08);
      |font-size:12px;
      |letter-spacing:1.4px;
      |text-transform:uppercase
      |}
      |h1{
      |font-size:52px;
      |line-height:1.02;
      |margin:18px 0 14px
      |}
      |h2{
      |font-size:28px;
      |margin:0 0 12px
      |}
      |h3{
      |font-size:18px;
      |margin:0 0 8px
      |}
      |p{
      |color:#b7c2dc;
      |line-height:1.7
      |}
      |.muted{
      |color:#8f9ab6
      |}
      |.grid{
      |display:grid;
      |grid-template-columns:repeat(3,1fr);
      |gap:18px;
      |margin-top:22px
      |}
      |.grid2{
      |display:grid;
      |grid-template-columns:repeat(2,1fr);
      |gap:18px;
      |margin-top:22px
      |}
      |.pill{
      |display:inline-block;
      |padding:8px 12px;
      |margin:5px;
      |border-radius:999px;
      |background:#202b4d;
      |color:#cfdaff;
      |font-size:13px
      |}
      |.btn{
      |display:inline-block;
      |padding:13px 18px;
      |border-radius:13px;
      |background:#6d7dff;
      |color:#fff;
      |text-decoration:none;
      |font-weight:700;
      |margin:6px 4px;
      |border:0;
      |cursor:pointer
      |}
      |.btn.secondary{
      |background:#253251
      |}
      |input,textarea,select{
      |width:100%;
      |padding:13px 15px;
      |border-radius:12px;
      |border:1px solid #364363;
      |background:#0f1730;
      |color:#fff
      |}
      |label{
      |display:block;
      |font-weight:700;
      |margin:0 0 7px
      |}
      |.field{
      |margin-bottom:16px
      |}
      |.metric{
      |font-size:34px;
      |font-weight:800;
      |margin-top:4px
      |}
      |.bar{
      |height:9px;
      |border-radius:999px;
      |background:#253251;
      |overflow:hidden
      |}
      |.fill{
      |height:100%;
      |border-radius:999px;
      |background:#6d7dff
      |}
      |.footer{
      |margin-top:24px;
      |color:#7f8aa5;
      |text-align:center;
      |font-size:12px
      |}
      |.avatar{
      |width:92px;
      |height:92px;
      |border-radius:50%;
      |background:#273b7a;
      |margin:0 auto 18px;
      |display:flex;
      |align-items:center;
      |justify-content:center;
      |font-size:34px;
      |font-weight:800
      |}
      |.tag{
      |padding:6px 10px;
      |border-radius:8px;
      |background:#1b2745;
      |color:#bdc9ea;
      |display:inline-block;
      |margin:4px;
      |font-size:12px
      |}
      |.row{
      |display:flex;
      |gap:14px;
      |align-items:center;
      |justify-content:space-between;
      |flex-wrap:wrap
      |}
      |.progress{
      |margin-top:10px
      |}
      |.code-chip{
      |font-family:Consolas,Monaco,monospace;
      |background:#09101f;
      |border:1px solid #263353;
      |padding:12px;
      |border-radius:12px;
      |overflow:auto
      |}
      |.notice{
      |padding:14px 16px;
      |border-radius:14px;
      |background:rgba(109,125,255,.10);
      |border:1px solid rgba(109,125,255,.24);
      |color:#ced7ff
      |}
      |</style>
      |""".stripMargin

  private def join(parts: String*): String = {
    parts.mkString
  }

  private def baseHtml(
      title: String,
      category: String,
      body: String,
      image: Option[ImageProfile],
      generation: Int
  ): String = {

    val safeTitle =
      HtmlTools.escapeHtml(title)

    val imageSection =
      image match {

        case Some(profile) =>

          val imageUri =
            HtmlTools.escapeAttribute(
              new File(
                profile.absolutePath
              ).toURI.toString
            )

          join(
            "<div class='card' style='margin-top:20px'>",
            "<div class='row'>",
            "<div>",
            "<h3>Reference Visual</h3>",
            "<p class='muted'>",
            "Imported design reference analyzed locally.",
            "</p>",
            "</div>",
            "<span class='pill'>",
            profile.width.toString,
            " � ",
            profile.height.toString,
            "</span>",
            "</div>",
            "<img src='",
            imageUri,
            "' style='display:block;max-width:100%;",
            "max-height:420px;border-radius:18px;",
            "margin-top:16px;margin-left:auto;",
            "margin-right:auto'/>",
            "</div>"
          )

        case None =>
          ""
      }

    join(
      "<!DOCTYPE html>",
      "<html>",
      "<head>",
      "<meta charset='UTF-8'>",
      "<meta name='viewport' ",
      "content='width=device-width,initial-scale=1'>",
      "<title>",
      safeTitle,
      "</title>",
      commonCss,
      "</head>",
      "<body>",
      "<main class='page'>",
      body,
      imageSection,
      "<div class='footer'>",
      "Generated by Developer Creator Platform � ",
      HtmlTools.escapeHtml(category),
      " � Generation ",
      generation.toString,
      "</div>",
      "</main>",
      "</body>",
      "</html>"
    )
  }

  private def inferTitle(
      prompt: String,
      category: String
  ): String = {

    val clean =
      Option(prompt)
        .getOrElse("")
        .trim

    if (clean.isEmpty) {

      category + " Project"

    } else {

      val first =
        clean
          .split("[.!?\\n]")
          .headOption
          .getOrElse(clean)
          .trim
          .take(58)

      if (first.isEmpty) {
        category + " Project"
      } else {
        first
      }
    }
  }

  def generate(
      category: String,
      prompt: String,
      image: Option[ImageProfile],
      generation: Int
  ): String = {

    val cleanPrompt =
      Option(prompt)
        .getOrElse("")
        .trim

    val safePrompt =
      HtmlTools.escapeHtml(
        cleanPrompt
      )

    val title =
      inferTitle(
        prompt,
        category
      )

    val visualColor =
      image
        .map(_.dominantHex)
        .getOrElse("#6D7DFF")

    val imageInsight =
      image match {

        case Some(p) =>
          join(
            "<div class='notice'>",
            "Reference analysis: ",
            p.width.toString,
            "�",
            p.height.toString,
            " � aspect ",
            "%.2f".format(p.ratio),
            " � sampled dominant tone ",
            p.dominantHex,
            " � brightness ",
            p.brightness.toString,
            "/255.",
            "</div>"
          )

        case None =>
          join(
            "<div class='notice'>",
            "No reference image uploaded. ",
            "The generator is using prompt-driven layout decisions.",
            "</div>"
          )
      }

    val body =
      category match {

        // ------------------------------------------------------
        // WEBSITES
        // ------------------------------------------------------

        case "Websites" =>

          join(

            "<section class='hero' ",
            "style='border-top:5px solid ",
            visualColor,
            "'>",

            "<span class='eyebrow'>Website Studio</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "A flexible multi-section website generated from your brief."
            else
              safePrompt,

            "</p>",

            "<a class='btn' href='#explore'>Explore Project</a>",
            "<a class='btn secondary' href='#contact'>Contact</a>",

            "</section>",

            "<section id='explore' class='grid'>",

            "<div class='card'>",
            "<h3>Hero</h3>",
            "<p>",
            "Clear value proposition, responsive hierarchy, ",
            "and strong call to action.",
            "</p>",
            "</div>",

            "<div class='card'>",
            "<h3>Features</h3>",
            "<p>",
            "Reusable cards, sections, metrics, and content modules ",
            "are ready to customize.",
            "</p>",
            "</div>",

            "<div class='card'>",
            "<h3>Contact</h3>",
            "<p>",
            "Built with semantic structure and form-ready controls.",
            "</p>",
            "</div>",

            "</section>",

            imageInsight,

            "<section id='contact' class='card' ",
            "style='margin-top:20px'>",

            "<h2>Contact</h2>",

            "<div class='grid2'>",

            "<div class='field'>",
            "<label>Name</label>",
            "<input placeholder='Your name'>",
            "</div>",

            "<div class='field'>",
            "<label>Email</label>",
            "<input placeholder='you@example.com'>",
            "</div>",

            "</div>",

            "<button class='btn'>Send Message</button>",

            "</section>"
          )

        // ------------------------------------------------------
        // LINKS
        // ------------------------------------------------------

        case "Links" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Link Hub</span>",

            "<div class='avatar'>L</div>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",
            "Your links, resources, socials, and important ",
            "destinations in one clean page.",
            "</p>",

            "<a class='btn' href='#links'>",
            "Open Link Collection",
            "</a>",

            "</section>",

            "<section id='links' class='card' ",
            "style='margin-top:20px'>",

            "<h2>Quick Links</h2>",

            "<p class='muted'>",

            if (safePrompt.isEmpty)
              "Add your links and short descriptions."
            else
              safePrompt,

            "</p>",

            "<a class='btn' href='#'>Main Website</a>",
            "<a class='btn' href='#'>Portfolio</a>",
            "<a class='btn secondary' href='#'>Social Profile</a>",
            "<a class='btn secondary' href='#'>Contact</a>",

            "</section>"
          )

        // ------------------------------------------------------
        // BIO PAGES
        // ------------------------------------------------------

        case "Bio Pages" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Bio Creator</span>",

            "<div class='avatar'>B</div>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "Creator � Developer � Builder � Dreamer"
            else
              safePrompt,

            "</p>",

            "<span class='pill'>Developer</span>",
            "<span class='pill'>Designer</span>",
            "<span class='pill'>Creator</span>",

            "</section>",

            "<section class='grid2'>",

            "<div class='card'>",
            "<h2>About</h2>",
            "<p>",
            "Use this area for your story, skills, goals, ",
            "and professional summary.",
            "</p>",
            "</div>",

            "<div class='card'>",
            "<h2>Focus</h2>",
            "<p>",
            "Projects, collaborations, experiments, and future ",
            "ideas can be highlighted here.",
            "</p>",
            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // APPS
        // ------------------------------------------------------

        case "Apps" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>App Generator</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "A polished application interface with cards, navigation, " +
              "actions, and status areas."
            else
              safePrompt,

            "</p>",

            "<button class='btn'>Launch App</button>",

            "</section>",

            "<section class='grid'>",

            "<div class='card'>",
            "<h3>Home</h3>",
            "<p>Primary application workspace.</p>",
            "</div>",

            "<div class='card'>",
            "<h3>Activity</h3>",
            "<p>Recent actions and updates.</p>",
            "</div>",

            "<div class='card'>",
            "<h3>Settings</h3>",
            "<p>Preferences and configuration.</p>",
            "</div>",

            "</section>",

            "<section class='card' style='margin-top:20px'>",

            "<h2>App State</h2>",

            "<div class='row'>",
            "<span class='muted'>Status</span>",
            "<span class='tag'>READY</span>",
            "</div>",

            "<div class='row'>",
            "<span class='muted'>Mode</span>",
            "<span class='tag'>LOCAL</span>",
            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // GAMES
        // ------------------------------------------------------

        case "Games" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Game Creator</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "A game shell with HUD, player state, objectives, " +
              "and action controls."
            else
              safePrompt,

            "</p>",

            "<button class='btn'>Start Game</button>",
            "<button class='btn secondary'>How To Play</button>",

            "</section>",

            "<section class='grid'>",

            "<div class='card'>",
            "<h3>PLAYER</h3>",
            "<div class='metric'>100 HP</div>",
            "<div class='progress'>",
            "<div class='bar'>",
            "<div class='fill' style='width:80%'></div>",
            "</div>",
            "</div>",
            "</div>",

            "<div class='card'>",
            "<h3>SCORE</h3>",
            "<div class='metric'>000250</div>",
            "<p class='muted'>",
            "Best score tracked in your project state.",
            "</p>",
            "</div>",

            "<div class='card'>",
            "<h3>LEVEL</h3>",
            "<div class='metric'>01</div>",
            "<p class='muted'>Progression-ready structure.</p>",
            "</div>",

            "</section>",

            "<section class='card' style='margin-top:20px'>",

            "<h2>Controls</h2>",
            "<span class='tag'>W A S D</span>",
            "<span class='tag'>ARROWS</span>",
            "<span class='tag'>SPACE</span>",
            "<span class='tag'>MOUSE</span>",

            "</section>"
          )

        // ------------------------------------------------------
        // LANDING PAGES
        // ------------------------------------------------------

        case "Landing Pages" =>

          join(

            "<section class='hero' ",
            "style='background:linear-gradient(135deg,",
            visualColor,
            ",#10162c)'>",

            "<span class='eyebrow'>Launch Ready</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "A conversion-focused landing page with clear " +
              "hierarchy and compact messaging."
            else
              safePrompt,

            "</p>",

            "<a class='btn' href='#cta'>Get Started</a>",

            "</section>",

            "<section class='grid'>",

            "<div class='card'>",
            "<h3>Fast Setup</h3>",
            "<p>Simple sections that can be customized quickly.</p>",
            "</div>",

            "<div class='card'>",
            "<h3>Strong Message</h3>",
            "<p>Hero-first layout with clear benefits and trust signals.</p>",
            "</div>",

            "<div class='card'>",
            "<h3>Action Focused</h3>",
            "<p>Buttons and forms are positioned around the main goal.</p>",
            "</div>",

            "</section>",

            "<section id='cta' class='card' ",
            "style='margin-top:20px;text-align:center'>",

            "<h2>Ready to build?</h2>",
            "<p>Turn your idea into a presentable project.</p>",
            "<button class='btn'>Create Now</button>",

            "</section>"
          )

        // ------------------------------------------------------
        // UI DESIGNS
        // ------------------------------------------------------

        case "UI Designs" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>UI Design Lab</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "Component-first interface exploration with cards, " +
              "spacing, typography, and controls."
            else
              safePrompt,

            "</p>",

            "</section>",

            "<section class='grid2'>",

            "<div class='card'>",

            "<h2>Components</h2>",
            "<button class='btn'>Primary</button>",
            "<button class='btn secondary'>Secondary</button>",
            "<span class='pill'>Badge</span>",
            "<span class='pill'>New</span>",

            "</div>",

            "<div class='card'>",

            "<h2>Form Preview</h2>",

            "<div class='field'>",
            "<label>Project name</label>",
            "<input placeholder='Type here'>",
            "</div>",

            "<div class='field'>",
            "<label>Message</label>",
            "<textarea rows='4' ",
            "placeholder='Describe your design'></textarea>",
            "</div>",

            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // TOOLS
        // ------------------------------------------------------

        case "Tools" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Tool Builder</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "An interactive utility layout ready for your custom logic."
            else
              safePrompt,

            "</p>",

            "</section>",

            "<section class='card' style='margin-top:20px'>",

            "<div class='field'>",
            "<label>Input</label>",
            "<textarea rows='6' ",
            "placeholder='Enter data...'></textarea>",
            "</div>",

            "<button class='btn'>Run Tool</button>",
            "<button class='btn secondary'>Clear</button>",

            "<div class='card' ",
            "style='margin-top:18px;background:#0b1328'>",

            "<h3>Output</h3>",
            "<div class='code-chip'>",
            "Output will appear here.",
            "</div>",

            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // PORTFOLIOS
        // ------------------------------------------------------

        case "Portfolios" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Portfolio Studio</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "A project portfolio with featured work, capabilities, " +
              "and contact information."
            else
              safePrompt,

            "</p>",

            "</section>",

            "<section class='grid'>",

            "<div class='card'>",

            "<span class='tag'>01</span>",
            "<h3>Featured Project</h3>",
            "<p>",
            "Show the strongest project with a focused story and results.",
            "</p>",
            "<button class='btn'>View</button>",

            "</div>",

            "<div class='card'>",

            "<span class='tag'>02</span>",
            "<h3>Experiment</h3>",
            "<p>",
            "Highlight creative tests, prototypes, and technical exploration.",
            "</p>",
            "<button class='btn secondary'>Open</button>",

            "</div>",

            "<div class='card'>",

            "<span class='tag'>03</span>",
            "<h3>Case Study</h3>",
            "<p>",
            "Present the problem, process, solution, and impact.",
            "</p>",
            "<button class='btn secondary'>Read</button>",

            "</div>",

            "</section>",

            "<section class='card' style='margin-top:20px'>",

            "<h2>Skills</h2>",
            "<span class='pill'>Development</span>",
            "<span class='pill'>UI/UX</span>",
            "<span class='pill'>Creative Coding</span>",
            "<span class='pill'>Problem Solving</span>",

            "</section>"
          )

        // ------------------------------------------------------
        // FORMS
        // ------------------------------------------------------

        case "Forms" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Form Builder</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "A clean, accessible form structure generated from your requirements."
            else
              safePrompt,

            "</p>",

            "</section>",

            "<section class='card' style='margin-top:20px'>",

            "<div class='field'>",
            "<label>Full Name</label>",
            "<input placeholder='Enter your name'>",
            "</div>",

            "<div class='field'>",
            "<label>Email</label>",
            "<input type='email' placeholder='you@example.com'>",
            "</div>",

            "<div class='field'>",
            "<label>Category</label>",
            "<select>",
            "<option>Choose one</option>",
            "<option>General</option>",
            "<option>Support</option>",
            "<option>Project</option>",
            "</select>",
            "</div>",

            "<div class='field'>",
            "<label>Message</label>",
            "<textarea rows='6' ",
            "placeholder='Tell us more...'></textarea>",
            "</div>",

            "<button class='btn'>Submit Form</button>",

            "</section>"
          )

        // ------------------------------------------------------
        // DASHBOARDS
        // ------------------------------------------------------

        case "Dashboards" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Dashboard Generator</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "An analytics-style dashboard with metrics, progress, " +
              "and action cards."
            else
              safePrompt,

            "</p>",

            "</section>",

            "<section class='grid'>",

            "<div class='card'>",
            "<p class='muted'>USERS</p>",
            "<div class='metric'>12,540</div>",
            "<span class='tag'>+12%</span>",
            "</div>",

            "<div class='card'>",
            "<p class='muted'>PROJECTS</p>",
            "<div class='metric'>348</div>",
            "<span class='tag'>+8%</span>",
            "</div>",

            "<div class='card'>",
            "<p class='muted'>TASKS</p>",
            "<div class='metric'>1,284</div>",
            "<span class='tag'>73%</span>",
            "</div>",

            "</section>",

            "<section class='grid2'>",

            "<div class='card'>",

            "<h2>Progress</h2>",
            "<p class='muted'>Primary goal completion</p>",

            "<div class='bar'>",
            "<div class='fill' style='width:72%'></div>",
            "</div>",

            "</div>",

            "<div class='card'>",

            "<h2>Activity</h2>",
            "<p class='muted'>Latest system events</p>",

            "<div class='row'>",
            "<span>New project</span>",
            "<span class='tag'>2m</span>",
            "</div>",

            "<div class='row'>",
            "<span>Upload complete</span>",
            "<span class='tag'>9m</span>",
            "</div>",

            "<div class='row'>",
            "<span>Profile updated</span>",
            "<span class='tag'>18m</span>",
            "</div>",

            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // API JSON
        // ------------------------------------------------------

        case "API / JSON" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Data &amp; API</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "A clean developer-facing API response and endpoint documentation layout."
            else
              safePrompt,

            "</p>",

            "</section>",

            "<section class='grid2'>",

            "<div class='card'>",

            "<h2>Endpoint</h2>",
            "<span class='tag'>GET</span>",
            "<div class='code-chip'>",
            "/api/v1/projects",
            "</div>",
            "<p class='muted'>",
            "Returns project metadata in JSON format.",
            "</p>",

            "</div>",

            "<div class='card'>",

            "<h2>Example</h2>",

            "<div class='code-chip'>",
            "{&quot;status&quot;:&quot;ok&quot;,&quot;items&quot;:3}",
            "</div>",

            "<p class='muted'>",
            "Use this section for schemas and response samples.",
            "</p>",

            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // COMPONENTS
        // ------------------------------------------------------

        case "Components" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Component Studio</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "Build reusable buttons, cards, alerts, navigation, " +
              "inputs, and layout primitives."
            else
              safePrompt,

            "</p>",

            "</section>",

            "<section class='grid'>",

            "<div class='card'>",
            "<h3>Button System</h3>",
            "<button class='btn'>Action</button>",
            "<button class='btn secondary'>More</button>",
            "</div>",

            "<div class='card'>",
            "<h3>Status</h3>",
            "<span class='tag'>ACTIVE</span>",
            "<span class='tag'>DRAFT</span>",
            "<span class='tag'>READY</span>",
            "</div>",

            "<div class='card'>",
            "<h3>Notice</h3>",
            "<div class='notice'>",
            "Reusable information component.",
            "</div>",
            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // ICONS
        // ------------------------------------------------------

        case "Icons" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Icon &amp; Visual Lab</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "A scalable visual board for icons, symbols, badges, " +
              "and small interface graphics."
            else
              safePrompt,

            "</p>",

            "</section>",

            "<section class='grid'>",

            "<div class='card' ",
            "style='text-align:center;font-size:42px'>",
            "?",
            "<p class='muted'>Star</p>",
            "</div>",

            "<div class='card' ",
            "style='text-align:center;font-size:42px'>",
            "?",
            "<p class='muted'>Settings</p>",
            "</div>",

            "<div class='card' ",
            "style='text-align:center;font-size:42px'>",
            "?",
            "<p class='muted'>Success</p>",
            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // CREATIVE PROJECTS
        // ------------------------------------------------------

        case "Creative Projects" =>

          join(

            "<section class='hero' ",
            "style='background:radial-gradient(circle at top left,",
            visualColor,
            ",#10162d 58%)'>",

            "<span class='eyebrow'>Creative Lab</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "An open canvas for experiments, prototypes, interactive stories, " +
              "visual projects, and unusual ideas."
            else
              safePrompt,

            "</p>",

            "<a class='btn' href='#canvas'>Open Canvas</a>",

            "</section>",

            "<section id='canvas' class='card' ",
            "style='margin-top:20px;min-height:250px;text-align:center'>",

            "<h2>Creative Canvas</h2>",

            "<p class='muted'>",
            "Use this area as the starting point for your custom creation.",
            "</p>",

            "<div style='margin:25px auto;width:85%;height:110px;",
            "border-radius:18px;background:linear-gradient(100deg,",
            visualColor,
            ",#17264f,#0e1428)'>",
            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // BLANK
        // ------------------------------------------------------

        case "Blank Project" =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>Blank Project</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "Start from a clean, extensible base and shape it into anything you need."
            else
              safePrompt,

            "</p>",

            "<button class='btn'>Begin</button>",

            "</section>",

            "<section class='grid2'>",

            "<div class='card'>",
            "<h2>Structure</h2>",
            "<p>",
            "Header, main content, utility modules, and footer are ready to adapt.",
            "</p>",
            "</div>",

            "<div class='card'>",
            "<h2>Next Step</h2>",
            "<p>",
            "Keep iterating in the code editor and regenerate whenever the idea changes.",
            "</p>",
            "</div>",

            "</section>"
          )

        // ------------------------------------------------------
        // FALLBACK
        // ------------------------------------------------------

        case _ =>

          join(

            "<section class='hero'>",

            "<span class='eyebrow'>",
            HtmlTools.escapeHtml(category),
            "</span>",

            "<h1>",
            HtmlTools.escapeHtml(title),
            "</h1>",

            "<p>",

            if (safePrompt.isEmpty)
              "Describe what you want to build and generate a new project."
            else
              safePrompt,

            "</p>",

            "<button class='btn'>Create</button>",

            "</section>"
          )
      }

    baseHtml(
      title,
      category,
      body,
      image,
      generation
    )
  }
}

// ============================================================
// LOGIN PANEL
// ============================================================

class LoginPanel(
    onSuccess: () => Unit
) extends JPanel(new GridBagLayout()) {

  private val loginBackground =
    new Color(
      7,
      11,
      22
    )

  private val cardBackground =
    new Color(
      17,
      24,
      43
    )

  private val accent =
    new Color(
      109,
      125,
      255
    )

  private val soft =
    new Color(
      168,
      180,
      214
    )

  setBackground(
    loginBackground
  )

  private val card =
    new JPanel(
      new GridBagLayout()
    )

  card.setBackground(
    cardBackground
  )

  card.setBorder(
    new CompoundBorder(
      new LineBorder(
        new Color(
          51,
          65,
          102
        ),
        1,
        true
      ),
      new EmptyBorder(
        34,
        40,
        34,
        40
      )
    )
  )

  private val constraints =
    new GridBagConstraints()

  constraints.gridx = 0
  constraints.weightx = 1.0
  constraints.fill =
    GridBagConstraints.HORIZONTAL

  private val brand =
    new JLabel(
      "DEVELOPER CREATOR"
    )

  brand.setHorizontalAlignment(
    SwingConstants.CENTER
  )

  brand.setForeground(
    new Color(
      146,
      159,
      255
    )
  )

  brand.setFont(
    new Font(
      "SansSerif",
      Font.BOLD,
      14
    )
  )

  private val title =
    new JLabel(
      "Secure Developer Platform"
    )

  title.setHorizontalAlignment(
    SwingConstants.CENTER
  )

  title.setForeground(
    Color.WHITE
  )

  title.setFont(
    new Font(
      "SansSerif",
      Font.BOLD,
      28
    )
  )

  private val subtitle =
    new JLabel(
      "Enter the private platform password to continue"
    )

  subtitle.setHorizontalAlignment(
    SwingConstants.CENTER
  )

  subtitle.setForeground(
    soft
  )

  subtitle.setFont(
    new Font(
      "SansSerif",
      Font.PLAIN,
      13
    )
  )

  private val passwordField =
    new JPasswordField()

  passwordField.setPreferredSize(
    new Dimension(
      320,
      44
    )
  )

  passwordField.setFont(
    new Font(
      "SansSerif",
      Font.PLAIN,
      17
    )
  )

  passwordField.setBackground(
    new Color(
      10,
      16,
      32
    )
  )

  passwordField.setForeground(
    Color.WHITE
  )

  passwordField.setCaretColor(
    Color.WHITE
  )

  passwordField.setBorder(
    new CompoundBorder(
      new LineBorder(
        new Color(
          56,
          71,
          111
        ),
        1,
        true
      ),
      new EmptyBorder(
        6,
        10,
        6,
        10
      )
    )
  )

  private val status =
    new JLabel(" ")

  status.setHorizontalAlignment(
    SwingConstants.CENTER
  )

  status.setForeground(
    new Color(
      244,
      110,
      110
    )
  )

  status.setFont(
    new Font(
      "SansSerif",
      Font.BOLD,
      12
    )
  )

  private val loginButton =
    new JButton(
      "UNLOCK PLATFORM"
    )

  loginButton.setPreferredSize(
    new Dimension(
      320,
      44
    )
  )

  loginButton.setBackground(
    accent
  )

  loginButton.setForeground(
    Color.WHITE
  )

  loginButton.setFocusPainted(
    false
  )

  loginButton.setBorder(
    new EmptyBorder(
      8,
      16,
      8,
      16
    )
  )

  loginButton.setFont(
    new Font(
      "SansSerif",
      Font.BOLD,
      13
    )
  )

  private val showButton =
    new JButton(
      "Show"
    )

  showButton.setFocusPainted(
    false
  )

  showButton.setBackground(
    new Color(
      30,
      41,
      70
    )
  )

  showButton.setForeground(
    new Color(
      202,
      211,
      238
    )
  )

  showButton.setBorder(
    new EmptyBorder(
      8,
      12,
      8,
      12
    )
  )

  private val passwordRow =
    new JPanel(
      new BorderLayout(
        8,
        0
      )
    )

  passwordRow.setOpaque(
    false
  )

  passwordRow.add(
    passwordField,
    BorderLayout.CENTER
  )

  passwordRow.add(
    showButton,
    BorderLayout.EAST
  )

  private val info =
    new JLabel(
      "<html>" +
      "<div style='text-align:center'>" +
      "Local SHA-256 verification<br>" +
      "No plaintext password is stored in this source." +
      "</div>" +
      "</html>"
    )

  info.setHorizontalAlignment(
    SwingConstants.CENTER
  )

  info.setForeground(
    new Color(
      126,
      139,
      174
    )
  )

  info.setFont(
    new Font(
      "SansSerif",
      Font.PLAIN,
      11
    )
  )

  private def addRow(
      component: Component,
      top: Int,
      bottom: Int
  ): Unit = {

    constraints.gridy += 1

    constraints.insets =
      new Insets(
        top,
        0,
        bottom,
        0
      )

    card.add(
      component,
      constraints
    )
  }

  constraints.gridy = -1

  addRow(
    brand,
    0,
    10
  )

  addRow(
    title,
    0,
    8
  )

  addRow(
    subtitle,
    0,
    24
  )

  addRow(
    passwordRow,
    0,
    12
  )

  addRow(
    loginButton,
    0,
    8
  )

  addRow(
    status,
    0,
    14
  )

  addRow(
    info,
    0,
    0
  )

  add(card)

  private var attempts =
    0

  private var locked =
    false

  private var passwordVisible =
    false

  showButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        passwordVisible =
          !passwordVisible

        passwordField.setEchoChar(
          if (passwordVisible)
            0.toChar
          else
            '?'
        )

        showButton.setText(
          if (passwordVisible)
            "Hide"
          else
            "Show"
        )
      }
    }
  )

  private def performLogin(): Unit = {

    if (locked) {
      return
    }

    val candidate =
      new String(
        passwordField.getPassword
      )

    if (candidate.isEmpty) {

      status.setText(
        "Enter the password."
      )

      return
    }

    if (
      PlatformSecurity.verify(
        candidate
      )
    ) {

      status.setForeground(
        new Color(
          105,
          225,
          158
        )
      )

      status.setText(
        "Access granted."
      )

      loginButton.setEnabled(false)
      passwordField.setEnabled(false)
      showButton.setEnabled(false)

      val transitionTimer =
        new Timer(
          180,
          new ActionListener {

            override def actionPerformed(
                e: ActionEvent
            ): Unit = {

              val timer =
                e.getSource
                  .asInstanceOf[Timer]

              timer.stop()

              onSuccess()
            }
          }
        )

      transitionTimer.setRepeats(
        false
      )

      transitionTimer.start()

    } else {

      attempts += 1

      passwordField.setText(
        ""
      )

      val remaining =
        math.max(
          0,
          5 - attempts
        )

      status.setForeground(
        new Color(
          244,
          110,
          110
        )
      )

      status.setText(
        "Incorrect password. Attempts remaining: " +
        remaining
      )

      if (attempts >= 5) {

        locked = true

        loginButton.setEnabled(false)
        passwordField.setEnabled(false)
        showButton.setEnabled(false)

        status.setText(
          "Too many attempts. Locked for 10 seconds."
        )

        val unlockTimer =
          new Timer(
            10000,
            new ActionListener {

              override def actionPerformed(
                  e: ActionEvent
              ): Unit = {

                val timer =
                  e.getSource
                    .asInstanceOf[Timer]

                timer.stop()

                attempts = 0
                locked = false

                loginButton.setEnabled(
                  true
                )

                passwordField.setEnabled(
                  true
                )

                showButton.setEnabled(
                  true
                )

                status.setText(
                  "You may try again."
                )
              }
            }
          )

        unlockTimer.setRepeats(
          false
        )

        unlockTimer.start()
      }
    }
  }

  loginButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        performLogin()
      }
    }
  )

  passwordField.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        performLogin()
      }
    }
  )
}

// ============================================================
// MAIN DEVELOPER PLATFORM
// ============================================================

class DeveloperPlatformPanel(
    frame: JFrame
) extends JPanel(new BorderLayout()) {

  // NOTE:
  // This is intentionally NOT named "background".
  private val appBackground =
    new Color(
      8,
      13,
      25
    )

  private val panelBg =
    new Color(
      13,
      20,
      37
    )

  private val borderColor =
    new Color(
      44,
      59,
      92
    )

  private val textColor =
    new Color(
      235,
      240,
      255
    )

  private val mutedColor =
    new Color(
      145,
      158,
      190
    )

  private val accent =
    new Color(
      109,
      125,
      255
    )

  private val success =
    new Color(
      98,
      218,
      154
    )

  private val categories =
    Array(
      "Websites",
      "Links",
      "Bio Pages",
      "Apps",
      "Games",
      "Landing Pages",
      "UI Designs",
      "Tools",
      "Portfolios",
      "Forms",
      "Dashboards",
      "API / JSON",
      "Components",
      "Icons",
      "Creative Projects",
      "Blank Project"
    )

  private var selectedCategory =
    "Websites"

  private var currentImage:
      Option[ImageProfile] =
    None

  private var generationCount =
    0

  private var projectCode =
    ProjectGenerator.generate(
      selectedCategory,
      "Create a modern professional project.",
      currentImage,
      generationCount
    )

  // ==========================================================
  // COMPONENTS
  // ==========================================================

  private val categoryModel =
    new DefaultListModel[String]()

  private val categoryList =
    new JList[String](
      categoryModel
    )

  private val searchField =
    new JTextField()

  private val promptArea =
    new JTextArea()

  private val codeArea =
    new JTextArea()

  private val previewPane =
    new JEditorPane()

  private val outputCards =
    new JPanel(
      new CardLayout()
    )

  private val statusLabel =
    new JLabel(
      "Ready"
    )

  private val imageNameLabel =
    new JLabel(
      "No reference image"
    )

  private val imagePreviewLabel =
    new JLabel()

  private val generateButton =
    new JButton(
      "Generate"
    )

  private val regenerateButton =
    new JButton(
      "Regenerate"
    )

  private val previewButton =
    new JButton(
      "Preview"
    )

  private val editButton =
    new JButton(
      "Edit Code"
    )

  private val copyButton =
    new JButton(
      "Copy Code"
    )

  private val downloadButton =
    new JButton(
      "Download Code"
    )

  private val saveProjectButton =
    new JButton(
      "Save Project"
    )

  private val openProjectButton =
    new JButton(
      "Open Project"
    )

  private val newProjectButton =
    new JButton(
      "New Project"
    )

  private val uploadImageButton =
    new JButton(
      "Upload Image"
    )

  private val removeImageButton =
    new JButton(
      "Remove Image"
    )

  private val previewCard =
    new JPanel(
      new BorderLayout()
    )

  private val codeCard =
    new JPanel(
      new BorderLayout()
    )

  setBackground(
    appBackground
  )

  // ==========================================================
  // HELPERS
  // ==========================================================

  private def configureButton(
      button: JButton,
      primary: Boolean
  ): Unit = {

    button.setFocusPainted(
      false
    )

    button.setFont(
      new Font(
        "SansSerif",
        Font.BOLD,
        12
      )
    )

    button.setBorder(
      new EmptyBorder(
        9,
        13,
        9,
        13
      )
    )

    if (primary) {

      button.setBackground(
        accent
      )

      button.setForeground(
        Color.WHITE
      )

    } else {

      button.setBackground(
        new Color(
          29,
          42,
          71
        )
      )

      button.setForeground(
        new Color(
          219,
          227,
          248
        )
      )
    }
  }

  private def configureTitleLabel(
      label: JLabel,
      size: Int
  ): Unit = {

    label.setForeground(
      textColor
    )

    label.setFont(
      new Font(
        "SansSerif",
        Font.BOLD,
        size
      )
    )
  }

  private def configureMutedLabel(
      label: JLabel
  ): Unit = {

    label.setForeground(
      mutedColor
    )

    label.setFont(
      new Font(
        "SansSerif",
        Font.PLAIN,
        11
      )
    )
  }

  // ==========================================================
  // TOP BAR
  // ==========================================================

  private val topBar =
    new JPanel(
      new BorderLayout(
        12,
        0
      )
    )

  topBar.setBackground(
    panelBg
  )

  topBar.setBorder(
    new CompoundBorder(
      new MatteBorder(
        0,
        0,
        1,
        0,
        borderColor
      ),
      new EmptyBorder(
        12,
        14,
        12,
        14
      )
    )
  )

  private val brandPanel =
    new JPanel()

  brandPanel.setOpaque(
    false
  )

  brandPanel.setLayout(
    new BoxLayout(
      brandPanel,
      BoxLayout.Y_AXIS
    )
  )

  private val brandLabel =
    new JLabel(
      "DEVELOPER CREATOR PLATFORM"
    )

  configureTitleLabel(
    brandLabel,
    17
  )

  private val brandSub =
    new JLabel(
      "A to Z creation workspace � local generation studio"
    )

  configureMutedLabel(
    brandSub
  )

  brandPanel.add(
    brandLabel
  )

  brandPanel.add(
    Box.createVerticalStrut(3)
  )

  brandPanel.add(
    brandSub
  )

  private val topActions =
    new JPanel(
      new FlowLayout(
        FlowLayout.RIGHT,
        7,
        0
      )
    )

  topActions.setOpaque(
    false
  )

  configureButton(
    newProjectButton,
    false
  )

  configureButton(
    saveProjectButton,
    false
  )

  configureButton(
    openProjectButton,
    false
  )

  configureButton(
    downloadButton,
    false
  )

  topActions.add(
    newProjectButton
  )

  topActions.add(
    saveProjectButton
  )

  topActions.add(
    openProjectButton
  )

  topActions.add(
    downloadButton
  )

  topBar.add(
    brandPanel,
    BorderLayout.WEST
  )

  topBar.add(
    topActions,
    BorderLayout.EAST
  )

  add(
    topBar,
    BorderLayout.NORTH
  )

  // ==========================================================
  // LEFT PANEL
  // ==========================================================

  private val leftPanel =
    new JPanel(
      new BorderLayout(
        0,
        10
      )
    )

  leftPanel.setBackground(
    panelBg
  )

  leftPanel.setBorder(
    new EmptyBorder(
      14,
      12,
      14,
      10
    )
  )

  leftPanel.setPreferredSize(
    new Dimension(
      205,
      0
    )
  )

  private val categoryTitle =
    new JLabel(
      "CREATE"
    )

  configureTitleLabel(
    categoryTitle,
    12
  )

  private val categorySubtitle =
    new JLabel(
      "Choose what you want to build"
    )

  configureMutedLabel(
    categorySubtitle
  )

  private val categoryHeader =
    new JPanel()

  categoryHeader.setOpaque(
    false
  )

  categoryHeader.setLayout(
    new BoxLayout(
      categoryHeader,
      BoxLayout.Y_AXIS
    )
  )

  categoryHeader.add(
    categoryTitle
  )

  categoryHeader.add(
    Box.createVerticalStrut(3)
  )

  categoryHeader.add(
    categorySubtitle
  )

  searchField.setBackground(
    new Color(
      9,
      15,
      29
    )
  )

  searchField.setForeground(
    textColor
  )

  searchField.setCaretColor(
    Color.WHITE
  )

  searchField.setBorder(
    new CompoundBorder(
      new LineBorder(
        borderColor,
        1,
        true
      ),
      new EmptyBorder(
        4,
        7,
        4,
        7
      )
    )
  )

  searchField.setPreferredSize(
    new Dimension(
      170,
      36
    )
  )

  private val leftNorth =
    new JPanel(
      new BorderLayout(
        0,
        9
      )
    )

  leftNorth.setOpaque(
    false
  )

  leftNorth.add(
    categoryHeader,
    BorderLayout.NORTH
  )

  leftNorth.add(
    searchField,
    BorderLayout.SOUTH
  )

  private val categoryScroll =
    new JScrollPane(
      categoryList
    )

  categoryScroll.setBorder(
    new LineBorder(
      borderColor,
      1,
      true
    )
  )

  categoryScroll.getViewport.setBackground(
    new Color(
      10,
      16,
      31
    )
  )

  categoryList.setBackground(
    new Color(
      10,
      16,
      31
    )
  )

  categoryList.setForeground(
    new Color(
      205,
      215,
      240
    )
  )

  categoryList.setFont(
    new Font(
      "SansSerif",
      Font.PLAIN,
      13
    )
  )

  categoryList.setFixedCellHeight(
    38
  )

  categoryList.setSelectionBackground(
    new Color(
      61,
      76,
      139
    )
  )

  categoryList.setSelectionForeground(
    Color.WHITE
  )

  private val leftFooter =
    new JLabel(
      "<html>" +
      "<div style='color:#71809e;width:165px'>" +
      "Prompt + image + category ? generate ? edit ? preview ? export" +
      "</div>" +
      "</html>"
    )

  leftPanel.add(
    leftNorth,
    BorderLayout.NORTH
  )

  leftPanel.add(
    categoryScroll,
    BorderLayout.CENTER
  )

  leftPanel.add(
    leftFooter,
    BorderLayout.SOUTH
  )

  var categoryIndex =
    0

  while (
    categoryIndex <
    categories.length
  ) {

    categoryModel.addElement(
      categories(categoryIndex)
    )

    categoryIndex += 1
  }

  categoryList.setSelectedIndex(
    0
  )

  // ==========================================================
  // CENTER PANEL
  // ==========================================================

  private val centerPanel =
    new JPanel(
      new BorderLayout(
        0,
        10
      )
    )

  centerPanel.setBackground(
    appBackground
  )

  centerPanel.setBorder(
    new EmptyBorder(
      14,
      10,
      14,
      10
    )
  )

  private val editorHeader =
    new JPanel(
      new BorderLayout()
    )

  editorHeader.setOpaque(
    false
  )

  private val editorTitlePanel =
    new JPanel()

  editorTitlePanel.setOpaque(
    false
  )

  editorTitlePanel.setLayout(
    new BoxLayout(
      editorTitlePanel,
      BoxLayout.Y_AXIS
    )
  )

  private val editorTitle =
    new JLabel(
      "Prompt & Generator"
    )

  configureTitleLabel(
    editorTitle,
    18
  )

  private val editorHint =
    new JLabel(
      "Describe your idea in natural language. The generator turns it into editable code."
    )

  configureMutedLabel(
    editorHint
  )

  editorTitlePanel.add(
    editorTitle
  )

  editorTitlePanel.add(
    Box.createVerticalStrut(4)
  )

  editorTitlePanel.add(
    editorHint
  )

  private val editorActions =
    new JPanel(
      new FlowLayout(
        FlowLayout.RIGHT,
        7,
        0
      )
    )

  editorActions.setOpaque(
    false
  )

  configureButton(
    generateButton,
    true
  )

  configureButton(
    regenerateButton,
    false
  )

  configureButton(
    previewButton,
    false
  )

  configureButton(
    editButton,
    false
  )

  editorActions.add(
    generateButton
  )

  editorActions.add(
    regenerateButton
  )

  editorActions.add(
    previewButton
  )

  editorActions.add(
    editButton
  )

  editorHeader.add(
    editorTitlePanel,
    BorderLayout.WEST
  )

  editorHeader.add(
    editorActions,
    BorderLayout.EAST
  )

  promptArea.setLineWrap(
    true
  )

  promptArea.setWrapStyleWord(
    true
  )

  promptArea.setBackground(
    new Color(
      11,
      18,
      34
    )
  )

  promptArea.setForeground(
    textColor
  )

  promptArea.setCaretColor(
    Color.WHITE
  )

  promptArea.setFont(
    new Font(
      "SansSerif",
      Font.PLAIN,
      15
    )
  )

  promptArea.setBorder(
    new EmptyBorder(
      16,
      16,
      16,
      16
    )
  )

  promptArea.setText(
    "Create a modern professional website for a gaming creator. " +
    "Use a bold hero section, project cards, social links, contact form, " +
    "responsive layout, dark theme, clean typography, and strong call-to-action."
  )

  private val promptScroll =
    new JScrollPane(
      promptArea
    )

  promptScroll.setBorder(
    new LineBorder(
      borderColor,
      1,
      true
    )
  )

  // ==========================================================
  // QUICK IDEA
  // ==========================================================

  private val quickIdeasPanel =
    new JPanel(
      new BorderLayout()
    )

  quickIdeasPanel.setBackground(
    panelBg
  )

  quickIdeasPanel.setBorder(
    new CompoundBorder(
      new LineBorder(
        borderColor,
        1,
        true
      ),
      new EmptyBorder(
        10,
        12,
        10,
        12
      )
    )
  )

  private val quickLabel =
    new JLabel(
      "QUICK IDEA"
    )

  configureTitleLabel(
    quickLabel,
    11
  )

  private val quickText =
    new JLabel(
      "<html>" +
      "<div style='color:#9da9c5'>" +
      "Try: &quot;Build a futuristic dashboard with analytics, " +
      "user cards, a side menu and activity feed.&quot;" +
      "</div>" +
      "</html>"
    )

  private val quickButton =
    new JButton(
      "Use Example"
    )

  configureButton(
    quickButton,
    false
  )

  private val quickLeft =
    new JPanel()

  quickLeft.setOpaque(
    false
  )

  quickLeft.setLayout(
    new BoxLayout(
      quickLeft,
      BoxLayout.Y_AXIS
    )
  )

  quickLeft.add(
    quickLabel
  )

  quickLeft.add(
    Box.createVerticalStrut(5)
  )

  quickLeft.add(
    quickText
  )

  quickIdeasPanel.add(
    quickLeft,
    BorderLayout.CENTER
  )

  quickIdeasPanel.add(
    quickButton,
    BorderLayout.EAST
  )

  // ==========================================================
  // IMAGE PANEL
  // ==========================================================

  private val uploadPanel =
    new JPanel(
      new BorderLayout(
        10,
        0
      )
    )

  uploadPanel.setBackground(
    panelBg
  )

  uploadPanel.setBorder(
    new CompoundBorder(
      new LineBorder(
        borderColor,
        1,
        true
      ),
      new EmptyBorder(
        12,
        12,
        12,
        12
      )
    )
  )

  private val uploadTextPanel =
    new JPanel()

  uploadTextPanel.setOpaque(
    false
  )

  uploadTextPanel.setLayout(
    new BoxLayout(
      uploadTextPanel,
      BoxLayout.Y_AXIS
    )
  )

  private val referenceTitle =
    new JLabel(
      "REFERENCE IMAGE"
    )

  configureTitleLabel(
    referenceTitle,
    11
  )

  imageNameLabel.setForeground(
    mutedColor
  )

  imageNameLabel.setFont(
    new Font(
      "SansSerif",
      Font.PLAIN,
      11
    )
  )

  uploadTextPanel.add(
    referenceTitle
  )

  uploadTextPanel.add(
    Box.createVerticalStrut(5)
  )

  uploadTextPanel.add(
    imageNameLabel
  )

  private val imageButtonsPanel =
    new JPanel(
      new FlowLayout(
        FlowLayout.RIGHT,
        6,
        0
      )
    )

  imageButtonsPanel.setOpaque(
    false
  )

  configureButton(
    uploadImageButton,
    false
  )

  configureButton(
    removeImageButton,
    false
  )

  imageButtonsPanel.add(
    uploadImageButton
  )

  imageButtonsPanel.add(
    removeImageButton
  )

  uploadPanel.add(
    uploadTextPanel,
    BorderLayout.CENTER
  )

  uploadPanel.add(
    imageButtonsPanel,
    BorderLayout.EAST
  )

  centerPanel.add(
    editorHeader,
    BorderLayout.NORTH
  )

  private val centerBody =
    new JPanel(
      new BorderLayout(
        0,
        10
      )
    )

  centerBody.setOpaque(
    false
  )

  centerBody.add(
    promptScroll,
    BorderLayout.CENTER
  )

  private val centerBottom =
    new JPanel()

  centerBottom.setOpaque(
    false
  )

  centerBottom.setLayout(
    new BoxLayout(
      centerBottom,
      BoxLayout.Y_AXIS
    )
  )

  centerBottom.add(
    quickIdeasPanel
  )

  centerBottom.add(
    Box.createVerticalStrut(8)
  )

  centerBottom.add(
    uploadPanel
  )

  centerBody.add(
    centerBottom,
    BorderLayout.SOUTH
  )

  centerPanel.add(
    centerBody,
    BorderLayout.CENTER
  )

  // ==========================================================
  // RIGHT PANEL
  // ==========================================================

  private val rightPanel =
    new JPanel(
      new BorderLayout(
        0,
        10
      )
    )

  rightPanel.setBackground(
    panelBg
  )

  rightPanel.setBorder(
    new EmptyBorder(
      14,
      10,
      14,
      12
    )
  )

  rightPanel.setPreferredSize(
    new Dimension(
      575,
      0
    )
  )

  private val rightHeader =
    new JPanel(
      new BorderLayout()
    )

  rightHeader.setOpaque(
    false
  )

  private val outputTitlePanel =
    new JPanel()

  outputTitlePanel.setOpaque(
    false
  )

  outputTitlePanel.setLayout(
    new BoxLayout(
      outputTitlePanel,
      BoxLayout.Y_AXIS
    )
  )

  private val outputTitle =
    new JLabel(
      "Preview & Output"
    )

  configureTitleLabel(
    outputTitle,
    18
  )

  private val outputSub =
    new JLabel(
      "Your generated artifact appears here."
    )

  configureMutedLabel(
    outputSub
  )

  outputTitlePanel.add(
    outputTitle
  )

  outputTitlePanel.add(
    Box.createVerticalStrut(4)
  )

  outputTitlePanel.add(
    outputSub
  )

  private val statusPanel =
    new JPanel(
      new FlowLayout(
        FlowLayout.RIGHT,
        5,
        0
      )
    )

  statusPanel.setOpaque(
    false
  )

  statusLabel.setForeground(
    success
  )

  statusLabel.setFont(
    new Font(
      "SansSerif",
      Font.BOLD,
      11
    )
  )

  statusPanel.add(
    statusLabel
  )

  rightHeader.add(
    outputTitlePanel,
    BorderLayout.WEST
  )

  rightHeader.add(
    statusPanel,
    BorderLayout.EAST
  )

  // ==========================================================
  // PREVIEW
  // ==========================================================

  previewCard.setBackground(
    new Color(
      10,
      16,
      31
    )
  )

  previewCard.setBorder(
    new LineBorder(
      borderColor,
      1,
      true
    )
  )

  private val browserBar =
    new JPanel(
      new BorderLayout()
    )

  browserBar.setBackground(
    new Color(
      18,
      26,
      46
    )
  )

  browserBar.setBorder(
    new EmptyBorder(
      8,
      10,
      8,
      10
    )
  )

  private val browserDots =
    new JLabel(
      "?  ?  ?"
    )

  browserDots.setForeground(
    new Color(
      120,
      135,
      169
    )
  )

  browserDots.setFont(
    new Font(
      "SansSerif",
      Font.BOLD,
      12
    )
  )

  private val browserAddress =
    new JLabel(
      " local://developer-preview"
    )

  browserAddress.setForeground(
    new Color(
      146,
      160,
      192
    )
  )

  browserAddress.setFont(
    new Font(
      "Monospaced",
      Font.PLAIN,
      11
    )
  )

  browserBar.add(
    browserDots,
    BorderLayout.WEST
  )

  browserBar.add(
    browserAddress,
    BorderLayout.CENTER
  )

  previewPane.setContentType(
    "text/html"
  )

  previewPane.setEditable(
    false
  )

  previewPane.putClientProperty(
    JEditorPane.HONOR_DISPLAY_PROPERTIES,
    java.lang.Boolean.TRUE
  )

  previewPane.setBorder(
    new EmptyBorder(
      12,
      12,
      12,
      12
    )
  )

  private val previewScroll =
    new JScrollPane(
      previewPane
    )

  previewScroll.setBorder(
    null
  )

  previewCard.add(
    browserBar,
    BorderLayout.NORTH
  )

  previewCard.add(
    previewScroll,
    BorderLayout.CENTER
  )

  // ==========================================================
  // CODE CARD
  // ==========================================================

  codeArea.setBackground(
    new Color(
      8,
      13,
      25
    )
  )

  codeArea.setForeground(
    new Color(
      211,
      220,
      243
    )
  )

  codeArea.setCaretColor(
    Color.WHITE
  )

  codeArea.setFont(
    new Font(
      "Monospaced",
      Font.PLAIN,
      12
    )
  )

  codeArea.setTabSize(
    2
  )

  codeArea.setLineWrap(
    false
  )

  codeArea.setText(
    projectCode
  )

  private val codeScroll =
    new JScrollPane(
      codeArea
    )

  codeScroll.setBorder(
    null
  )

  private val codeToolbar =
    new JPanel(
      new BorderLayout()
    )

  codeToolbar.setBackground(
    new Color(
      18,
      26,
      46
    )
  )

  codeToolbar.setBorder(
    new EmptyBorder(
      8,
      10,
      8,
      10
    )
  )

  private val codeLabel =
    new JLabel(
      "Generated HTML / CSS / UI CODE"
    )

  codeLabel.setForeground(
    new Color(
      168,
      181,
      213
    )
  )

  codeLabel.setFont(
    new Font(
      "SansSerif",
      Font.BOLD,
      11
    )
  )

  codeToolbar.add(
    codeLabel,
    BorderLayout.WEST
  )

  codeCard.setBackground(
    new Color(
      8,
      13,
      25
    )
  )

  codeCard.setBorder(
    new LineBorder(
      borderColor,
      1,
      true
    )
  )

  codeCard.add(
    codeToolbar,
    BorderLayout.NORTH
  )

  codeCard.add(
    codeScroll,
    BorderLayout.CENTER
  )

  outputCards.setOpaque(
    false
  )

  outputCards.add(
    previewCard,
    "PREVIEW"
  )

  outputCards.add(
    codeCard,
    "CODE"
  )

  private val outputButtonBar =
    new JPanel(
      new FlowLayout(
        FlowLayout.RIGHT,
        7,
        0
      )
    )

  outputButtonBar.setOpaque(
    false
  )

  configureButton(
    copyButton,
    false
  )

  outputButtonBar.add(
    copyButton
  )

  private val outputOuter =
    new JPanel(
      new BorderLayout(
        0,
        8
      )
    )

  outputOuter.setOpaque(
    false
  )

  outputOuter.add(
    outputCards,
    BorderLayout.CENTER
  )

  outputOuter.add(
    outputButtonBar,
    BorderLayout.SOUTH
  )

  rightPanel.add(
    rightHeader,
    BorderLayout.NORTH
  )

  rightPanel.add(
    outputOuter,
    BorderLayout.CENTER
  )

  // ==========================================================
  // SPLITS
  // ==========================================================

  private val horizontalSplit =
    new JSplitPane(
      JSplitPane.HORIZONTAL_SPLIT,
      leftPanel,
      centerPanel
    )

  horizontalSplit.setDividerLocation(
    205
  )

  horizontalSplit.setDividerSize(
    5
  )

  horizontalSplit.setBorder(
    null
  )

  horizontalSplit.setBackground(
    appBackground
  )

  private val mainSplit =
    new JSplitPane(
      JSplitPane.HORIZONTAL_SPLIT,
      horizontalSplit,
      rightPanel
    )

  mainSplit.setDividerLocation(
    700
  )

  mainSplit.setDividerSize(
    5
  )

  mainSplit.setBorder(
    null
  )

  mainSplit.setBackground(
    appBackground
  )

  add(
    mainSplit,
    BorderLayout.CENTER
  )

  // ==========================================================
  // FILTER CATEGORIES
  // ==========================================================

  private def filterCategories(
      filterText: String
  ): Unit = {

    categoryModel.clear()

    val lower =
      Option(filterText)
        .getOrElse("")
        .trim
        .toLowerCase

    var i =
      0

    while (
      i < categories.length
    ) {

      if (
        lower.isEmpty ||
        categories(i)
          .toLowerCase
          .contains(lower)
      ) {

        categoryModel.addElement(
          categories(i)
        )
      }

      i += 1
    }

    if (
      categoryModel.size() > 0
    ) {

      categoryList.setSelectedIndex(
        0
      )
    }
  }

  // ==========================================================
  // SELECT CATEGORY
  // ==========================================================

  private def selectCategoryByName(
      name: String
  ): Unit = {

    var i =
      0

    while (
      i < categoryModel.size()
    ) {

      if (
        categoryModel.getElementAt(i) ==
        name
      ) {

        categoryList.setSelectedIndex(
          i
        )

        return
      }

      i += 1
    }
  }

  // ==========================================================
  // CARD LAYOUT
  // ==========================================================

  private def currentCardLayout:
      CardLayout = {

    outputCards
      .getLayout
      .asInstanceOf[CardLayout]
  }

  // ==========================================================
  // PREVIEW
  // ==========================================================

  private def showPreview(): Unit = {

    projectCode =
      codeArea.getText

    try {

      previewPane.setText(
        projectCode
      )

      previewPane.setCaretPosition(
        0
      )

      currentCardLayout.show(
        outputCards,
        "PREVIEW"
      )

      statusLabel.setForeground(
        success
      )

      statusLabel.setText(
        "Preview updated"
      )

    } catch {

      case ex: Throwable =>

        statusLabel.setForeground(
          new Color(
            244,
            160,
            110
          )
        )

        statusLabel.setText(
          "Preview error: " +
          Option(
            ex.getMessage
          ).getOrElse(
            "unknown"
          )
        )
    }
  }

  // ==========================================================
  // CODE
  // ==========================================================

  private def showCode(): Unit = {

    projectCode =
      codeArea.getText

    currentCardLayout.show(
      outputCards,
      "CODE"
    )

    codeArea.requestFocusInWindow()

    statusLabel.setForeground(
      new Color(
        174,
        194,
        248
      )
    )

    statusLabel.setText(
      "Editing generated code"
    )
  }

  // ==========================================================
  // GENERATE
  // ==========================================================

  private def generateProject(
      forceRegenerate: Boolean
  ): Unit = {

    if (forceRegenerate) {

      generationCount += 1

    } else if (
      generationCount == 0
    ) {

      generationCount = 1
    }

    val selectedValue =
      categoryList.getSelectedValue

    if (
      selectedValue != null
    ) {

      selectedCategory =
        selectedValue
    }

    val prompt =
      promptArea.getText.trim

    projectCode =
      ProjectGenerator.generate(
        selectedCategory,
        prompt,
        currentImage,
        generationCount
      )

    codeArea.setText(
      projectCode
    )

    codeArea.setCaretPosition(
      0
    )

    previewPane.setText(
      projectCode
    )

    previewPane.setCaretPosition(
      0
    )

    currentCardLayout.show(
      outputCards,
      "PREVIEW"
    )

    statusLabel.setForeground(
      success
    )

    statusLabel.setText(
      if (forceRegenerate)
        "Regenerated � revision " +
        generationCount
      else
        "Generated � revision " +
        generationCount
    )
  }

  // ==========================================================
  // COPY CODE
  // ==========================================================

  private def copyCodeToClipboard(): Unit = {

    try {

      val clipboard =
        Toolkit
          .getDefaultToolkit
          .getSystemClipboard

      clipboard.setContents(
        new StringSelection(
          codeArea.getText
        ),
        null
      )

      statusLabel.setForeground(
        success
      )

      statusLabel.setText(
        "Code copied to clipboard"
      )

    } catch {

      case _: Throwable =>

        statusLabel.setForeground(
          new Color(
            244,
            160,
            110
          )
        )

        statusLabel.setText(
          "Clipboard unavailable"
        )
    }
  }

  // ==========================================================
  // DOWNLOAD
  // ==========================================================

  private def chooseDownloadPath:
      Option[File] = {

    val chooser =
      new JFileChooser()

    chooser.setDialogTitle(
      "Download Generated Code"
    )

    chooser.setSelectedFile(
      new File(
        HtmlTools.slug(
          selectedCategory
        ) +
        "-" +
        HtmlTools.slug(
          Option(
            promptArea.getText
          ).getOrElse(
            "project"
          )
        ) +
        ".html"
      )
    )

    val result =
      chooser.showSaveDialog(
        this
      )

    if (
      result ==
      JFileChooser.APPROVE_OPTION
    ) {

      Some(
        chooser.getSelectedFile
      )

    } else {

      None
    }
  }

  private def downloadCode(): Unit = {

    chooseDownloadPath match {

      case Some(file) =>

        try {

          val parent =
            file.getParentFile

          if (
            parent != null &&
            !parent.exists()
          ) {

            parent.mkdirs()
          }

          Files.write(
            file.toPath,
            codeArea
              .getText
              .getBytes(
                StandardCharsets.UTF_8
              )
          )

          statusLabel.setForeground(
            success
          )

          statusLabel.setText(
            "Downloaded: " +
            file.getName
          )

        } catch {

          case ex: Throwable =>

            statusLabel.setForeground(
              new Color(
                244,
                160,
                110
              )
            )

            statusLabel.setText(
              "Download failed: " +
              Option(
                ex.getMessage
              ).getOrElse(
                "unknown"
              )
            )
        }

      case None =>
    }
  }

  // ==========================================================
  // SAVE PROJECT
  // ==========================================================

  private def saveProject(): Unit = {

    val chooser =
      new JFileChooser()

    chooser.setDialogTitle(
      "Save Developer Creator Project"
    )

    chooser.setSelectedFile(
      new File(
        HtmlTools.slug(
          Option(
            promptArea.getText
          ).getOrElse(
            "project"
          )
        ) +
        ".dcp"
      )
    )

    if (
      chooser.showSaveDialog(
        this
      ) ==
      JFileChooser.APPROVE_OPTION
    ) {

      val file =
        chooser.getSelectedFile

      try {

        val properties =
          new java.util.Properties()

        properties.setProperty(
          "version",
          "1"
        )

        properties.setProperty(
          "category",
          selectedCategory
        )

        properties.setProperty(
          "generation",
          generationCount.toString
        )

        properties.setProperty(
          "prompt",
          java.util.Base64
            .getEncoder
            .encodeToString(
              promptArea
                .getText
                .getBytes(
                  StandardCharsets.UTF_8
                )
            )
        )

        properties.setProperty(
          "code",
          java.util.Base64
            .getEncoder
            .encodeToString(
              codeArea
                .getText
                .getBytes(
                  StandardCharsets.UTF_8
                )
            )
        )

        val output =
          new FileOutputStream(
            file
          )

        try {

          properties.store(
            output,
            "Developer Creator Project"
          )

        } finally {

          output.close()
        }

        statusLabel.setForeground(
          success
        )

        statusLabel.setText(
          "Project saved: " +
          file.getName
        )

      } catch {

        case ex: Throwable =>

          statusLabel.setForeground(
            new Color(
              244,
              160,
              110
            )
          )

          statusLabel.setText(
            "Save failed: " +
            Option(
              ex.getMessage
            ).getOrElse(
              "unknown"
            )
          )
      }
    }
  }

  // ==========================================================
  // OPEN PROJECT
  // ==========================================================

  private def openProject(): Unit = {

    val chooser =
      new JFileChooser()

    chooser.setDialogTitle(
      "Open Developer Creator Project"
    )

    if (
      chooser.showOpenDialog(
        this
      ) ==
      JFileChooser.APPROVE_OPTION
    ) {

      val file =
        chooser.getSelectedFile

      try {

        val properties =
          new java.util.Properties()

        val input =
          new FileInputStream(
            file
          )

        try {

          properties.load(
            input
          )

        } finally {

          input.close()
        }

        val loadedCategory =
          properties.getProperty(
            "category",
            "Websites"
          )

        val promptEncoded =
          properties.getProperty(
            "prompt",
            ""
          )

        val codeEncoded =
          properties.getProperty(
            "code",
            ""
          )

        val loadedPrompt =
          if (
            promptEncoded.isEmpty
          ) {

            ""

          } else {

            new String(
              java.util.Base64
                .getDecoder
                .decode(
                  promptEncoded
                ),
              StandardCharsets.UTF_8
            )
          }

        val loadedCode =
          if (
            codeEncoded.isEmpty
          ) {

            ""

          } else {

            new String(
              java.util.Base64
                .getDecoder
                .decode(
                  codeEncoded
                ),
              StandardCharsets.UTF_8
            )
          }

        val parsedGeneration =
          try {

            properties
              .getProperty(
                "generation",
                "1"
              )
              .toInt

          } catch {

            case _: Throwable =>
              1
          }

        generationCount =
          math.max(
            1,
            parsedGeneration
          )

        selectCategoryByName(
          loadedCategory
        )

        selectedCategory =
          loadedCategory

        promptArea.setText(
          loadedPrompt
        )

        projectCode =
          if (
            loadedCode.nonEmpty
          ) {

            loadedCode

          } else {

            ProjectGenerator.generate(
              selectedCategory,
              loadedPrompt,
              currentImage,
              generationCount
            )
          }

        codeArea.setText(
          projectCode
        )

        previewPane.setText(
          projectCode
        )

        previewPane.setCaretPosition(
          0
        )

        currentCardLayout.show(
          outputCards,
          "PREVIEW"
        )

        statusLabel.setForeground(
          success
        )

        statusLabel.setText(
          "Project loaded: " +
          file.getName
        )

      } catch {

        case ex: Throwable =>

          statusLabel.setForeground(
            new Color(
              244,
              160,
              110
            )
          )

          statusLabel.setText(
            "Open failed: " +
            Option(
              ex.getMessage
            ).getOrElse(
              "unknown"
            )
          )
      }
    }
  }

  // ==========================================================
  // NEW PROJECT
  // ==========================================================

  private def newProject(): Unit = {

    generationCount =
      0

    currentImage =
      None

    selectedCategory =
      "Websites"

    selectCategoryByName(
      selectedCategory
    )

    promptArea.setText(
      "Create a modern project for a creative developer. " +
      "Include a strong hero section, useful content cards, " +
      "responsive structure, a clear navigation area, " +
      "and a professional visual style."
    )

    codeArea.setText(
      ProjectGenerator.generate(
        selectedCategory,
        promptArea.getText,
        currentImage,
        generationCount
      )
    )

    projectCode =
      codeArea.getText

    previewPane.setText(
      projectCode
    )

    previewPane.setCaretPosition(
      0
    )

    imageNameLabel.setText(
      "No reference image"
    )

    imagePreviewLabel.setIcon(
      null
    )

    statusLabel.setForeground(
      new Color(
        174,
        194,
        248
      )
    )

    statusLabel.setText(
      "New project ready"
    )

    currentCardLayout.show(
      outputCards,
      "PREVIEW"
    )
  }

  // ==========================================================
  // UPLOAD IMAGE
  // ==========================================================

  private def uploadReferenceImage():
      Unit = {

    val chooser =
      new JFileChooser()

    chooser.setDialogTitle(
      "Choose Reference Image"
    )

    val filters =
      Array(
        "jpg",
        "jpeg",
        "png",
        "gif",
        "bmp"
      )

    chooser.setFileFilter(
      new FileNameExtensionFilter(
        "Image files",
        filters: _*
      )
    )

    if (
      chooser.showOpenDialog(
        this
      ) ==
      JFileChooser.APPROVE_OPTION
    ) {

      val file =
        chooser.getSelectedFile

      ImageAnalyzer.analyze(
        file
      ) match {

        case Some(profile) =>

          currentImage =
            Some(profile)

          imageNameLabel.setText(
            profile.fileName +
            " � " +
            profile.width +
            "�" +
            profile.height +
            " � " +
            profile.dominantHex
          )

          ImageAnalyzer
            .makePreviewIcon(
              file,
              72,
              54
            ) match {

            case Some(icon) =>

              imagePreviewLabel.setIcon(
                icon
              )

            case None =>

              imagePreviewLabel.setIcon(
                null
              )
          }

          statusLabel.setForeground(
            success
          )

          statusLabel.setText(
            "Image analyzed � layout + color hints prepared"
          )

          generateProject(
            true
          )

        case None =>

          statusLabel.setForeground(
            new Color(
              244,
              160,
              110
            )
          )

          statusLabel.setText(
            "Could not read that image"
          )
      }
    }
  }

  // ==========================================================
  // REMOVE IMAGE
  // ==========================================================

  private def removeReferenceImage():
      Unit = {

    currentImage =
      None

    imageNameLabel.setText(
      "No reference image"
    )

    imagePreviewLabel.setIcon(
      null
    )

    statusLabel.setForeground(
      new Color(
        174,
        194,
        248
      )
    )

    statusLabel.setText(
      "Reference image removed"
    )
  }

  // ==========================================================
  // CATEGORY LISTENER
  // ==========================================================

  categoryList.addListSelectionListener(
    new ListSelectionListener {

      override def valueChanged(
          e: ListSelectionEvent
      ): Unit = {

        if (
          !e.getValueIsAdjusting
        ) {

          val value =
            categoryList.getSelectedValue

          if (
            value != null
          ) {

            selectedCategory =
              value

            editorTitle.setText(
              "Prompt & Generator � " +
              selectedCategory
            )

            statusLabel.setForeground(
              new Color(
                174,
                194,
                248
              )
            )

            statusLabel.setText(
              "Selected: " +
              selectedCategory
            )
          }
        }
      }
    }
  )

  // ==========================================================
  // SEARCH LISTENER
  // ==========================================================

  searchField
    .getDocument
    .addDocumentListener(
      new DocumentListener {

        override def insertUpdate(
            e: DocumentEvent
        ): Unit = {

          filterCategories(
            searchField.getText
          )
        }

        override def removeUpdate(
            e: DocumentEvent
        ): Unit = {

          filterCategories(
            searchField.getText
          )
        }

        override def changedUpdate(
            e: DocumentEvent
        ): Unit = {

          filterCategories(
            searchField.getText
          )
        }
      }
    )

  // ==========================================================
  // QUICK BUTTON
  // ==========================================================

  quickButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        promptArea.setText(
          "Build a futuristic developer dashboard with a left navigation menu, " +
          "analytics cards, active projects, recent activity, notifications, " +
          "a search bar, responsive layout, dark theme, and polished glass-like panels."
        )

        selectedCategory =
          "Dashboards"

        selectCategoryByName(
          selectedCategory
        )

        statusLabel.setForeground(
          new Color(
            174,
            194,
            248
          )
        )

        statusLabel.setText(
          "Example prompt inserted"
        )

        promptArea.requestFocusInWindow()
      }
    }
  )

  // ==========================================================
  // BUTTON EVENTS
  // ==========================================================

  generateButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        generateProject(
          false
        )
      }
    }
  )

  regenerateButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        generateProject(
          true
        )
      }
    }
  )

  previewButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        showPreview()
      }
    }
  )

  editButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        showCode()
      }
    }
  )

  copyButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        copyCodeToClipboard()
      }
    }
  )

  downloadButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        downloadCode()
      }
    }
  )

  saveProjectButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        saveProject()
      }
    }
  )

  openProjectButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        openProject()
      }
    }
  )

  newProjectButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        newProject()
      }
    }
  )

  uploadImageButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        uploadReferenceImage()
      }
    }
  )

  removeImageButton.addActionListener(
    new ActionListener {

      override def actionPerformed(
          e: ActionEvent
      ): Unit = {

        removeReferenceImage()
      }
    }
  )

  // ==========================================================
  // CODE DOCUMENT LISTENER
  // ==========================================================

  codeArea
    .getDocument
    .addDocumentListener(
      new DocumentListener {

        override def insertUpdate(
            e: DocumentEvent
        ): Unit = {

          projectCode =
            codeArea.getText
        }

        override def removeUpdate(
            e: DocumentEvent
        ): Unit = {

          projectCode =
            codeArea.getText
        }

        override def changedUpdate(
            e: DocumentEvent
        ): Unit = {

          projectCode =
            codeArea.getText
        }
      }
    )

  // ==========================================================
  // KEYBOARD SHORTCUTS
  // ==========================================================

  private val keyboardActions =
    new KeyAdapter {

      override def keyPressed(
          e: KeyEvent
      ): Unit = {

        if (
          e.isControlDown &&
          e.getKeyCode ==
          KeyEvent.VK_S
        ) {

          saveProject()

        } else if (
          e.isControlDown &&
          e.getKeyCode ==
          KeyEvent.VK_O
        ) {

          openProject()

        } else if (
          e.isControlDown &&
          e.getKeyCode ==
          KeyEvent.VK_ENTER
        ) {

          generateProject(
            false
          )

        } else if (
          e.isControlDown &&
          e.isShiftDown &&
          e.getKeyCode ==
          KeyEvent.VK_C
        ) {

          copyCodeToClipboard()
        }
      }
    }

  promptArea.addKeyListener(
    keyboardActions
  )

  codeArea.addKeyListener(
    keyboardActions
  )

  categoryList.addKeyListener(
    keyboardActions
  )

  searchField.addKeyListener(
    keyboardActions
  )

  // ==========================================================
  // SPLIT CONFIGURATION
  // ==========================================================

  private def configureSplitBehavior():
      Unit = {

    SwingUtilities.invokeLater(
      new Runnable {

        override def run():
            Unit = {

          try {

            horizontalSplit.setDividerLocation(
              205
            )

            val target =
              math.max(
                670,
                getWidth - 590
              )

            mainSplit.setDividerLocation(
              target
            )

          } catch {
            case _: Throwable =>
          }
        }
      }
    )
  }

  // ==========================================================
  // INITIAL PREVIEW
  // ==========================================================

  previewPane.setText(
    projectCode
  )

  previewPane.setCaretPosition(
    0
  )

  configureSplitBehavior()

  setFocusable(
    true
  )

  requestFocusInWindow()
}

// ============================================================
// APPLICATION
// ============================================================

val appFrame =
  new JFrame(
    "Developer Creator Platform"
  )

appFrame.setDefaultCloseOperation(
  WindowConstants.EXIT_ON_CLOSE
)

appFrame.setMinimumSize(
  new Dimension(
    1120,
    720
  )
)

// ============================================================
// LOGIN SUCCESS
// ============================================================

val loginPanel =
  new LoginPanel(
    () => {

      val platform =
        new DeveloperPlatformPanel(
          appFrame
        )

      appFrame.setContentPane(
        platform
      )

      appFrame.setTitle(
        "Developer Creator Platform � A to Z Studio"
      )

      appFrame.setSize(
        1440,
        880
      )

      appFrame.setLocationRelativeTo(
        null
      )

      appFrame.setVisible(
        true
      )

      platform.requestFocusInWindow()

      platform.revalidate()

      platform.repaint()
    }
  )

// ============================================================
// SHOW LOGIN
// ============================================================

appFrame.setContentPane(
  loginPanel
)

appFrame.setSize(
  560,
  610
)

appFrame.setLocationRelativeTo(
  null
)

appFrame.setVisible(
  true
)

loginPanel.requestFocusInWindow()